siplasplas
typeinfo.hpp
1 #ifndef SIPLASPLAS_UTILITY_TYPEINFO_HPP
2 #define SIPLASPLAS_UTILITY_TYPEINFO_HPP
3 
4 #include "function_traits.hpp"
5 #include <ctti/type_id.hpp>
6 #include <bitset>
7 #include <cstdint>
8 #include <climits>
9 #include <type_traits>
10 
11 namespace cpp
12 {
13 class TypeInfo
14 {
15 public:
16  enum class TypeTraitIndex : std::size_t
17  {
18  // Primary type categories:
19  is_void,
20  is_null_pointer,
21  is_integral,
22  is_floating_point,
23  is_array,
24  is_enum,
25  is_union,
26  is_class,
27  is_function,
28  is_pointer,
29  is_lvalue_reference,
30  is_rvalue_reference,
31  is_member_object_pointer,
32  is_member_function_pointer,
33 
34  // Composite type categories:
35  is_fundamental,
36  is_arithmetic,
37  is_scalar,
38  is_object,
39  is_compound,
40  is_reference,
41  is_member_pointer,
42 
43  // Type properties:
44  is_const,
45  is_volatile,
46  is_trivial,
47  is_trivially_copyable,
48  is_standard_layout,
49  is_pod,
50  is_literal_type,
51  is_empty,
52  is_polymorphic,
53  is_abstract,
54  is_signed,
55  is_unsigned,
56  is_default_constructible,
57  is_copy_constructible,
58  is_move_constructible,
59  is_copy_assignable,
60  is_move_assignable,
61  is_destructible,
62  is_trivially_default_constructible,
63  is_trivially_copy_constructible,
64  is_trivially_move_constructible,
65  is_trivially_copy_assignable,
66  is_trivially_move_assignable,
67  is_trivially_destructible,
68  is_nothrow_default_constructible,
69  is_nothrow_copy_constructible,
70  is_nothrow_move_constructible,
71  is_nothrow_copy_assignable,
72  is_nothrow_move_assignable,
73  is_nothrow_destructible,
74  has_virtual_destructor,
75  ALWAYS_AT_END_PLEASE__ACTUALLY_NOT_A_TRAIT_INDEX
76  };
77 
78  using BitsetValue = std::uint64_t;
79 
80  static_assert(
81  static_cast<std::size_t>(TypeTraitIndex::ALWAYS_AT_END_PLEASE__ACTUALLY_NOT_A_TRAIT_INDEX) <= sizeof(BitsetValue)*CHAR_BIT,
82  "BitsetValue has no enough bits to store all type traits"
83  );
84 
85  using TypeTraits = std::bitset<static_cast<std::size_t>(TypeTraitIndex::ALWAYS_AT_END_PLEASE__ACTUALLY_NOT_A_TRAIT_INDEX)>;
86 
87  template<typename T>
88  static constexpr TypeInfo get()
89  {
90 #define BITSET_TRAIT(trait) (static_cast<std::uint64_t>(std::trait<T>::value) << static_cast<std::size_t>(TypeTraitIndex::trait))
91  return{
92  ctti::type_id<T>(),
93  sizeof(T),
94  alignof(T),
95  cpp::function_kind<T>(),
96  BitsetValue{
97  BITSET_TRAIT(is_void) |
98  BITSET_TRAIT(is_null_pointer) |
99  BITSET_TRAIT(is_integral) |
100  BITSET_TRAIT(is_floating_point) |
101  BITSET_TRAIT(is_array) |
102  BITSET_TRAIT(is_enum) |
103  BITSET_TRAIT(is_union) |
104  BITSET_TRAIT(is_class) |
105  BITSET_TRAIT(is_function) |
106  BITSET_TRAIT(is_pointer) |
107  BITSET_TRAIT(is_lvalue_reference) |
108  BITSET_TRAIT(is_rvalue_reference) |
109  BITSET_TRAIT(is_member_object_pointer) |
110  BITSET_TRAIT(is_member_function_pointer) |
111  BITSET_TRAIT(is_fundamental) |
112  BITSET_TRAIT(is_arithmetic) |
113  BITSET_TRAIT(is_scalar) |
114  BITSET_TRAIT(is_object) |
115  BITSET_TRAIT(is_compound) |
116  BITSET_TRAIT(is_reference) |
117  BITSET_TRAIT(is_member_pointer) |
118  BITSET_TRAIT(is_const) |
119  BITSET_TRAIT(is_volatile) |
120  BITSET_TRAIT(is_trivial) |
121  BITSET_TRAIT(is_trivially_copyable) |
122  BITSET_TRAIT(is_standard_layout) |
123  BITSET_TRAIT(is_pod) |
124  BITSET_TRAIT(is_literal_type) |
125  BITSET_TRAIT(is_empty) |
126  BITSET_TRAIT(is_polymorphic) |
127  BITSET_TRAIT(is_abstract) |
128  BITSET_TRAIT(is_signed) |
129  BITSET_TRAIT(is_unsigned) |
130  BITSET_TRAIT(is_default_constructible) |
131  BITSET_TRAIT(is_copy_constructible) |
132  BITSET_TRAIT(is_move_constructible) |
133  BITSET_TRAIT(is_copy_assignable) |
134  BITSET_TRAIT(is_move_assignable) |
135  BITSET_TRAIT(is_destructible) |
136  BITSET_TRAIT(is_trivially_default_constructible) |
137  BITSET_TRAIT(is_trivially_copy_constructible) |
138  BITSET_TRAIT(is_trivially_move_constructible) |
139  BITSET_TRAIT(is_trivially_copy_assignable) |
140  BITSET_TRAIT(is_trivially_move_assignable) |
141  BITSET_TRAIT(is_trivially_destructible) |
142  BITSET_TRAIT(is_nothrow_default_constructible) |
143  BITSET_TRAIT(is_nothrow_copy_constructible) |
144  BITSET_TRAIT(is_nothrow_move_constructible) |
145  BITSET_TRAIT(is_nothrow_copy_assignable) |
146  BITSET_TRAIT(is_nothrow_move_assignable) |
147  BITSET_TRAIT(is_nothrow_destructible) |
148  BITSET_TRAIT(has_virtual_destructor)
149  }
150  };
151 #undef BITSET_TRAIT
152  }
153 
154  constexpr bool operator()(const TypeTraitIndex typeTrait) const
155  {
156  return _typeTraits[static_cast<std::size_t>(typeTrait)];
157  }
158 
159  constexpr ctti::detail::cstring name() const
160  {
161  return _typeId.name();
162  }
163 
164  constexpr ctti::detail::cstring typeName() const
165  {
166  return name();
167  }
168 
169  constexpr const ctti::type_id_t& type_id() const
170  {
171  return _typeId;
172  }
173 
174  constexpr std::size_t sizeOf() const
175  {
176  return _sizeOf;
177  }
178 
179  constexpr std::size_t alignment() const
180  {
181  return _alignment;
182  }
183 
184  constexpr cpp::FunctionKind kind() const
185  {
186  return _kind;
187  }
188 
189  constexpr bool isPointer() const
190  {
191  return (*this)(TypeTraitIndex::is_pointer) &&
192  kind() != cpp::FunctionKind::FREE_FUNCTION;
193  }
194 
195  friend constexpr bool operator==(const TypeInfo& lhs, const TypeInfo& rhs)
196  {
197  return lhs.type_id() == rhs.type_id();
198  }
199 
200  friend constexpr bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs)
201  {
202  return !(lhs == rhs);
203  }
204 
205 private:
206  ctti::type_id_t _typeId;
207  std::size_t _sizeOf;
208  std::size_t _alignment;
209  cpp::FunctionKind _kind;
210  TypeTraits _typeTraits;
211 
212  constexpr TypeInfo(const ctti::type_id_t& typeId,
213  const std::size_t sizeOf,
214  const std::size_t alignment,
215  const cpp::FunctionKind kind,
216  const BitsetValue typeTraits) :
217  _typeId{ typeId },
218  _sizeOf{sizeOf},
219  _alignment{ alignment },
220  _kind{kind},
221  _typeTraits{ typeTraits }
222  {}
223 };
224 
225 using TypeTrait = TypeInfo::TypeTraitIndex;
226 }
227 
228 #endif // SIPLASPLAS_UTILITY_TYPEINFO_HPP
Definition: messaging.hpp:8
Definition: typeinfo.hpp:13