Commit 908a5c78 authored by Tomáš Jakubec's avatar Tomáš Jakubec
Browse files

Member reference can hold extern get (constant getter) and set (as non-

const getter).
parent 215130e3
Loading
Loading
Loading
Loading
+51 −1
Original line number Diff line number Diff line
@@ -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()
@@ -2259,7 +2308,8 @@ int main()
    //testJson();
    //testTestTraits();
    //testTraitsAlgorithms();
    testNumericTraitsPerformance();
    //testNumericTraitsPerformance();
    testTraitsTuple();
    return 0;
}

+2 −1
Original line number Diff line number Diff line
@@ -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;
+124 −0
Original line number Diff line number Diff line
@@ -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;
    }
@@ -67,6 +71,9 @@ public:
};





template <typename Class, typename ValueType>
class MemberReference<Class, ValueType, ValueType& (Class::*)()> : public MemberApproach<Class, ValueType>{

@@ -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 \
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -260,6 +260,7 @@ public:
};



template<typename Class>
class DefaultIOTraits : public Traits<Class> {};

+100 −0
Original line number Diff line number Diff line
@@ -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);
}
@@ -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;
}

@@ -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,
@@ -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