pupene  0.2.0
traits.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <string>
4 
5 namespace pupene {
6  /** Holds name and type of objects. */
7  struct Meta {
8  enum class Type {
9  Array = 1, Object, Value
10  };
11 
12  Meta() : Meta("") {}
13  Meta(const char* name, Type type = Type::Value)
14  : name(name), type(type) {}
15  ~Meta() = default;
16 
17  /** The name typically matches the name of the represented field. */
18  const char* name;
19  const Type type = Type::Value;
20  };
21 
22  // https://blog.tartanllama.xyz/detection-idiom/
23  // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4502.pdf
24  template <template<typename...> typename Trait, typename Enabler, typename... Args>
25  struct is_detected
26  : std::false_type {};
27 
28  template <template<typename...> typename Trait, typename... Args>
29  struct is_detected<Trait, std::void_t<Trait<Args...>>, Args...>
30  : std::true_type {};
31 
32  namespace detect {
33  using std::void_t;
34  using std::declval;
35 
36  template<typename T>
37  using begin_member = decltype(declval<T>().begin());
38  template<typename T>
39  using has_begin = is_detected<begin_member, void, T>;
40 
41  template<typename T>
42  using end_member = decltype(declval<T>().end());
43  template<typename T>
44  using has_end = is_detected<end_member, void, T>;
45 
46  template<typename T>
47  using resize_member = decltype(declval<T>().resize(declval<uint32_t>()));
48  template<typename T>
49  using has_resize = is_detected<resize_member, void, T>;
50 
51  template<typename T>
52  using size_member = decltype(declval<T>().size());
53  template<typename T>
54  using has_size = is_detected<size_member, void, T>;
55 
56  template <typename T, typename = void_t<>>
57  struct is_map_impl : std::false_type {};
58 
59  template <typename T>
60  struct is_map_impl<T, std::void_t<
61  typename T::key_type,
62  typename T::mapped_type>>
63  : std::true_type {};
64 
65  template<typename P, typename T, typename = std::void_t<>>
66  struct is_pup_impl
67  : std::false_type {};
68 
69  template<typename P, typename T>
70  struct is_pup_impl<P, T, void_t<
71  decltype(declval<P>().pup_impl(declval<T&>(), declval<const Meta&>()))>>
72  : std::true_type {};
73  }
74 
75  template <typename T>
76  constexpr bool is_map() {
77  return detect::is_map_impl<T>::value;
78  }
79 
80  template<typename T>
81  constexpr bool is_pup_iterable() {
82  return detect::has_begin<T>::value
83  && detect::has_end<T>::value
84  && detect::has_resize<T>::value
85  && detect::has_size<T>::value;
86  }
87 
88  template<typename T>
89  constexpr bool is_pup_container() {
90  return is_pup_iterable<T>()
91  && !std::is_same<std::string, T>::value;
92  }
93 
94  template<typename P, typename T>
95  constexpr bool is_pup_impl() {
96  return detect::is_pup_impl<P, T>{};
97  }
98 
99  template<typename T>
100  constexpr bool is_puppable() {
101  return std::is_integral<T>()
102  || std::is_floating_point<T>()
103  || std::is_same<std::string, T>();
104  }
105 
106  template <typename T>
107  using enable_if_pup_iterable = typename std::enable_if_t<is_pup_iterable<T>()>;
108 
109  template <typename T>
110  using enable_if_puppable_container = typename std::enable_if_t<is_pup_container<T>()>;
111 
112  template<typename T>
113  using enable_if_puppable = typename std::enable_if_t<is_puppable<T>()>;
114 
115  template<typename T>
116  using enable_if_not_puppable = typename std::enable_if_t<!is_puppable<T>()>;
117 
118  template<typename T>
119  using enable_if_puppable_map = typename std::enable_if_t<is_map<T>()>;
120 }
constexpr bool is_map()
Definition: traits.h:76
constexpr bool is_pup_iterable()
Definition: traits.h:81
Definition: debug.cpp:4
const char * name
The name typically matches the name of the represented field.
Definition: traits.h:18
constexpr bool is_puppable()
Definition: traits.h:100
Holds name and type of objects.
Definition: traits.h:7
constexpr bool is_pup_container()
Definition: traits.h:89
Meta(const char *name, Type type=Type::Value)
Definition: traits.h:13
~Meta()=default
constexpr bool is_pup_impl()
Definition: traits.h:95
const Type type
Definition: traits.h:19