# GTMesh: A Highly Efficient C++ Template Library for Numerical Schemes on General Topology Meshes
## 4 The GTMesh Library
### The UnstructuredMeshWrapper Class
### Default Traits

In order for the algorithms in GTMesh to be able to access the class reflection functionalities, there has to be a standard mechanism of globally exposing Traits for the given user-defined data structures. The solution is based on the DefaultTraits class template, which accepts the reflected class as its template parameter. The generic declaration of DefaultTraits has no methods or parameters. Traits for a particular class are exposed by defining DefaultTraits template specialization with a single static member function getTraits(), which returns the corresponding Traits instance. From DefaultTraits, GTMesh derives DefaultIOTraits for mesh data I/O and DefaultArithmeticTraits for arithmetics (see Listing 5). Both of them inherit the DefaultTraits functionality, but a specialization of each template can be provided by the user. The SFINAE paradigm [31] is used to detect whether a particular class has the respective type of Traits defined. Finally, to simplify the definition of default class traits, GTMesh offers several preprocessor macros expanding to the specializations of the above classes. For example, MAKE_DEFAULT_ATTRIBUTE_TRAITS expands to DefaultTraits, etc., with the expected static member functions and type definitions. As a result, the definition of the default class traits for a data structure requires a single line of code, as demonstrated in Listing 4. ```
1 classData{
2 doubledensity;
3 Vector<3,double>momentum;
4 Vector<3,double>getVelocity()(returnmomentum/density;)
5 voidsetVelocity(constVector<3,double>velocity)(momentum=velocity*density;)
6}
7
8//MacrocreatesspecializationofDefaultTraitsforDatasandnames
9//accordingtotheattributesnames
10 NAKE_ATTRIBUTE_TRAIT(Data,density,momentum);
11
12//MacrocreatesspecializationofDefaultTOTraitsfortheDataslass
13 NAKE_CUSTOM_TRAIT_IO(
14 Data. 15\"density\",&Data::density,
16\"velocity\",std::make_pair(&Data::getVelocity,&Data::setVelocity)
17};
18//usage...
19//Onlyvaluesreturnedas1-valuereferencecanbobtainedusinggetAttrfunction
20 DefaultTraits+Data>::getTraits().getAttr<0>(qInstance)=3;//getreferenceto
21 density
22 DefaultTOTraits+Data>::getTraits().setValue<1>(qInstance,{3,6,9});//setmomentum
23 DefaultTOTraits+Data>::getTraits().getValue<1>(qInstance);//{1,2,3}getvelocity
24 DefaultTOTraits+Data>::getTraits().setValue<1>(qInstance,{1,1,1});//setvelocity
25 DefaultTraits+Data>::getTraits().getValue<1>(qInstance);//{3,3,3}getmomentum
```
Listing 5: Example implementation of operator + for any type with DefaultArithmeticTraits or DefaultTraits defined, e.g., application of this operator on the data class from Listing 4 would sum up the density and momentum members. This approach allows us to define all common mathematical operations for the classes with traits defined. It is even possible to define maximum value among the members, if the members of the class are comparable. ```
1 template<typenameT1,typenameT2>
2 structBinaryPlus
3{
4 staticoutevaluate(constT1&,constT2&b)->decltype(a+b)
5{
6 returna+b;
7}
8};
9
10 template<typenameTraitT>
11 typenamestd::ENDLE_if<H=D=DefaultArithmeticTraits<TraitT>::value,TraitT>::type
12 Operat<(constTraitT&op1,constTraitT&op2)noexcept{
13 TraitTres;
14//A classperforminganoperationforeachmemberofttheclass
15 TraitsBinaryExpressionProcessor<BinaryPlus>::evaluate(res,op1,op2);
16 returnres;
17}