Newer
Older
#ifndef PRINTTRAITEDCLASS_H
#define PRINTTRAITEDCLASS_H
#include "../VariableExport.h"
template <typename Class, typename ClassTraits>
struct IsTraitsOf : public std::false_type {};
template <typename Class, typename ClassTraits>
struct IsTraitsOf<Class, const ClassTraits&> : public IsTraitsOf<Class, std::decay_t<ClassTraits>>{};
template <typename Class, typename ... TraitsArgs>
struct IsTraitsOf<Class, Traits<Class, TraitsArgs...>> : public std::true_type {};
/**
* This class selects the first class traits with respect
Tomáš Jakubec
committed
* to Class. If none type of traits is given, it returns
* DefaultIOTraits<Class> if possible.
Tomáš Jakubec
committed
template <typename Class, size_t Index, typename... TraitsTypes>
struct SelectTraits{};
template <typename Class, size_t Index, typename TraitsType, typename... TraitsTypes>
Tomáš Jakubec
committed
struct SelectTraits<Class, Index, TraitsType, TraitsTypes...> : public
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
std::conditional_t<IsTraitsOf<Class, TraitsType>::value, SelectTraits<Class, Index, TraitsType>, SelectTraits<Class, Index + 1, TraitsTypes...>>{};
template <typename Class, size_t Index, typename TraitsType>
struct SelectTraits<Class, Index, TraitsType> {
static constexpr bool valid = IsTraitsOf<Class, TraitsType>::value || HasDefaultIOTraits<Class>::value;
private:
template <bool b, bool valid, typename = void>
struct _conditional{
using type = TraitsType;
};
template <typename Dummy>
struct _conditional<false, true, Dummy>{
using type = typename DefaultIOTraits<Class>::traitsType;
};
template <typename Dummy>
struct _conditional<false, false, Dummy>{
using type = void;
};
public:
using TypeTraits = typename _conditional< IsTraitsOf<Class, TraitsType>::value, valid >::type;
template<typename ... Args, typename TT = TraitsType, typename std::enable_if<IsTraitsOf<Class, TT>::value, bool>::type = true>
static const auto& getTraitsInstance(const std::tuple<Args...>& t) {
return std::get<Index>(t);
}
template<typename ... Args, typename TT = TraitsType, typename std::enable_if<!IsTraitsOf<Class, TT>::value, bool>::type = true>
static auto getTraitsInstance(const std::tuple<Args...>&) {
return DefaultIOTraits<Class>::getTraits();
}
};
Tomáš Jakubec
committed
template <typename Class, size_t Index>
struct SelectTraits<Class, Index> {
static constexpr bool valid = HasDefaultIOTraits<Class>::value;
private:
template <bool valid, typename = void>
struct _conditional{
using type = typename DefaultIOTraits<Class>::traitsType;
};
template <typename Dummy>
struct _conditional<false, Dummy>{
using type = void;
};
public:
using TypeTraits = typename _conditional< valid >::type;
template<typename ... Args>
static auto getTraitsInstance(const std::tuple<Args...>&) {
return DefaultIOTraits<Class>::getTraits();
}
};
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
struct PrintTraitedClass {
static int print(...){return 0;}
template<typename T, typename TraitsIO, unsigned int Index = 0, bool = Index == TraitsIO::size() - 1>
struct PrintClass{
static void print(std::ostream& ost, const T &traitedClass, const TraitsIO& traitsIO){
PrintClass<T, TraitsIO, Index, true>::print(ost, traitedClass, traitsIO);
ost << ", ";
PrintClass<T, TraitsIO, Index + 1>::print(ost, traitedClass, traitsIO);
}
template <typename ... _Traits, typename _T = T>
static void print(std::ostream& ost, const _T &traitedClass, const TraitsIO& traitsIO, std::tuple<const _Traits& ...> t){
PrintClass<T, TraitsIO, Index, true>::print(ost, traitedClass, traitsIO, t);
ost << ", ";
PrintClass<T, TraitsIO, Index + 1>::print(ost, traitedClass, traitsIO, t);
}
static void print(const T &traitedClass, const TraitsIO& traitsIO){
PrintClass<T, TraitsIO, Index, true>::print(traitedClass, traitsIO);
printf(", ");
PrintClass<T, TraitsIO, Index + 1>::print(traitedClass, traitsIO);
}
template <typename ... _Traits, typename _T = T>
static void print(const _T &traitedClass, const TraitsIO& traitsIO, std::tuple<const _Traits& ...> t){
PrintClass<T, TraitsIO, Index, true>::print(traitedClass, traitsIO, t);
printf(", ");
PrintClass<T, TraitsIO, Index + 1>::print(traitedClass, traitsIO, t);
}
};
template<typename T, typename TraitsIO, unsigned int Index>
struct PrintClass<T, TraitsIO, Index, true>{
static void print(std::ostream& ost, const T &traitedClass, const TraitsIO& traitsIO){
ost << '"' << traitsIO.template getName<Index>() << "\" : ";
VariableExport<>::exportVariable(ost, traitsIO.template getValue<Index>(traitedClass));
}
template <typename ... _Traits, typename _T = T>
static void print(std::ostream& ost, const _T &traitedClass, const TraitsIO& traitsIO, std::tuple<const _Traits& ...> t) {
ost << '"' << traitsIO.template getName<Index>() << "\" : ";
VariableExport<>::exportVariable(ost, traitsIO.template getValue<Index>(traitedClass), t);
}
static void print(const T &traitedClass, const TraitsIO& traitsIO){
printf("\"%s\" : ", traitsIO.template getName<Index>());
VariableExport<VARIABLE_EXPORT_METHOD_STDIO>::exportVariable(traitsIO.template getValue<Index>(traitedClass));
}
template <typename ... _Traits, typename _T = T>
static void print(const _T &traitedClass, const TraitsIO& traitsIO, std::tuple<const _Traits& ...> t) {
printf("\"%s\" : ", traitsIO.template getName<Index>());
VariableExport<VARIABLE_EXPORT_METHOD_STDIO>::exportVariable(traitsIO.template getValue<Index>(traitedClass), t);
}
};
template<typename TraitedClass, std::enable_if_t<HasDefaultIOTraits<TraitedClass>::value, bool> = true>
static void print(std::ostream& ost, const TraitedClass& var, ...)
{
ost << "{ ";
PrintClass<TraitedClass, typename DefaultIOTraits<TraitedClass>::traitsType>::print(ost, var, DefaultIOTraits<TraitedClass>::getTraits());
ost << " }";
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
}
template<typename Class, typename ...TraitsTypes>
using IsValid = std::enable_if_t<SelectTraits<Class, 0, TraitsTypes...>::valid, bool>;
template< typename Class, typename PrimaryTraits, typename ... SecondaryTraits>
static void print(std::ostream& ost, const TraitsBinder<Class, PrimaryTraits, SecondaryTraits...> &traitedClass, ...)
{
VariableExport<>::exportVariable(ost, traitedClass.object, traitedClass.tupTraits);
}
template< typename Class, typename PrimaryTraits, typename ... SecondaryTraits, IsValid<Class, PrimaryTraits, SecondaryTraits...> = true>
static void print(std::ostream& ost, const Class &traitedClass, const std::tuple<PrimaryTraits, SecondaryTraits...>& tupleTraits)
{
auto traits = SelectTraits<Class, 0, PrimaryTraits, SecondaryTraits...>::getTraitsInstance(tupleTraits);
ost << "{ ";
PrintClass<Class, decltype(traits)>::print(ost, traitedClass, traits, tupleTraits);
ost << " }";
}
template<typename TraitedClass, std::enable_if_t<HasDefaultIOTraits<TraitedClass>::value, bool> = true>
static void print(const TraitedClass& var, ...)
{
printf("{ ");
PrintClass<TraitedClass, typename DefaultIOTraits<TraitedClass>::traitsType>::print(var, DefaultIOTraits<TraitedClass>::getTraits());
printf(" }");
}
template< typename Class, typename PrimaryTraits, typename ... SecondaryTraits>
static void print(const TraitsBinder<Class, PrimaryTraits, SecondaryTraits...> &traitedClass, ...)
{
VariableExport<VARIABLE_EXPORT_METHOD_STDIO>::exportVariable(traitedClass.object, traitedClass.tupTraits);
}
template< typename Class, typename PrimaryTraits, typename ... SecondaryTraits, IsValid<Class, PrimaryTraits, SecondaryTraits...> = true>
static void print(const Class &traitedClass, const std::tuple<PrimaryTraits, SecondaryTraits...>& tupleTraits)
{
auto traits = SelectTraits<Class, 0, PrimaryTraits, SecondaryTraits...>::getTraitsInstance(tupleTraits);
printf("{ ");
PrintClass<Class, decltype(traits)>::print(traitedClass, traits, tupleTraits);
printf(" }");
}
};
#endif // PRINTTRAITEDCLASS_H