Loading TemplateTest/main.cpp +86 −18 Original line number Original line Diff line number Diff line Loading @@ -3,7 +3,7 @@ #include "../src/UnstructuredMesh/UnstructuredMesh.h" #include "../src/UnstructuredMesh/UnstructuredMesh.h" #include "../src/Traits/MemberApproach/MemberApproach.h" #include "../src/Traits/MemberApproach/MemberApproach.h" #include "../src/Traits/Traits.h" #include "../src/Traits/Traits.h" #include "../src/Singleton/Singleton.h" #include <chrono> #include <chrono> #include <functional> #include <functional> #include <type_traits> #include <type_traits> Loading Loading @@ -322,14 +322,6 @@ void testMemberRef(){ DBGVAR(e, ClassC<>()); DBGVAR(e, ClassC<>()); } } void testTraitsAlgorithms() { ExportTest e1, e2; ExportTest res = e1 + e2; std::vector<ExportTest> vec(40, ExportTest()); DBGVAR(2.45*e1,e1 + e2, e1, e2,HasDefaultArithmeticTraits<int>::value, max(e2), min(e2), max(vec)); } struct NumStruct { struct NumStruct { double data; double data; Loading @@ -340,10 +332,32 @@ MAKE_ATTRIBUTE_TRAIT(NumStruct, data); struct NumStruct2 { struct NumStruct2 { double data1; double data1; double data2; double data2; NumStruct2(double d1 = 0.0, double d2 = 0.0): data1(d1), data2(d2){} }; }; MAKE_ATTRIBUTE_TRAIT(NumStruct2, data1, data2); MAKE_ATTRIBUTE_TRAIT(NumStruct2, data1, data2); void testTraitsAlgorithms() { ExportTest e1, e2; ExportTest res = e1 + e2; std::vector<ExportTest> vec(40, ExportTest()); DBGVAR(2.45*e1,e1 + e2, e1, e2,HasDefaultArithmeticTraits<int>::value, max(e2), min(e2), max(vec)); NumStruct2 ns{21,15}, ns2{2,3}; DBGVAR(ns * ns2, -(ns + 4 * ns2), max(-(ns + 4 * ns2)), max(abs(-(ns + 4 * ns2))), log(ns), exp(log(ns)), pow(sqrt(ns), 2) ); } template <unsigned int Index> template <unsigned int Index> const MemberReference<tempData, DefaultArithmeticTraits<tempData>::traitsType::type<Index>, DefaultArithmeticTraits<tempData>::traitsType::refType<Index>> const MemberReference<tempData, DefaultArithmeticTraits<tempData>::traitsType::type<Index>, DefaultArithmeticTraits<tempData>::traitsType::refType<Index>> getReference() { getReference() { Loading Loading @@ -1048,6 +1062,24 @@ void testNumericTraitsPerformance() { duration = 0; duration = 0; DBGMSG("numeric traits = +"); start = clock.now(); res2 = NumStruct2(); for(int rep = 0; rep < maxRep; rep++){ for(size_t i = 0; i < numVec2.size(); i++) { res2 = res2 + numVec2[i]; } duration += (clock.now() - start).count(); deviation += (clock.now() - start).count() * (clock.now() - start).count(); start = clock.now(); } avgDuration = duration / maxRep; DBGVAR(res2, avgDuration , sqrt(((deviation)- maxRep * pow(avgDuration,2)) / (maxRep - 1))); deviation = 0; duration = 0; DBGMSG("\n","ExportTest performance, direct approach"); DBGMSG("\n","ExportTest performance, direct approach"); std::vector<ExportTest> vec3(size, ExportTest()); std::vector<ExportTest> vec3(size, ExportTest()); Loading Loading @@ -1093,6 +1125,9 @@ void testNumericTraitsPerformance() { deviation = 0; deviation = 0; duration = 0; duration = 0; } } Loading Loading @@ -1297,15 +1332,15 @@ template <typename Class, typename T> class Func { class Func { public: public: template <typename U = T> template <typename U = T, typename refType> auto operator()(unsigned int index, const MemberApproach<Class, T>&, const std::string& name) auto operator()(unsigned int index, const MemberReference<Class, T, refType>&, const std::string& name) -> typename std::enable_if<!(HasDefaultTraits<U>::value)>::type -> typename std::enable_if<!(HasDefaultTraits<U>::value)>::type { { DBGVAR(Singleton<Depth>::getInstance().value,index, name); DBGVAR(Singleton<Depth>::getInstance().value,index, name); } } template <typename U = T> template <typename U = T, typename refType> auto operator()(unsigned int index, const MemberApproach<Class, T>&, const std::string& name) auto operator()(unsigned int index, const MemberReference<Class, T, refType>&, const std::string& name) -> typename std::enable_if<HasDefaultTraits<U>::value>::type -> typename std::enable_if<HasDefaultTraits<U>::value>::type { { DBGVAR(Singleton<Depth>::getInstance().value,index, name); DBGVAR(Singleton<Depth>::getInstance().value,index, name); Loading Loading @@ -1602,7 +1637,7 @@ class TestMemberReference{ template <typename Class, typename ValueType> template <typename Class, typename ValueType> class TestMemberReference<Class, ValueType, ValueType Class::*> : MemberApproach<Class, ValueType>{ class TestMemberReference<Class, ValueType, ValueType Class::*> /*: MemberApproach<Class, ValueType>*/{ using refType = ValueType Class::*; using refType = ValueType Class::*; public: public: Loading Loading @@ -1902,7 +1937,7 @@ void testTraitPerformance() { DBGVAR(res, avgDuration , sqrt(((deviation)- maxRep * pow(avgDuration,2)) / (maxRep - 1))); DBGVAR(res, avgDuration , sqrt(((deviation)- maxRep * pow(avgDuration,2)) / (maxRep - 1))); deviation = 0; deviation = 0; duration = 0; duration = 0; /* DBGMSG("member reference virtual"); DBGMSG("member reference virtual"); const MemberApproach<ExportTest, double>* MA = new MemberReference<ExportTest, double, decltype (&ExportTest::attrDouble)>(&ExportTest::attrDouble); const MemberApproach<ExportTest, double>* MA = new MemberReference<ExportTest, double, decltype (&ExportTest::attrDouble)>(&ExportTest::attrDouble); start = clock.now(); start = clock.now(); Loading @@ -1920,7 +1955,7 @@ void testTraitPerformance() { DBGVAR(res, avgDuration , sqrt(((deviation)- maxRep * pow(avgDuration,2)) / (maxRep - 1))); DBGVAR(res, avgDuration , sqrt(((deviation)- maxRep * pow(avgDuration,2)) / (maxRep - 1))); deviation = 0; deviation = 0; duration = 0; duration = 0; */ DBGMSG("traits"); DBGMSG("traits"); start = clock.now(); start = clock.now(); Loading Loading @@ -2290,6 +2325,38 @@ void testTraitsTuple(){ DBGVAR(foo(t), t); DBGVAR(foo(t), t); } } /* template <unsigned int n, unsigned int _n = 1> constexpr typename std::enable_if<(_n == n), unsigned int>::type factorial(){ return _n; } template <unsigned int n, unsigned int _n = 1> constexpr typename std::enable_if<(_n < n), unsigned int>::type factorial(){ return factorial<n,_n+1>() * _n; } */ namespace Impl { template <unsigned int n, unsigned int _n = 1> constexpr typename std::enable_if<(_n == n), unsigned int>::type factorial(){ return _n; } template <unsigned int n, unsigned int _n = 1> constexpr typename std::enable_if<(_n < n), unsigned int>::type factorial(){ return Impl::factorial<n,_n+1>() * _n; } } void testFactorial() { DBGVAR(Impl::factorial<5>()); } int main() int main() { { Loading @@ -2308,8 +2375,9 @@ int main() //testJson(); //testJson(); //testTestTraits(); //testTestTraits(); //testTraitsAlgorithms(); //testTraitsAlgorithms(); //testNumericTraitsPerformance(); testNumericTraitsPerformance(); testTraitsTuple(); //testTraitsTuple(); //testFactorial(); return 0; return 0; } } Loading src/Traits/MemberApproach/MemberApproach.h +84 −51 Original line number Original line Diff line number Diff line Loading @@ -4,22 +4,45 @@ #include <utility> #include <utility> /** /** * @brief The MemberApproach class * @brief The DirectReference struct determines that the * Generic abstract class providing the approach to * reference can provide direct approach to the member. * any attribute of a class using getValue and setValue */ */ template <typename Class, typename ValueType> struct DirectReference{ class MemberApproach{ static constexpr std::true_type is_direct{}; public: virtual ValueType getValue(const Class*) const = 0; virtual void setValue(Class*, const ValueType&) const = 0; virtual ValueType getValue(const Class&) const = 0; virtual void setValue(Class&, const ValueType&) const = 0; }; }; namespace Impl { template <typename T, typename = void> struct IsDirectReference : public std::false_type {}; template <typename T> struct IsDirectReference < T, typename std::enable_if<T::is_direct>::type > : public std::true_type {}; } // Impl /** * @brief The IsDirectReference struct inherits * @ref std::true_type if the class MemberReference provides direct * approach to the member using function getAttr. */ template <typename T> struct IsDirectReference : public Impl::IsDirectReference<T> {}; template<typename Class, typename ValueType, typename Ref> template<typename Class, typename ValueType, typename Ref> class MemberReference{ class MemberReference{ static_assert (std::is_same<Ref, ValueType Class::*>::value, static_assert (std::is_same<Ref, ValueType Class::*>::value, Loading @@ -29,7 +52,7 @@ class MemberReference{ template <typename Class, typename ValueType> template <typename Class, typename ValueType> class MemberReference<Class, ValueType, ValueType Class::*> : public MemberApproach<Class, ValueType>{ class MemberReference<Class, ValueType, ValueType Class::*> : public DirectReference { using refType = ValueType Class::*; using refType = ValueType Class::*; Loading @@ -45,11 +68,11 @@ public: MemberReference(MemberReference<Class, ValueType, ValueType Class::*>&&) = default; MemberReference(MemberReference<Class, ValueType, ValueType Class::*>&&) = default; virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return c->*ref; return c->*ref; } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { c->*ref = val; c->*ref = val; } } Loading @@ -57,11 +80,11 @@ public: return c->*ref; return c->*ref; } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return c.*ref; return c.*ref; } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { c.*ref = val; c.*ref = val; } } Loading @@ -75,7 +98,7 @@ public: template <typename Class, typename ValueType> template <typename Class, typename ValueType> class MemberReference<Class, ValueType, ValueType& (Class::*)()> : public MemberApproach<Class, ValueType>{ class MemberReference<Class, ValueType, ValueType& (Class::*)()> : public DirectReference { using refType = ValueType& (Class::*)(); using refType = ValueType& (Class::*)(); Loading @@ -89,21 +112,29 @@ public: //ref = referenceToMember; //ref = referenceToMember; } } virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return (c->*ref)(); } ValueType& getAttr(Class* c) const { return (c->*ref)(); return (c->*ref)(); } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { (c->*ref)() = val; (c->*ref)() = val; } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return (c.*ref)(); return (c.*ref)(); } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { (c.*ref)() = val; (c.*ref)() = val; } } ValueType& getAttr(Class& c) const { return (c->*ref)(); } }; }; Loading @@ -115,7 +146,7 @@ class MemberReference< ValueType, ValueType, std::pair<ValueType (Class::*)(), void (Class::*)(const ValueType&)> std::pair<ValueType (Class::*)(), void (Class::*)(const ValueType&)> > > : public MemberApproach<Class, ValueType>{ { using getter = ValueType (Class::*)(); using getter = ValueType (Class::*)(); getter const refGet; getter const refGet; Loading @@ -130,19 +161,19 @@ public: //refSet = getSet.second; //refSet = getSet.second; } } virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return (c->*refGet)(); return (c->*refGet)(); } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { (c->*refSet)(val); (c->*refSet)(val); } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return (c.*refGet)(); return (c.*refGet)(); } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { (c.*refSet)(val); (c.*refSet)(val); } } }; }; Loading @@ -154,7 +185,7 @@ class MemberReference< ValueType, ValueType, std::pair<ValueType (Class::*)() const, void (Class::*)(const ValueType&)> std::pair<ValueType (Class::*)() const, void (Class::*)(const ValueType&)> > > : public MemberApproach<Class, ValueType>{ { using getter = ValueType (Class::*)() const; using getter = ValueType (Class::*)() const; getter const refGet; getter const refGet; Loading @@ -169,19 +200,19 @@ public: //refSet = getSet.second; //refSet = getSet.second; } } virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return (c->*refGet)(); return (c->*refGet)(); } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { (c->*refSet)(val); (c->*refSet)(val); } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return (c.*refGet)(); return (c.*refGet)(); } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { (c.*refSet)(val); (c.*refSet)(val); } } }; }; Loading @@ -193,7 +224,7 @@ class MemberReference< ValueType, ValueType, std::pair<const ValueType& (Class::*)() const, void (Class::*)(const ValueType&)> std::pair<const ValueType& (Class::*)() const, void (Class::*)(const ValueType&)> > > : public MemberApproach<Class, ValueType>{ { using getter = const ValueType& (Class::*)() const; using getter = const ValueType& (Class::*)() const; getter const refGet; getter const refGet; Loading @@ -208,19 +239,19 @@ public: //refSet = getSet.second; //refSet = getSet.second; } } virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return (c->*refGet)(); return (c->*refGet)(); } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { (c->*refSet)(val); (c->*refSet)(val); } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return (c.*refGet)(); return (c.*refGet)(); } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { (c.*refSet)(val); (c.*refSet)(val); } } }; }; Loading @@ -232,7 +263,7 @@ class MemberReference< ValueType, ValueType, std::pair<const ValueType& (Class::*)(), void (Class::*)(const ValueType&)> std::pair<const ValueType& (Class::*)(), void (Class::*)(const ValueType&)> > > : public MemberApproach<Class, ValueType>{ { using getter = const ValueType& (Class::*)(); using getter = const ValueType& (Class::*)(); getter const refGet; getter const refGet; Loading @@ -247,19 +278,19 @@ public: //refSet = getSet.second; //refSet = getSet.second; } } virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return (c->*refGet)(); return (c->*refGet)(); } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { (c->*refSet)(val); (c->*refSet)(val); } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return (c.*refGet)(); return (c.*refGet)(); } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { (c.*refSet)(val); (c.*refSet)(val); } } }; }; Loading @@ -267,7 +298,8 @@ public: template <typename Class, typename ValueType> template <typename Class, typename ValueType> class MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class&), const ValueType&(*)(const Class&)>> : public MemberApproach<Class, ValueType>{ class MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class&), const ValueType&(*)(const Class&)>> : public DirectReference { using setter = ValueType& (*)(Class&); using setter = ValueType& (*)(Class&); Loading @@ -289,21 +321,21 @@ public: MemberReference(MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class&), const ValueType&(*)(const Class&)>>&&) = default; MemberReference(MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class&), const ValueType&(*)(const Class&)>>&&) = default; virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return get(*c); return get(*c); } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { set(*c) = val; set(*c) = val; } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return get(c); return get(c); } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { set(c) = val; set(c) = val; } } Loading @@ -318,7 +350,8 @@ public: template <typename Class, typename ValueType> template <typename Class, typename ValueType> class MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class*), const ValueType&(*)(const Class*)>> : public MemberApproach<Class, ValueType>{ class MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class*), const ValueType&(*)(const Class*)>> : public DirectReference { using setter = ValueType& (*)(Class*); using setter = ValueType& (*)(Class*); Loading @@ -340,21 +373,21 @@ public: MemberReference(MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class*), const ValueType&(*)(const Class*)>>&&) = default; MemberReference(MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class*), const ValueType&(*)(const Class*)>>&&) = default; virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return get(c); return get(c); } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { set(c) = val; set(c) = val; } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return get(&c); return get(&c); } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { set(&c) = val; set(&c) = val; } } Loading src/Traits/Traits.h +66 −5 Original line number Original line Diff line number Diff line Loading @@ -3,7 +3,6 @@ #include "MemberApproach/MemberApproach.h" #include "MemberApproach/MemberApproach.h" #include <string> #include <string> #include <memory> #include <memory> #include "../Singleton/Singleton.h" #include <functional> #include <functional> template<typename Class, typename...RefTypes> template<typename Class, typename...RefTypes> Loading Loading @@ -74,6 +73,19 @@ public: } } template<unsigned int Index> type<Index>& getAttr(Class* c) const { static_assert (IsDirectReference<memRefType<Index>>::value, "The current reference to the member does not provide direct approach."); return getReference<Index>()->getAttr(c); } template<unsigned int Index> type<Index>& getAttr(Class& c) const { static_assert (IsDirectReference<memRefType<Index>>::value, "The current reference to the member does not provide direct approach."); return getReference<Index>().getAttr(c); } template<unsigned int Index> template<unsigned int Index> const char* getName() const { const char* getName() const { return refs.MemRefs<Index, void>::name; return refs.MemRefs<Index, void>::name; Loading Loading @@ -261,12 +273,61 @@ public: template<typename Class> template<typename Class> class DefaultIOTraits : public Traits<Class> {}; class DefaultIOTraits : public Traits<Class> {}; template<typename Class> template<typename Class> class DefaultArithmeticTraits : public Traits<Class> {}; class DefaultArithmeticTraits : public Traits<Class> {}; #include "CustomTypeTraits.h" namespace Impl { template <unsigned int Index, unsigned int ...Indexes> struct TraitedAttributeGetter{ template<typename TraitT, typename = typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value>::type> static auto& get(TraitT& arg){ return TraitedAttributeGetter<Indexes...>::get(DefaultArithmeticTraits<TraitT>::getTraits().template getAttr<Index>(arg)); } template<typename TraitT, typename = typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value>::type> static auto& get(TraitT* arg){ return TraitedAttributeGetter<Indexes...>::get(DefaultArithmeticTraits<TraitT>::getTraits().template getAttr<Index>(arg)); } }; template <unsigned int Index> struct TraitedAttributeGetter<Index>{ template<typename TraitT, typename = typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value>::type> static auto& get(TraitT& arg){ return DefaultArithmeticTraits<TraitT>::getTraits().template getAttr<Index>(arg); } template<typename TraitT, typename = typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value>::type> static auto& get(TraitT* arg){ return DefaultArithmeticTraits<TraitT>::getTraits().template getAttr<Index>(arg); } }; } //Impl template <typename ArythmeticTraitT, unsigned int ...Indexes, typename = typename std::enable_if<HasDefaultArithmeticTraits<ArythmeticTraitT>::value>::type> auto& getTraitedAttribute(ArythmeticTraitT& arg){ return Impl::TraitedAttributeGetter<Indexes...>::get(arg); } template <typename ArythmeticTraitT, unsigned int ...Indexes, typename = typename std::enable_if<HasDefaultArithmeticTraits<ArythmeticTraitT>::value>::type> auto& getTraitedAttribute(ArythmeticTraitT* arg){ return Impl::TraitedAttributeGetter<Indexes...>::get(arg); } #include "../Macros/MacroForEach.h" #include "../Macros/MacroForEach.h" #define IMPL_MEMREF_TYPE_CUSTOM(name, memberRef) decltype(memberRef) #define IMPL_MEMREF_TYPE_CUSTOM(name, memberRef) decltype(memberRef) Loading Loading
TemplateTest/main.cpp +86 −18 Original line number Original line Diff line number Diff line Loading @@ -3,7 +3,7 @@ #include "../src/UnstructuredMesh/UnstructuredMesh.h" #include "../src/UnstructuredMesh/UnstructuredMesh.h" #include "../src/Traits/MemberApproach/MemberApproach.h" #include "../src/Traits/MemberApproach/MemberApproach.h" #include "../src/Traits/Traits.h" #include "../src/Traits/Traits.h" #include "../src/Singleton/Singleton.h" #include <chrono> #include <chrono> #include <functional> #include <functional> #include <type_traits> #include <type_traits> Loading Loading @@ -322,14 +322,6 @@ void testMemberRef(){ DBGVAR(e, ClassC<>()); DBGVAR(e, ClassC<>()); } } void testTraitsAlgorithms() { ExportTest e1, e2; ExportTest res = e1 + e2; std::vector<ExportTest> vec(40, ExportTest()); DBGVAR(2.45*e1,e1 + e2, e1, e2,HasDefaultArithmeticTraits<int>::value, max(e2), min(e2), max(vec)); } struct NumStruct { struct NumStruct { double data; double data; Loading @@ -340,10 +332,32 @@ MAKE_ATTRIBUTE_TRAIT(NumStruct, data); struct NumStruct2 { struct NumStruct2 { double data1; double data1; double data2; double data2; NumStruct2(double d1 = 0.0, double d2 = 0.0): data1(d1), data2(d2){} }; }; MAKE_ATTRIBUTE_TRAIT(NumStruct2, data1, data2); MAKE_ATTRIBUTE_TRAIT(NumStruct2, data1, data2); void testTraitsAlgorithms() { ExportTest e1, e2; ExportTest res = e1 + e2; std::vector<ExportTest> vec(40, ExportTest()); DBGVAR(2.45*e1,e1 + e2, e1, e2,HasDefaultArithmeticTraits<int>::value, max(e2), min(e2), max(vec)); NumStruct2 ns{21,15}, ns2{2,3}; DBGVAR(ns * ns2, -(ns + 4 * ns2), max(-(ns + 4 * ns2)), max(abs(-(ns + 4 * ns2))), log(ns), exp(log(ns)), pow(sqrt(ns), 2) ); } template <unsigned int Index> template <unsigned int Index> const MemberReference<tempData, DefaultArithmeticTraits<tempData>::traitsType::type<Index>, DefaultArithmeticTraits<tempData>::traitsType::refType<Index>> const MemberReference<tempData, DefaultArithmeticTraits<tempData>::traitsType::type<Index>, DefaultArithmeticTraits<tempData>::traitsType::refType<Index>> getReference() { getReference() { Loading Loading @@ -1048,6 +1062,24 @@ void testNumericTraitsPerformance() { duration = 0; duration = 0; DBGMSG("numeric traits = +"); start = clock.now(); res2 = NumStruct2(); for(int rep = 0; rep < maxRep; rep++){ for(size_t i = 0; i < numVec2.size(); i++) { res2 = res2 + numVec2[i]; } duration += (clock.now() - start).count(); deviation += (clock.now() - start).count() * (clock.now() - start).count(); start = clock.now(); } avgDuration = duration / maxRep; DBGVAR(res2, avgDuration , sqrt(((deviation)- maxRep * pow(avgDuration,2)) / (maxRep - 1))); deviation = 0; duration = 0; DBGMSG("\n","ExportTest performance, direct approach"); DBGMSG("\n","ExportTest performance, direct approach"); std::vector<ExportTest> vec3(size, ExportTest()); std::vector<ExportTest> vec3(size, ExportTest()); Loading Loading @@ -1093,6 +1125,9 @@ void testNumericTraitsPerformance() { deviation = 0; deviation = 0; duration = 0; duration = 0; } } Loading Loading @@ -1297,15 +1332,15 @@ template <typename Class, typename T> class Func { class Func { public: public: template <typename U = T> template <typename U = T, typename refType> auto operator()(unsigned int index, const MemberApproach<Class, T>&, const std::string& name) auto operator()(unsigned int index, const MemberReference<Class, T, refType>&, const std::string& name) -> typename std::enable_if<!(HasDefaultTraits<U>::value)>::type -> typename std::enable_if<!(HasDefaultTraits<U>::value)>::type { { DBGVAR(Singleton<Depth>::getInstance().value,index, name); DBGVAR(Singleton<Depth>::getInstance().value,index, name); } } template <typename U = T> template <typename U = T, typename refType> auto operator()(unsigned int index, const MemberApproach<Class, T>&, const std::string& name) auto operator()(unsigned int index, const MemberReference<Class, T, refType>&, const std::string& name) -> typename std::enable_if<HasDefaultTraits<U>::value>::type -> typename std::enable_if<HasDefaultTraits<U>::value>::type { { DBGVAR(Singleton<Depth>::getInstance().value,index, name); DBGVAR(Singleton<Depth>::getInstance().value,index, name); Loading Loading @@ -1602,7 +1637,7 @@ class TestMemberReference{ template <typename Class, typename ValueType> template <typename Class, typename ValueType> class TestMemberReference<Class, ValueType, ValueType Class::*> : MemberApproach<Class, ValueType>{ class TestMemberReference<Class, ValueType, ValueType Class::*> /*: MemberApproach<Class, ValueType>*/{ using refType = ValueType Class::*; using refType = ValueType Class::*; public: public: Loading Loading @@ -1902,7 +1937,7 @@ void testTraitPerformance() { DBGVAR(res, avgDuration , sqrt(((deviation)- maxRep * pow(avgDuration,2)) / (maxRep - 1))); DBGVAR(res, avgDuration , sqrt(((deviation)- maxRep * pow(avgDuration,2)) / (maxRep - 1))); deviation = 0; deviation = 0; duration = 0; duration = 0; /* DBGMSG("member reference virtual"); DBGMSG("member reference virtual"); const MemberApproach<ExportTest, double>* MA = new MemberReference<ExportTest, double, decltype (&ExportTest::attrDouble)>(&ExportTest::attrDouble); const MemberApproach<ExportTest, double>* MA = new MemberReference<ExportTest, double, decltype (&ExportTest::attrDouble)>(&ExportTest::attrDouble); start = clock.now(); start = clock.now(); Loading @@ -1920,7 +1955,7 @@ void testTraitPerformance() { DBGVAR(res, avgDuration , sqrt(((deviation)- maxRep * pow(avgDuration,2)) / (maxRep - 1))); DBGVAR(res, avgDuration , sqrt(((deviation)- maxRep * pow(avgDuration,2)) / (maxRep - 1))); deviation = 0; deviation = 0; duration = 0; duration = 0; */ DBGMSG("traits"); DBGMSG("traits"); start = clock.now(); start = clock.now(); Loading Loading @@ -2290,6 +2325,38 @@ void testTraitsTuple(){ DBGVAR(foo(t), t); DBGVAR(foo(t), t); } } /* template <unsigned int n, unsigned int _n = 1> constexpr typename std::enable_if<(_n == n), unsigned int>::type factorial(){ return _n; } template <unsigned int n, unsigned int _n = 1> constexpr typename std::enable_if<(_n < n), unsigned int>::type factorial(){ return factorial<n,_n+1>() * _n; } */ namespace Impl { template <unsigned int n, unsigned int _n = 1> constexpr typename std::enable_if<(_n == n), unsigned int>::type factorial(){ return _n; } template <unsigned int n, unsigned int _n = 1> constexpr typename std::enable_if<(_n < n), unsigned int>::type factorial(){ return Impl::factorial<n,_n+1>() * _n; } } void testFactorial() { DBGVAR(Impl::factorial<5>()); } int main() int main() { { Loading @@ -2308,8 +2375,9 @@ int main() //testJson(); //testJson(); //testTestTraits(); //testTestTraits(); //testTraitsAlgorithms(); //testTraitsAlgorithms(); //testNumericTraitsPerformance(); testNumericTraitsPerformance(); testTraitsTuple(); //testTraitsTuple(); //testFactorial(); return 0; return 0; } } Loading
src/Traits/MemberApproach/MemberApproach.h +84 −51 Original line number Original line Diff line number Diff line Loading @@ -4,22 +4,45 @@ #include <utility> #include <utility> /** /** * @brief The MemberApproach class * @brief The DirectReference struct determines that the * Generic abstract class providing the approach to * reference can provide direct approach to the member. * any attribute of a class using getValue and setValue */ */ template <typename Class, typename ValueType> struct DirectReference{ class MemberApproach{ static constexpr std::true_type is_direct{}; public: virtual ValueType getValue(const Class*) const = 0; virtual void setValue(Class*, const ValueType&) const = 0; virtual ValueType getValue(const Class&) const = 0; virtual void setValue(Class&, const ValueType&) const = 0; }; }; namespace Impl { template <typename T, typename = void> struct IsDirectReference : public std::false_type {}; template <typename T> struct IsDirectReference < T, typename std::enable_if<T::is_direct>::type > : public std::true_type {}; } // Impl /** * @brief The IsDirectReference struct inherits * @ref std::true_type if the class MemberReference provides direct * approach to the member using function getAttr. */ template <typename T> struct IsDirectReference : public Impl::IsDirectReference<T> {}; template<typename Class, typename ValueType, typename Ref> template<typename Class, typename ValueType, typename Ref> class MemberReference{ class MemberReference{ static_assert (std::is_same<Ref, ValueType Class::*>::value, static_assert (std::is_same<Ref, ValueType Class::*>::value, Loading @@ -29,7 +52,7 @@ class MemberReference{ template <typename Class, typename ValueType> template <typename Class, typename ValueType> class MemberReference<Class, ValueType, ValueType Class::*> : public MemberApproach<Class, ValueType>{ class MemberReference<Class, ValueType, ValueType Class::*> : public DirectReference { using refType = ValueType Class::*; using refType = ValueType Class::*; Loading @@ -45,11 +68,11 @@ public: MemberReference(MemberReference<Class, ValueType, ValueType Class::*>&&) = default; MemberReference(MemberReference<Class, ValueType, ValueType Class::*>&&) = default; virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return c->*ref; return c->*ref; } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { c->*ref = val; c->*ref = val; } } Loading @@ -57,11 +80,11 @@ public: return c->*ref; return c->*ref; } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return c.*ref; return c.*ref; } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { c.*ref = val; c.*ref = val; } } Loading @@ -75,7 +98,7 @@ public: template <typename Class, typename ValueType> template <typename Class, typename ValueType> class MemberReference<Class, ValueType, ValueType& (Class::*)()> : public MemberApproach<Class, ValueType>{ class MemberReference<Class, ValueType, ValueType& (Class::*)()> : public DirectReference { using refType = ValueType& (Class::*)(); using refType = ValueType& (Class::*)(); Loading @@ -89,21 +112,29 @@ public: //ref = referenceToMember; //ref = referenceToMember; } } virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return (c->*ref)(); } ValueType& getAttr(Class* c) const { return (c->*ref)(); return (c->*ref)(); } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { (c->*ref)() = val; (c->*ref)() = val; } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return (c.*ref)(); return (c.*ref)(); } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { (c.*ref)() = val; (c.*ref)() = val; } } ValueType& getAttr(Class& c) const { return (c->*ref)(); } }; }; Loading @@ -115,7 +146,7 @@ class MemberReference< ValueType, ValueType, std::pair<ValueType (Class::*)(), void (Class::*)(const ValueType&)> std::pair<ValueType (Class::*)(), void (Class::*)(const ValueType&)> > > : public MemberApproach<Class, ValueType>{ { using getter = ValueType (Class::*)(); using getter = ValueType (Class::*)(); getter const refGet; getter const refGet; Loading @@ -130,19 +161,19 @@ public: //refSet = getSet.second; //refSet = getSet.second; } } virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return (c->*refGet)(); return (c->*refGet)(); } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { (c->*refSet)(val); (c->*refSet)(val); } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return (c.*refGet)(); return (c.*refGet)(); } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { (c.*refSet)(val); (c.*refSet)(val); } } }; }; Loading @@ -154,7 +185,7 @@ class MemberReference< ValueType, ValueType, std::pair<ValueType (Class::*)() const, void (Class::*)(const ValueType&)> std::pair<ValueType (Class::*)() const, void (Class::*)(const ValueType&)> > > : public MemberApproach<Class, ValueType>{ { using getter = ValueType (Class::*)() const; using getter = ValueType (Class::*)() const; getter const refGet; getter const refGet; Loading @@ -169,19 +200,19 @@ public: //refSet = getSet.second; //refSet = getSet.second; } } virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return (c->*refGet)(); return (c->*refGet)(); } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { (c->*refSet)(val); (c->*refSet)(val); } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return (c.*refGet)(); return (c.*refGet)(); } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { (c.*refSet)(val); (c.*refSet)(val); } } }; }; Loading @@ -193,7 +224,7 @@ class MemberReference< ValueType, ValueType, std::pair<const ValueType& (Class::*)() const, void (Class::*)(const ValueType&)> std::pair<const ValueType& (Class::*)() const, void (Class::*)(const ValueType&)> > > : public MemberApproach<Class, ValueType>{ { using getter = const ValueType& (Class::*)() const; using getter = const ValueType& (Class::*)() const; getter const refGet; getter const refGet; Loading @@ -208,19 +239,19 @@ public: //refSet = getSet.second; //refSet = getSet.second; } } virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return (c->*refGet)(); return (c->*refGet)(); } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { (c->*refSet)(val); (c->*refSet)(val); } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return (c.*refGet)(); return (c.*refGet)(); } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { (c.*refSet)(val); (c.*refSet)(val); } } }; }; Loading @@ -232,7 +263,7 @@ class MemberReference< ValueType, ValueType, std::pair<const ValueType& (Class::*)(), void (Class::*)(const ValueType&)> std::pair<const ValueType& (Class::*)(), void (Class::*)(const ValueType&)> > > : public MemberApproach<Class, ValueType>{ { using getter = const ValueType& (Class::*)(); using getter = const ValueType& (Class::*)(); getter const refGet; getter const refGet; Loading @@ -247,19 +278,19 @@ public: //refSet = getSet.second; //refSet = getSet.second; } } virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return (c->*refGet)(); return (c->*refGet)(); } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { (c->*refSet)(val); (c->*refSet)(val); } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return (c.*refGet)(); return (c.*refGet)(); } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { (c.*refSet)(val); (c.*refSet)(val); } } }; }; Loading @@ -267,7 +298,8 @@ public: template <typename Class, typename ValueType> template <typename Class, typename ValueType> class MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class&), const ValueType&(*)(const Class&)>> : public MemberApproach<Class, ValueType>{ class MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class&), const ValueType&(*)(const Class&)>> : public DirectReference { using setter = ValueType& (*)(Class&); using setter = ValueType& (*)(Class&); Loading @@ -289,21 +321,21 @@ public: MemberReference(MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class&), const ValueType&(*)(const Class&)>>&&) = default; MemberReference(MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class&), const ValueType&(*)(const Class&)>>&&) = default; virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return get(*c); return get(*c); } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { set(*c) = val; set(*c) = val; } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return get(c); return get(c); } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { set(c) = val; set(c) = val; } } Loading @@ -318,7 +350,8 @@ public: template <typename Class, typename ValueType> template <typename Class, typename ValueType> class MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class*), const ValueType&(*)(const Class*)>> : public MemberApproach<Class, ValueType>{ class MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class*), const ValueType&(*)(const Class*)>> : public DirectReference { using setter = ValueType& (*)(Class*); using setter = ValueType& (*)(Class*); Loading @@ -340,21 +373,21 @@ public: MemberReference(MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class*), const ValueType&(*)(const Class*)>>&&) = default; MemberReference(MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class*), const ValueType&(*)(const Class*)>>&&) = default; virtual ValueType getValue(const Class* c) const override { ValueType getValue(const Class* c) const { return get(c); return get(c); } } virtual void setValue(Class* c, const ValueType& val) const override { void setValue(Class* c, const ValueType& val) const { set(c) = val; set(c) = val; } } virtual ValueType getValue(const Class& c) const override { ValueType getValue(const Class& c) const { return get(&c); return get(&c); } } virtual void setValue(Class& c, const ValueType& val) const override { void setValue(Class& c, const ValueType& val) const { set(&c) = val; set(&c) = val; } } Loading
src/Traits/Traits.h +66 −5 Original line number Original line Diff line number Diff line Loading @@ -3,7 +3,6 @@ #include "MemberApproach/MemberApproach.h" #include "MemberApproach/MemberApproach.h" #include <string> #include <string> #include <memory> #include <memory> #include "../Singleton/Singleton.h" #include <functional> #include <functional> template<typename Class, typename...RefTypes> template<typename Class, typename...RefTypes> Loading Loading @@ -74,6 +73,19 @@ public: } } template<unsigned int Index> type<Index>& getAttr(Class* c) const { static_assert (IsDirectReference<memRefType<Index>>::value, "The current reference to the member does not provide direct approach."); return getReference<Index>()->getAttr(c); } template<unsigned int Index> type<Index>& getAttr(Class& c) const { static_assert (IsDirectReference<memRefType<Index>>::value, "The current reference to the member does not provide direct approach."); return getReference<Index>().getAttr(c); } template<unsigned int Index> template<unsigned int Index> const char* getName() const { const char* getName() const { return refs.MemRefs<Index, void>::name; return refs.MemRefs<Index, void>::name; Loading Loading @@ -261,12 +273,61 @@ public: template<typename Class> template<typename Class> class DefaultIOTraits : public Traits<Class> {}; class DefaultIOTraits : public Traits<Class> {}; template<typename Class> template<typename Class> class DefaultArithmeticTraits : public Traits<Class> {}; class DefaultArithmeticTraits : public Traits<Class> {}; #include "CustomTypeTraits.h" namespace Impl { template <unsigned int Index, unsigned int ...Indexes> struct TraitedAttributeGetter{ template<typename TraitT, typename = typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value>::type> static auto& get(TraitT& arg){ return TraitedAttributeGetter<Indexes...>::get(DefaultArithmeticTraits<TraitT>::getTraits().template getAttr<Index>(arg)); } template<typename TraitT, typename = typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value>::type> static auto& get(TraitT* arg){ return TraitedAttributeGetter<Indexes...>::get(DefaultArithmeticTraits<TraitT>::getTraits().template getAttr<Index>(arg)); } }; template <unsigned int Index> struct TraitedAttributeGetter<Index>{ template<typename TraitT, typename = typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value>::type> static auto& get(TraitT& arg){ return DefaultArithmeticTraits<TraitT>::getTraits().template getAttr<Index>(arg); } template<typename TraitT, typename = typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value>::type> static auto& get(TraitT* arg){ return DefaultArithmeticTraits<TraitT>::getTraits().template getAttr<Index>(arg); } }; } //Impl template <typename ArythmeticTraitT, unsigned int ...Indexes, typename = typename std::enable_if<HasDefaultArithmeticTraits<ArythmeticTraitT>::value>::type> auto& getTraitedAttribute(ArythmeticTraitT& arg){ return Impl::TraitedAttributeGetter<Indexes...>::get(arg); } template <typename ArythmeticTraitT, unsigned int ...Indexes, typename = typename std::enable_if<HasDefaultArithmeticTraits<ArythmeticTraitT>::value>::type> auto& getTraitedAttribute(ArythmeticTraitT* arg){ return Impl::TraitedAttributeGetter<Indexes...>::get(arg); } #include "../Macros/MacroForEach.h" #include "../Macros/MacroForEach.h" #define IMPL_MEMREF_TYPE_CUSTOM(name, memberRef) decltype(memberRef) #define IMPL_MEMREF_TYPE_CUSTOM(name, memberRef) decltype(memberRef) Loading