Loading TemplateTest/main.cpp +51 −1 Original line number Diff line number Diff line Loading @@ -2238,8 +2238,57 @@ void testJson() { }*/ struct testTuple{ double attr1; int attr2; std::string attr3; }; double& getData1(testTuple& s){return s.attr1;} int& getData2(testTuple& s){return s.attr2;} std::string& getData3(testTuple& s){return s.attr3;} const double& getData1(const testTuple& s){return s.attr1;} const int& getData2(const testTuple& s){return s.attr2;} const std::string& getData3(const testTuple& s){return s.attr3;} MAKE_CUSTOM_ATTRIBUTE_TRAIT_IO( testTuple, "1", std::make_pair(static_cast<double&(*)(testTuple&)>(getData1), static_cast<const double&(*)(const testTuple&)>(getData1)), "2", std::make_pair(static_cast<int&(*)(testTuple&)>(getData2), static_cast<const int&(*)(const testTuple&)>(getData2)), "3", std::make_pair(static_cast<std::string&(*)(testTuple&)>(getData3), static_cast<const std::string&(*)(const testTuple&)>(getData3)) ); using double_tuple = std::tuple<double>; MAKE_CUSTOM_ATTRIBUTE_TRAIT( double_tuple, "double attr", std::make_pair(static_cast<double&(*)(std::tuple<double>&)>(std::get<0>), static_cast<const double&(*)(const std::tuple<double>&)>(std::get<0>)) ); template <typename ...T> class Traits<std::tuple<T...>>{ static constexpr std::true_type is_specialized{}; using traitsType = ::Traits<std::tuple<T...>, T...>; }; void testTraitsTuple(){ testTuple tt; DefaultIOTraits<testTuple>::getTraits().setValue<1>(tt, 5); DefaultIOTraits<testTuple>::getTraits().setValue<2>(tt, "Hello :)"); DBGVAR(tt); std::tuple<double> t{1.5}; get<0>(t) = 2.5; auto foo = static_cast<double&(*)(std::tuple<double>&)>(std::get<0>); DBGVAR(foo(t), t); } int main() Loading @@ -2259,7 +2308,8 @@ int main() //testJson(); //testTestTraits(); //testTraitsAlgorithms(); testNumericTraitsPerformance(); //testNumericTraitsPerformance(); testTraitsTuple(); return 0; } Loading src/Debug/VariableExport.h +2 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,8 @@ struct VariableExport { !std::is_same<T, std::string>::value && !std::is_same<T, const char*>::value && !std::is_same<T, char*>::value && !std::is_same<T, const char>::value !std::is_same<T, const char>::value && !HasDefaultIOTraits<T>::value >::type { ost << b; Loading src/Traits/MemberApproach/MemberApproach.h +124 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,10 @@ public: c->*ref = val; } ValueType& getAttr(Class* c) const { return c->*ref; } virtual ValueType getValue(const Class& c) const override { return c.*ref; } Loading @@ -67,6 +71,9 @@ public: }; template <typename Class, typename ValueType> class MemberReference<Class, ValueType, ValueType& (Class::*)()> : public MemberApproach<Class, ValueType>{ Loading Loading @@ -259,6 +266,111 @@ public: template <typename Class, typename ValueType> class MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class&), const ValueType&(*)(const Class&)>> : public MemberApproach<Class, ValueType>{ using setter = ValueType& (*)(Class&); const setter set; using getter = const ValueType&(*)(const Class&); const getter get; public: MemberReference(std::pair<ValueType&(*)(Class&), const ValueType&(*)(const Class&)> referenceToMember) : set(referenceToMember.first), get(referenceToMember.second) { //ref = referenceToMember; } MemberReference(const 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 { return get(*c); } virtual void setValue(Class* c, const ValueType& val) const override { set(*c) = val; } virtual ValueType getValue(const Class& c) const override { return get(c); } virtual void setValue(Class& c, const ValueType& val) const override { set(c) = val; } ValueType& getAttr(Class& c) const { return set(c); } ValueType& getAttr(Class* c) const { return set(*c); } }; template <typename Class, typename ValueType> class MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class*), const ValueType&(*)(const Class*)>> : public MemberApproach<Class, ValueType>{ using setter = ValueType& (*)(Class*); const setter set; using getter = const ValueType&(*)(const Class*); const getter get; public: MemberReference(std::pair<ValueType&(*)(Class*), const ValueType&(*)(const Class*)> referenceToMember) : set(referenceToMember.first), get(referenceToMember.second) { //ref = referenceToMember; } MemberReference(const 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 { return get(c); } virtual void setValue(Class* c, const ValueType& val) const override { set(c) = val; } virtual ValueType getValue(const Class& c) const override { return get(&c); } virtual void setValue(Class& c, const ValueType& val) const override { set(&c) = val; } ValueType& getAttr(Class& c) const { return set(&c); } ValueType& getAttr(Class* c) const { return set(c); } }; template <typename Ref> struct MemberReferenceType { static_assert (std::is_trivial<Ref>::value, "The Ref must be a type of member reference (MemberType Class::*) or reference getter (MemberType& (Class::*)()) into class \ Loading Loading @@ -303,4 +415,16 @@ struct MemberReferenceType <std::pair<const MemberType& (Class::*)(), void (Clas using typeClass = Class; }; template <typename Class, typename MemberType> struct MemberReferenceType <std::pair<MemberType&(*)(Class&), const MemberType&(*)(const Class&)>>{ using type = MemberType; using typeClass = Class; }; template <typename Class, typename MemberType> struct MemberReferenceType <std::pair<MemberType&(*)(Class*), const MemberType&(*)(const Class*)>>{ using type = MemberType; using typeClass = Class; }; #endif // MEMBERAPPROACH_H src/Traits/Traits.h +1 −0 Original line number Diff line number Diff line Loading @@ -260,6 +260,7 @@ public: }; template<typename Class> class DefaultIOTraits : public Traits<Class> {}; Loading src/Traits/TraitsAlgorithm/TraitsAlgorithm.h +100 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ operator+=(TraitT& op1, const TraitT& op2) noexcept { template <typename TraitT> typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value, TraitT>::type operator+(const TraitT& op1, const TraitT& op2) noexcept { DBGMSG("+"); TraitT res(op1); return operator+=(res, op2); } Loading @@ -59,6 +60,23 @@ operator+(const TraitT& op1, const TraitT& op2) noexcept { template <typename TraitT> typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value, TraitT>::type operator+(const TraitT& op1, TraitT&& op2) noexcept { DBGMSG("+="); return op2 += op1; } template <typename TraitT> typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value, TraitT>::type operator+(TraitT&& op1, const TraitT& op2) noexcept { DBGMSG("+="); return op1 += op2; } template <typename TraitT> typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value, TraitT>::type operator+(TraitT&& op1, TraitT&& op2) noexcept { DBGMSG("+="); return op2 += op1; } Loading Loading @@ -275,6 +293,24 @@ max(const T& array) noexcept { return res; } template <typename T> typename std::enable_if< IsTNLIndexable<T>::value, double >::type max(const T& array) noexcept { double res = std::numeric_limits<double>::min(); for (decltype (array.getSize()) index = 0; index < array.getSize(); index++){ double m = max(array[index]); if (res < m){ res = m; } } return res; } template <typename TraitT> typename std::enable_if< HasDefaultArithmeticTraits<TraitT>::value, Loading Loading @@ -345,4 +381,68 @@ min(const TraitT& op1) noexcept { return res; } template <typename T> typename std::enable_if< !std::is_class<T>::value, T >::type abs(const T& arg) noexcept { return std::abs(arg); } template <typename T> typename std::enable_if< IsIndexable<T>::value, T >::type abs(const T& array) noexcept { T resArray(array); for (decltype (resArray.size()) index = 0; index < resArray.size(); index++){ resArray[index] = abs(resArray[index]); } return resArray; } template <typename T> typename std::enable_if< IsTNLIndexable<T>::value, T >::type abs(const T& array) noexcept { T resArray(array); for (decltype (resArray.getSize()) index = 0; index < resArray.getSize(); index++){ resArray[index] = abs(resArray[index]); } return resArray; } template <typename TraitT> typename std::enable_if< HasDefaultArithmeticTraits<TraitT>::value, TraitT >::type abs(const TraitT& op1) noexcept { TraitT res; DefaultArithmeticTraits<TraitT>::getTraits().apply( [&res, &op1](unsigned int, const auto& ref, const std::string&) noexcept { ref.setValue(res, abs(ref.getValue(op1))); } ); return res; } #endif // TRAITSALGORITHM_H Loading
TemplateTest/main.cpp +51 −1 Original line number Diff line number Diff line Loading @@ -2238,8 +2238,57 @@ void testJson() { }*/ struct testTuple{ double attr1; int attr2; std::string attr3; }; double& getData1(testTuple& s){return s.attr1;} int& getData2(testTuple& s){return s.attr2;} std::string& getData3(testTuple& s){return s.attr3;} const double& getData1(const testTuple& s){return s.attr1;} const int& getData2(const testTuple& s){return s.attr2;} const std::string& getData3(const testTuple& s){return s.attr3;} MAKE_CUSTOM_ATTRIBUTE_TRAIT_IO( testTuple, "1", std::make_pair(static_cast<double&(*)(testTuple&)>(getData1), static_cast<const double&(*)(const testTuple&)>(getData1)), "2", std::make_pair(static_cast<int&(*)(testTuple&)>(getData2), static_cast<const int&(*)(const testTuple&)>(getData2)), "3", std::make_pair(static_cast<std::string&(*)(testTuple&)>(getData3), static_cast<const std::string&(*)(const testTuple&)>(getData3)) ); using double_tuple = std::tuple<double>; MAKE_CUSTOM_ATTRIBUTE_TRAIT( double_tuple, "double attr", std::make_pair(static_cast<double&(*)(std::tuple<double>&)>(std::get<0>), static_cast<const double&(*)(const std::tuple<double>&)>(std::get<0>)) ); template <typename ...T> class Traits<std::tuple<T...>>{ static constexpr std::true_type is_specialized{}; using traitsType = ::Traits<std::tuple<T...>, T...>; }; void testTraitsTuple(){ testTuple tt; DefaultIOTraits<testTuple>::getTraits().setValue<1>(tt, 5); DefaultIOTraits<testTuple>::getTraits().setValue<2>(tt, "Hello :)"); DBGVAR(tt); std::tuple<double> t{1.5}; get<0>(t) = 2.5; auto foo = static_cast<double&(*)(std::tuple<double>&)>(std::get<0>); DBGVAR(foo(t), t); } int main() Loading @@ -2259,7 +2308,8 @@ int main() //testJson(); //testTestTraits(); //testTraitsAlgorithms(); testNumericTraitsPerformance(); //testNumericTraitsPerformance(); testTraitsTuple(); return 0; } Loading
src/Debug/VariableExport.h +2 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,8 @@ struct VariableExport { !std::is_same<T, std::string>::value && !std::is_same<T, const char*>::value && !std::is_same<T, char*>::value && !std::is_same<T, const char>::value !std::is_same<T, const char>::value && !HasDefaultIOTraits<T>::value >::type { ost << b; Loading
src/Traits/MemberApproach/MemberApproach.h +124 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,10 @@ public: c->*ref = val; } ValueType& getAttr(Class* c) const { return c->*ref; } virtual ValueType getValue(const Class& c) const override { return c.*ref; } Loading @@ -67,6 +71,9 @@ public: }; template <typename Class, typename ValueType> class MemberReference<Class, ValueType, ValueType& (Class::*)()> : public MemberApproach<Class, ValueType>{ Loading Loading @@ -259,6 +266,111 @@ public: template <typename Class, typename ValueType> class MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class&), const ValueType&(*)(const Class&)>> : public MemberApproach<Class, ValueType>{ using setter = ValueType& (*)(Class&); const setter set; using getter = const ValueType&(*)(const Class&); const getter get; public: MemberReference(std::pair<ValueType&(*)(Class&), const ValueType&(*)(const Class&)> referenceToMember) : set(referenceToMember.first), get(referenceToMember.second) { //ref = referenceToMember; } MemberReference(const 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 { return get(*c); } virtual void setValue(Class* c, const ValueType& val) const override { set(*c) = val; } virtual ValueType getValue(const Class& c) const override { return get(c); } virtual void setValue(Class& c, const ValueType& val) const override { set(c) = val; } ValueType& getAttr(Class& c) const { return set(c); } ValueType& getAttr(Class* c) const { return set(*c); } }; template <typename Class, typename ValueType> class MemberReference<Class, ValueType, std::pair<ValueType&(*)(Class*), const ValueType&(*)(const Class*)>> : public MemberApproach<Class, ValueType>{ using setter = ValueType& (*)(Class*); const setter set; using getter = const ValueType&(*)(const Class*); const getter get; public: MemberReference(std::pair<ValueType&(*)(Class*), const ValueType&(*)(const Class*)> referenceToMember) : set(referenceToMember.first), get(referenceToMember.second) { //ref = referenceToMember; } MemberReference(const 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 { return get(c); } virtual void setValue(Class* c, const ValueType& val) const override { set(c) = val; } virtual ValueType getValue(const Class& c) const override { return get(&c); } virtual void setValue(Class& c, const ValueType& val) const override { set(&c) = val; } ValueType& getAttr(Class& c) const { return set(&c); } ValueType& getAttr(Class* c) const { return set(c); } }; template <typename Ref> struct MemberReferenceType { static_assert (std::is_trivial<Ref>::value, "The Ref must be a type of member reference (MemberType Class::*) or reference getter (MemberType& (Class::*)()) into class \ Loading Loading @@ -303,4 +415,16 @@ struct MemberReferenceType <std::pair<const MemberType& (Class::*)(), void (Clas using typeClass = Class; }; template <typename Class, typename MemberType> struct MemberReferenceType <std::pair<MemberType&(*)(Class&), const MemberType&(*)(const Class&)>>{ using type = MemberType; using typeClass = Class; }; template <typename Class, typename MemberType> struct MemberReferenceType <std::pair<MemberType&(*)(Class*), const MemberType&(*)(const Class*)>>{ using type = MemberType; using typeClass = Class; }; #endif // MEMBERAPPROACH_H
src/Traits/Traits.h +1 −0 Original line number Diff line number Diff line Loading @@ -260,6 +260,7 @@ public: }; template<typename Class> class DefaultIOTraits : public Traits<Class> {}; Loading
src/Traits/TraitsAlgorithm/TraitsAlgorithm.h +100 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ operator+=(TraitT& op1, const TraitT& op2) noexcept { template <typename TraitT> typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value, TraitT>::type operator+(const TraitT& op1, const TraitT& op2) noexcept { DBGMSG("+"); TraitT res(op1); return operator+=(res, op2); } Loading @@ -59,6 +60,23 @@ operator+(const TraitT& op1, const TraitT& op2) noexcept { template <typename TraitT> typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value, TraitT>::type operator+(const TraitT& op1, TraitT&& op2) noexcept { DBGMSG("+="); return op2 += op1; } template <typename TraitT> typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value, TraitT>::type operator+(TraitT&& op1, const TraitT& op2) noexcept { DBGMSG("+="); return op1 += op2; } template <typename TraitT> typename std::enable_if<HasDefaultArithmeticTraits<TraitT>::value, TraitT>::type operator+(TraitT&& op1, TraitT&& op2) noexcept { DBGMSG("+="); return op2 += op1; } Loading Loading @@ -275,6 +293,24 @@ max(const T& array) noexcept { return res; } template <typename T> typename std::enable_if< IsTNLIndexable<T>::value, double >::type max(const T& array) noexcept { double res = std::numeric_limits<double>::min(); for (decltype (array.getSize()) index = 0; index < array.getSize(); index++){ double m = max(array[index]); if (res < m){ res = m; } } return res; } template <typename TraitT> typename std::enable_if< HasDefaultArithmeticTraits<TraitT>::value, Loading Loading @@ -345,4 +381,68 @@ min(const TraitT& op1) noexcept { return res; } template <typename T> typename std::enable_if< !std::is_class<T>::value, T >::type abs(const T& arg) noexcept { return std::abs(arg); } template <typename T> typename std::enable_if< IsIndexable<T>::value, T >::type abs(const T& array) noexcept { T resArray(array); for (decltype (resArray.size()) index = 0; index < resArray.size(); index++){ resArray[index] = abs(resArray[index]); } return resArray; } template <typename T> typename std::enable_if< IsTNLIndexable<T>::value, T >::type abs(const T& array) noexcept { T resArray(array); for (decltype (resArray.getSize()) index = 0; index < resArray.getSize(); index++){ resArray[index] = abs(resArray[index]); } return resArray; } template <typename TraitT> typename std::enable_if< HasDefaultArithmeticTraits<TraitT>::value, TraitT >::type abs(const TraitT& op1) noexcept { TraitT res; DefaultArithmeticTraits<TraitT>::getTraits().apply( [&res, &op1](unsigned int, const auto& ref, const std::string&) noexcept { ref.setValue(res, abs(ref.getValue(op1))); } ); return res; } #endif // TRAITSALGORITHM_H