siplasplas
A library for C++ reflection and introspection
typeinfo.hpp
1 #ifndef SIPLASPLAS_TYPEERASURE_TYPEINFO_HPP
2 #define SIPLASPLAS_TYPEERASURE_TYPEINFO_HPP
3 
4 #include "features/valuesemantics.hpp"
5 #include <siplasplas/utility/memory_manip.hpp>
6 #include <siplasplas/utility/meta.hpp>
7 #include <siplasplas/utility/function_traits.hpp>
8 #include <siplasplas/utility/typeinfo.hpp>
9 
10 namespace cpp
11 {
12 
13 namespace typeerasure
14 {
15 
16 namespace detail
17 {
18 
23 enum class ValueSemanticsOperation : std::size_t
24 {
25  DEFAULT_CONSTRUCT = 0,
26  COPY_CONSTRUCT = 1,
27  MOVE_CONSTRUCT = 2,
28  COPY_ASSIGN = 3,
29  MOVE_ASSIGN = 4,
30  DESTROY = 5
31 };
32 
33 using ValueSemanticsOperationFunction = void(*)(void*, const void*);
34 
56 template<typename T>
57 ValueSemanticsOperationFunction valueSemanticsOperation(ValueSemanticsOperation operation)
58 {
59  static ValueSemanticsOperationFunction operations[] = {
60  +[](void* object, const void*) {
61  features::DefaultConstructible::apply<T>(object);
62  },
63  +[](void* object, const void* other) {
64  features::CopyConstructible::apply<T>(object, other);
65  },
66  +[](void* object, const void* other) {
67  features::MoveConstructible::apply<T>(object, const_cast<void*>(other));
68  },
69  +[](void* object, const void* other) {
70  features::CopyAssignable::apply<T>(object, other);
71  },
72  +[](void* object, const void* other) {
73  features::MoveAssignable::apply<T>(object, const_cast<void*>(other));
74  },
75  +[](void* object, const void*) {
76  features::Destructible::apply<T>(object);
77  }
78  };
79 
80  return operations[static_cast<std::size_t>(operation)];
81 }
82 
83 using ValueSemantics = decltype(&valueSemanticsOperation<int>);
84 
85 }
86 
113 class TypeInfo : public cpp::TypeInfo
114 {
115 public:
119  detail::ValueSemantics semantics() const
120  {
121  return _semantics;
122  }
123 
127  bool isPointer() const
128  {
129  return _isPointer;
130  }
131 
136  detail::ValueSemanticsOperationFunction semantics(detail::ValueSemanticsOperation operation) const
137  {
138  return semantics()(operation);
139  }
140 
147  void defaultConstruct(void* where) const
148  {
149  semantics(detail::ValueSemanticsOperation::DEFAULT_CONSTRUCT)(where, nullptr);
150  }
151 
159  void copyConstruct(void* where, const void* other) const
160  {
161  semantics(detail::ValueSemanticsOperation::COPY_CONSTRUCT)(where, other);
162  }
163 
172  void moveConstruct(void* where, void* other) const
173  {
174  semantics(detail::ValueSemanticsOperation::MOVE_CONSTRUCT)(where, const_cast<const void*>(other));
175  }
176 
184  void copyAssign(void* where, const void* other) const
185  {
186  semantics(detail::ValueSemanticsOperation::COPY_ASSIGN)(where, other);
187  }
188 
197  void moveAssign(void* where, void* other) const
198  {
199  semantics(detail::ValueSemanticsOperation::MOVE_ASSIGN)(where, const_cast<const void*>(other));
200  }
201 
208  void destroy(void* where) const
209  {
210  if(!isPointer())
211  {
212  semantics(detail::ValueSemanticsOperation::DESTROY)(where, nullptr);
213  }
214  }
215 
219  template<typename T>
220  static constexpr TypeInfo get()
221  {
222  return TypeInfo{meta::identity<T>()};
223  }
224 
225  friend constexpr bool operator==(const TypeInfo& lhs, const TypeInfo& rhs)
226  {
227  return lhs._semantics == rhs._semantics;
228  }
229 
230  friend constexpr bool operator!=(const TypeInfo& lhs, const TypeInfo& rhs)
231  {
232  return !(lhs == rhs);
233  }
234 
235 private:
236  template<typename T>
237  constexpr TypeInfo(meta::identity<T>) :
238  cpp::TypeInfo{cpp::TypeInfo::get<T>()},
239  _semantics{detail::valueSemanticsOperation<T>},
240  _isPointer{
241  std::is_pointer<T>::value &&
242  cpp::function_kind<T>() != cpp::FunctionKind::FREE_FUNCTION
243  }
244  {
245  static_assert(alignof(T) < (1 << 16), "Alignment of T cannot be tagged in a pointer, its value overflows a 16 bit unsigned integer");
246  }
247 
248  detail::ValueSemantics _semantics;
249  bool _isPointer;
250 };
251 
252 }
253 
254 }
255 
256 #endif // SIPLASPLAS_TYPEERASURE_TYPEINFO_HPP
ValueSemanticsOperation
Represents a value semantics operation. See valueSemanticsOperation()
Definition: typeinfo.hpp:23
void defaultConstruct(void *where) const
Default constructs a value of the type If the passed argument is not of the represented type...
Definition: typeinfo.hpp:147
void moveConstruct(void *where, void *other) const
Move constructs values of the type If the passed arguments are not of the represented type...
Definition: typeinfo.hpp:172
Definition: canary_allocator.hpp:7
detail::ValueSemanticsOperationFunction semantics(detail::ValueSemanticsOperation operation) const
Returns the function implementing the given valuesemantics operation for the type.
Definition: typeinfo.hpp:136
ValueSemanticsOperationFunction valueSemanticsOperation(ValueSemanticsOperation operation)
Implements a type-erased interface for the value semantics features of a type T.
Definition: typeinfo.hpp:57
detail::ValueSemantics semantics() const
Retuns the type-erased semantics of the type. See valueSemantics().
Definition: typeinfo.hpp:119
void copyConstruct(void *where, const void *other) const
Copy constructs values of the type If the passed arguments are not of the represented type...
Definition: typeinfo.hpp:159
void destroy(void *where) const
Destroys objects of the type If the passed arguments are not of the represented type, the behavior is undefined.
Definition: typeinfo.hpp:208
void copyAssign(void *where, const void *other) const
Move assigns values of the type If the passed arguments are not of the represented type...
Definition: typeinfo.hpp:184
bool isPointer() const
Checks if the type is a pointer type.
Definition: typeinfo.hpp:127
void moveAssign(void *where, void *other) const
Move assigns values of the type If the passed arguments are not of the represented type...
Definition: typeinfo.hpp:197
Contains minimal information to execute the value semantics operations of a type. ...
Definition: typeinfo.hpp:113