Skip to content
Snippets Groups Projects
Commit d9052745 authored by Tomáš Jakubec's avatar Tomáš Jakubec
Browse files

First try of implementation of binding Traits to specify the output

Traits for classes with complex structure.
parent b4a05756
No related branches found
No related tags found
No related merge requests found
......@@ -31,7 +31,7 @@ namespace dbg {
#define DBGVAR(...) ConsoleLogger<>::writeVar(__LINE__, __FILE__, FOR_EACH(STRVAR, __VA_ARGS__))
#define DBGVARCOND(condition, ...) if(condition) DBGVAR(__VA_ARGS__)
#define DBGVAR_STDIO(...) ConsoleLogger<VARIABLE_EXPORT_METHOD::stdio>::writeVar(__LINE__, __FILE__, FOR_EACH(STRVAR, __VA_ARGS__))
#define DBGVAR_STDIO(...) ConsoleLogger<VARIABLE_EXPORT_METHOD_STDIO>::writeVar(__LINE__, __FILE__, FOR_EACH(STRVAR, __VA_ARGS__))
#define DBGVARCOND_STDIO(condition, ...) if(condition) DBGVAR_STDIO(__VA_ARGS__)
#define DBGMSG(...) ConsoleLogger<>::writeMessage("++", __LINE__, __FILE__, __VA_ARGS__)
......
#ifndef PRINTERS_H
#define PRINTERS_H
#include "../VariableExport.h"
class TraitsPrint {
int print(...) {}
template <typename T, std::enable_if_t<HasDefaultIOTraits<T>::value, bool> = true>
void print(const T& var, std::ostream& ost) {
VariableExport<VARIABLE_EXPORT_METHOD_OSTREAM>::PrintClass<>
}
};
#endif // PRINTERS_H
......@@ -5,9 +5,45 @@
#include <string>
#include <sstream>
#include "../Traits/Traits.h"
#include "../Traits/TraitsBind/TraitsBind.h"
#include "../Traits/CustomTypeTraits.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 {};
template <typename Class,typename TraitsType, typename... TraitsTypes>
struct SelectTraits : public
std::conditional_t<isTraitsOf<Class, TraitsType>::value, SelectTraits<Class, TraitsType>, SelectTraits<Class, TraitsTypes...>>{};
template <typename Class,typename TraitsType>
struct SelectTraits<Class, TraitsType> {
using TypeTraits = std::conditional_t< isTraitsOf<Class, TraitsType>::value, TraitsType, typename DefaultIOTraits<Class>::traitsType>;
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<const TypeTraits&>(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();
}
};
enum VARIABLE_EXPORT_METHOD {
VARIABLE_EXPORT_METHOD_OSTREAM,
VARIABLE_EXPORT_METHOD_STDIO
......@@ -24,7 +60,7 @@ struct VariableExport {
template<typename T>
static auto exportVariable(std::ostream& ost, const T& b)
static auto exportVariable(std::ostream& ost, const T& b, ...)
-> typename std::enable_if<
IsExportable<T>::value &&
!std::is_same<T, bool>::value &&
......@@ -40,7 +76,7 @@ struct VariableExport {
static void exportVariable(std::ostream& ost, const bool& b)
static void exportVariable(std::ostream& ost, const bool& b, ...)
{
ost << (b == true ? "true" : "false");
}
......@@ -59,7 +95,7 @@ struct VariableExport {
template<typename T1, typename T2>
static auto exportVariable(std::ostream& ost, const std::pair<T1,T2>& b)
static auto exportVariable(std::ostream& ost, const std::pair<T1,T2>& b, ...)
-> typename std::enable_if<
!IsTraits<T2>::value
>::type
......@@ -93,7 +129,7 @@ struct VariableExport {
template<typename T>
static auto exportVariable(std::ostream& ost, const T &list)
static auto exportVariable(std::ostream& ost, const T &list, ...)
-> typename std::enable_if<
IsIndexable<T>::value &&
!IsIterable<T>::value &&
......@@ -113,7 +149,7 @@ struct VariableExport {
template<typename T>
static auto exportVariable(std::ostream& ost, const T &list)
static auto exportVariable(std::ostream& ost, const T &list, ...)
-> typename std::enable_if<
IsTNLIndexable<T>::value &&
!IsIndexable<T>::value &&
......@@ -135,7 +171,7 @@ struct VariableExport {
template<typename T>
static void exportVariable(std::ostream& ost, const std::initializer_list<T> &list)
static void exportVariable(std::ostream& ost, const std::initializer_list<T> &list, ...)
{
static auto it = list.begin();
ost << "[ ";
......@@ -157,19 +193,34 @@ struct VariableExport {
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);
}
};
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);
}
};
template<typename T>
static auto exportVariable(std::ostream& ost, const T &traitedClass)
static auto exportVariable(std::ostream& ost, const T &traitedClass, ...)
-> typename std::enable_if<
HasDefaultIOTraits<T>::value
>::type
......@@ -179,8 +230,26 @@ struct VariableExport {
ost << " }";
}
template< typename Class, typename PrimaryTraits, typename ... SecondaryTraits>
static void exportVariable(std::ostream& ost, const TraitsBinder<Class, PrimaryTraits, SecondaryTraits...> &traitedClass)
{
auto traits = SelectTraits<Class, PrimaryTraits, SecondaryTraits...>::getTraitsInstance(traitedClass.tupTraits);
ost << "{ ";
PrintClass<Class, decltype(traits)>::print(ost, traitedClass.object, traits, traitedClass.tupTraits);
ost << " }";
}
template< typename Class, typename PrimaryTraits, typename ... SecondaryTraits, typename std::enable_if<std::is_class<Class>::value, bool>::type = true>
static void exportVariable(std::ostream& ost, const Class &traitedClass, std::tuple<PrimaryTraits, SecondaryTraits...> tupleTraits)
{
auto traits = SelectTraits<Class, PrimaryTraits, SecondaryTraits...>::getTraitsInstance(tupleTraits);
ost << "{ ";
PrintClass<Class, decltype(traits)>::print(ost, traitedClass, traits, tupleTraits);
ost << " }";
}
template<typename T, typename... Refs>
static auto exportVariable(std::ostream& ost, const std::pair<T, Traits<std::decay_t<T>, Refs...>> &traitedClassWithTraits)
static auto exportVariable(std::ostream& ost, const std::pair<T, Traits<std::decay_t<T>, Refs...>> &traitedClassWithTraits, ...)
-> typename std::enable_if<
HasDefaultIOTraits<T>::value
>::type
......
......@@ -135,27 +135,21 @@ public:
void setValue(_typeClass* c, const _typeValue& val) const {
set(c) = val;
set(c, val);
}
void setValue(_typeClass& c, const _typeValue& val) const {
set(c) = val;
}
auto getAttr(_typeClass* c) const {
return set(c);
set(c, val);
}
auto getAttr(_typeClass& c) const {
return set(c);
}
};
template<typename SetFunctor>
struct SetAccess<SetFunctor, std::enable_if_t<!std::is_member_pointer<SetFunctor>::value && function_traits<SetFunctor>::arity == 1, void>>{
struct SetAccess<SetFunctor, std::enable_if_t<!std::is_member_pointer<SetFunctor>::value && function_traits<SetFunctor>::arity == 1, void>>
: public DirectAccess{
using _typeValue = std::decay_t<typename function_traits<SetFunctor>::return_type>;
using _typeClass = std::decay_t<typename function_traits<SetFunctor>::template argument<0>::type>;
......@@ -176,6 +170,15 @@ public:
void setValue(_typeClass& c, const _typeValue& val) const {
set(c) = val;
}
auto getAttr(_typeClass* c) const {
return set(c);
}
auto getAttr(_typeClass& c) const {
return set(c);
}
};
template<typename SetFunctor>
......
......@@ -86,7 +86,7 @@ public:
template <class Class, class GetFunctor, class SetFunctor>
class MemberAccess<Class, std::pair<GetFunctor, SetFunctor>, std::enable_if_t<std::is_bind_expression<GetFunctor>::value> >
: public Impl::GetAccess<GetFunctor, Class>, public Impl::SetAccess<SetFunctor, Class>{
: public Impl::GetAccess<GetFunctor, Class>, public Impl::SetAccess<SetFunctor>{
public:
using typeValue = typename Impl::GetAccess<GetFunctor, Class>::_typeValue;
using typeClass = Class;
......@@ -94,7 +94,7 @@ public:
public:
MemberAccess(std::pair<GetFunctor, SetFunctor> getSet)
: Impl::GetAccess<GetFunctor, Class>(getSet.first), Impl::SetAccess<SetFunctor, Class>(getSet.second)
: Impl::GetAccess<GetFunctor, Class>(getSet.first), Impl::SetAccess<SetFunctor>(getSet.second)
{}
MemberAccess(const MemberAccess<Class, std::pair<GetFunctor, SetFunctor>, std::enable_if_t<std::is_bind_expression<GetFunctor>::value> >&) = default;
......
......@@ -287,7 +287,39 @@ public:
}
};
template<typename,typename >
struct MakeTraitsFromTuple {
};
template<typename TraitedClass, typename ... Refs>
struct MakeTraitsFromTuple<TraitedClass, std::tuple<Refs...>> {
using type = Traits<TraitedClass, Refs...>;
};
template<typename T1, typename A>
struct TupleAppend {};
template<typename T1, typename ... A>
struct TupleAppend<T1, std::tuple<A...>> {
using type = std::tuple<T1, A...>;
};
template<typename odd, typename even, typename ... Refs>
struct SelectEvenTypes {
using type = typename TupleAppend<even, typename SelectEvenTypes<Refs...>::type>::type;
};
template<typename odd, typename even>
struct SelectEvenTypes<odd, even> {
using type = std::tuple<even>;
};
template<typename TraitedClass, typename ... Args>
auto
makeTraits(const Args&... args) {
return typename MakeTraitsFromTuple<TraitedClass, typename SelectEvenTypes<Args...>::type>::type(args...);
}
template<typename Class>
......
#ifndef TRAITSBIND_H
#define TRAITSBIND_H
#include "../Traits.h"
/**
* @brief Non-owning container binding an object to its Traits.
* It is possible to setup more than one Traits in case of
* deeper structure of the object, i.e., it has members with
* another Traits assigned.
*/
template <typename Class, typename PrimaryTraits, typename ... SecondaryTraits>
struct TraitsBinder {
// The object the traits are bound to
Class& object;
// Custom Traits used for description of traited class object
const std::tuple<const PrimaryTraits&, const SecondaryTraits& ...> tupTraits;
// Constructors
TraitsBinder(Class& obj, const PrimaryTraits& primaryTraits, const SecondaryTraits&... secondaryTraits)
: object(obj), tupTraits(primaryTraits, secondaryTraits...)
{}
TraitsBinder(const TraitsBinder<Class, PrimaryTraits, SecondaryTraits...>&) = default;
TraitsBinder(TraitsBinder<Class, PrimaryTraits, SecondaryTraits...>&&) = default;
};
/**
* @brief This function creates an instance of TraitsBinder
* which gathers an instance of a traited class and traits
* to be used to annotate the data members.
*/
template <typename Class, typename PrimaryTraits, typename ... SecondaryTraits>
TraitsBinder<Class, PrimaryTraits, SecondaryTraits ...> bindTraits(Class& obj, const PrimaryTraits& p, const SecondaryTraits& ... s) {
return TraitsBinder<Class, PrimaryTraits, SecondaryTraits ...>(obj, p, s...);
}
#endif // TRAITSBIND_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment