9 #include <density/detail/runtime_type_internals.h> 14 #include <type_traits> 49 using tuple_type = std::tuple<>;
51 template <
typename FIRST_FEATURE,
typename... OTHER_FEATURES>
56 !std::is_void<FIRST_FEATURE>::value,
"[cv-qualified] void does not satisfy TypeFeature");
59 std::is_literal_type<FIRST_FEATURE>::value,
"a TypeFeature must be a literal type");
61 using tuple_type = detail::Tuple_Merge_t<
64 std::tuple<FIRST_FEATURE>,
69 Tuple_Remove_t<
typename feature_list<OTHER_FEATURES...>::tuple_type, FIRST_FEATURE>>;
71 template <
typename... GROUPED_FEATURES,
typename... OTHER_FEATURES>
75 using tuple_type = detail::Tuple_Merge_t<
87 template <
typename... OTHER_FEATURES>
90 using tuple_type =
typename feature_list<OTHER_FEATURES...>::tuple_type;
109 template <
typename TARGET_TYPE> constexpr
static f_size make() noexcept
113 sizeof(TARGET_TYPE) < (std::numeric_limits<uintptr_t>::max)() / 4,
114 "Type with size >= 1/4 of the address space are not supported");
116 return f_size{
sizeof(TARGET_TYPE)};
120 DENSITY_NODISCARD constexpr
size_t operator()() const noexcept {
return m_size; }
123 constexpr
f_size(
size_t i_size) noexcept : m_size(i_size) {}
136 alignof(TARGET_TYPE) < (std::numeric_limits<uintptr_t>::max)() / 4,
137 "Type with alignment >= 1/4 of the address space are not supported");
143 DENSITY_NODISCARD constexpr
size_t operator()() const noexcept {
return m_alignment; }
146 constexpr
f_alignment(
size_t i_alignment) noexcept : m_alignment(i_alignment) {}
147 size_t const m_alignment;
166 void operator()(
void * i_dest)
const { (*m_function)(i_dest); }
169 using Function = void (*)(
void * i_dest);
170 Function
const m_function;
172 template <
typename TARGET_TYPE>
static void invoke(
void * i_dest)
175 new (i_dest) TARGET_TYPE();
199 (*m_function)(i_dest, i_source);
203 using Function = void (*)(
void * i_dest,
const void * i_source);
204 Function
const m_function;
206 template <
typename TARGET_TYPE>
static void invoke(
void * i_dest,
const void * i_source)
210 const TARGET_TYPE & source = *
static_cast<const TARGET_TYPE *
>(i_source);
211 new (i_dest) TARGET_TYPE(source);
233 void operator()(
void * i_dest,
void * i_source)
const { (*m_function)(i_dest, i_source); }
236 using Function = void (*)(
void * i_dest,
void * i_source);
237 Function
const m_function;
239 template <
typename TARGET_TYPE>
static void invoke(
void * i_dest,
void * i_source)
243 TARGET_TYPE & source = *
static_cast<TARGET_TYPE *
>(i_source);
244 new (i_dest) TARGET_TYPE(std::move(source));
268 (*m_function)(i_dest, i_source);
272 using Function = void (*)(
void * i_dest,
const void * i_source);
273 Function
const m_function;
274 constexpr
f_copy_assign(Function i_function) : m_function(i_function) {}
275 template <
typename TARGET_TYPE>
static void invoke(
void * i_dest,
const void * i_source)
279 const TARGET_TYPE & source = *
static_cast<const TARGET_TYPE *
>(i_source);
280 TARGET_TYPE & dest = *
static_cast<TARGET_TYPE *
>(i_dest);
303 void operator()(
void * i_dest,
void * i_source)
const { (*m_function)(i_dest, i_source); }
306 using Function = void (*)(
void * i_dest,
void * i_source);
307 Function
const m_function;
308 constexpr
f_move_assign(Function i_function) : m_function(i_function) {}
309 template <
typename TARGET_TYPE>
static void invoke(
void * i_dest,
void * i_source)
313 const TARGET_TYPE & source = *
static_cast<TARGET_TYPE *
>(i_source);
314 TARGET_TYPE & dest = *
static_cast<TARGET_TYPE *
>(i_dest);
315 dest = std::move(source);
335 void operator()(
void * i_object)
const noexcept {
return (*m_function)(i_object); }
338 using Function = void (*)(
void * i_dest) DENSITY_CPP17_NOEXCEPT;
339 Function
const m_function;
340 constexpr
f_destroy(Function i_function) : m_function(i_function) {}
341 template <
typename TARGET_TYPE>
static void invoke(
void * i_object) noexcept
344 TARGET_TYPE * obj =
static_cast<TARGET_TYPE *
>(i_object);
346 noexcept(obj->TARGET_TYPE::~TARGET_TYPE()),
347 "TARGET_TYPE must be nothrow destructible");
348 obj->TARGET_TYPE::~TARGET_TYPE();
358 template <
typename TARGET_TYPE> constexpr
static f_equal make() noexcept
360 return f_equal{&invoke<TARGET_TYPE>};
370 bool operator()(
void const * i_first,
void const * i_second)
const noexcept
372 return (*m_function)(i_first, i_second);
376 using Function = bool (*)(
void const * i_first,
void const * i_second)
377 DENSITY_CPP17_NOEXCEPT;
378 Function
const m_function;
379 constexpr
f_equal(Function i_function) : m_function(i_function) {}
380 template <
typename TARGET_TYPE>
381 static bool invoke(
void const * i_first,
void const * i_second) noexcept
385 auto const & first = *
static_cast<TARGET_TYPE
const *
>(i_first);
386 auto const & second = *
static_cast<TARGET_TYPE
const *
>(i_second);
387 bool const result = first == second;
398 template <
typename TARGET_TYPE> constexpr
static f_less make() noexcept
400 return f_less{&invoke<TARGET_TYPE>};
410 bool operator()(
void const * i_first,
void const * i_second)
const 412 return (*m_function)(i_first, i_second);
416 using Function = bool (*)(
void const * i_first,
void const * i_second)
417 DENSITY_CPP17_NOEXCEPT;
418 Function
const m_function;
419 constexpr
f_less(Function i_function) : m_function(i_function) {}
420 template <
typename TARGET_TYPE>
421 static bool invoke(
void const * i_first,
void const * i_second) noexcept
425 auto const & first = *
static_cast<TARGET_TYPE
const *
>(i_first);
426 auto const & second = *
static_cast<TARGET_TYPE
const *
>(i_second);
427 bool const result = first < second;
439 template <
typename TARGET_TYPE> constexpr
static f_hash make() noexcept
441 return f_hash{&invoke<TARGET_TYPE>};
448 DENSITY_NODISCARD
size_t operator()(
const void * i_source)
const noexcept
450 return (*m_function)(i_source);
454 using Function = size_t (*)(
const void * i_source) DENSITY_CPP17_NOEXCEPT;
455 Function
const m_function;
456 constexpr
f_hash(Function i_function) noexcept : m_function(i_function) {}
457 template <
typename TARGET_TYPE>
static size_t invoke(
const void * i_source) noexcept
461 noexcept(std::hash<TARGET_TYPE>()(*static_cast<const TARGET_TYPE *>(i_source))),
462 "Specializations of std::hash must be nothrow constructible and invokable");
463 return std::hash<TARGET_TYPE>()(*static_cast<const TARGET_TYPE *>(i_source));
472 template <
typename TARGET_TYPE> constexpr
static f_rtti make() noexcept
474 return f_rtti{&invoke<TARGET_TYPE>};
478 DENSITY_NODISCARD std::type_info
const &
operator()() const noexcept
480 return (*m_function)();
484 using Function = std::type_info
const & (*)() DENSITY_CPP17_NOEXCEPT;
485 Function
const m_function;
486 constexpr
f_rtti(Function i_function) noexcept : m_function(i_function) {}
487 template <
typename TARGET_TYPE>
static const std::type_info & invoke() noexcept
489 return typeid(TARGET_TYPE);
509 template <
typename FEATURE_LIST,
typename... TARGET_FEATURES>
struct has_features;
510 template <
typename FEATURE_LIST>
511 struct has_features<FEATURE_LIST> : std::integral_constant<bool, true>
514 template <
typename FEATURE_LIST,
typename FIRST_FEATURE,
typename... OTHER_FEATURES>
515 struct has_features<FEATURE_LIST, FIRST_FEATURE, OTHER_FEATURES...>
516 : std::integral_constant<
519 (detail::Tuple_FindFirst<typename FEATURE_LIST::tuple_type, FIRST_FEATURE>::index <
520 std::tuple_size<typename FEATURE_LIST::tuple_type>::value) &&
521 has_features<FEATURE_LIST, OTHER_FEATURES...>::value
665 template <typename... FEATURES> class runtime_type
669 using feature_list_type = typename std::conditional<
670 (sizeof...(FEATURES) > 0),
671 feature_list<FEATURES...>,
672 default_type_features>::type;
688 template <typename TARGET_TYPE> constexpr static
runtime_type make() noexcept
691 &detail::FeatureTable<
tuple_type,
typename std::decay<TARGET_TYPE>::type>::s_table);
711 template <
typename... OTHER_FEATURES>
714 #ifndef DOXYGEN_DOC_GENERATION
716 typename std::enable_if<
723 : m_feature_table(i_source.m_feature_table)
738 template <
typename... OTHER_FEATURES>
739 DENSITY_CPP14_CONSTEXPR
740 #ifndef DOXYGEN_DOC_GENERATION 741 typename std::enable_if<
751 m_feature_table = i_source.m_feature_table;
762 std::swap(i_first.m_feature_table, i_second.m_feature_table);
768 constexpr
bool empty() const noexcept {
return m_feature_table ==
nullptr; }
776 DENSITY_CPP14_CONSTEXPR
void clear() noexcept { m_feature_table =
nullptr; }
798 constexpr
size_t size() const noexcept {
return get_feature<f_size>()(); }
820 constexpr
size_t alignment() const noexcept {
return get_feature<f_alignment>()(); }
852 get_feature<f_default_construct>()(i_dest);
884 get_feature<f_copy_construct>()(i_dest, i_source);
917 get_feature<f_move_construct>()(i_dest, i_source);
945 get_feature<f_destroy>()(i_dest);
969 return get_feature<f_rtti>()();
994 bool are_equal(
const void * i_first,
const void * i_second)
const noexcept
996 DENSITY_ASSERT(i_first !=
nullptr && i_second !=
nullptr && !empty());
997 return get_feature<f_equal>()(i_first, i_second);
1011 template <
typename FEATURE>
const FEATURE & get_feature()
const noexcept
1014 return std::get<detail::Tuple_FindFirst<tuple_type, FEATURE>::index>(*m_feature_table);
1022 return m_feature_table == i_other.m_feature_table;
1030 return m_feature_table != i_other.m_feature_table;
1039 template <
typename TARGET_TYPE> constexpr
bool is() const noexcept
1041 return m_feature_table ==
1042 &detail::FeatureTable<tuple_type, typename std::decay<TARGET_TYPE>::type>::
1048 : m_feature_table(i_feature_table)
1053 #ifndef DOXYGEN_DOC_GENERATION 1057 const tuple_type * m_feature_table =
nullptr;
1065 template <
typename... FEATURES>
struct hash<
density::runtime_type<FEATURES...>>
1069 return std::hash<const void *>()(i_runtime_type.m_feature_table);
Definition: runtime_type.h:354
DENSITY_NODISCARD constexpr size_t operator()() const noexcept
Definition: runtime_type.h:120
static constexpr f_rtti make() noexcept
Definition: runtime_type.h:472
DENSITY_NODISCARD std::type_info const & operator()() const noexcept
Definition: runtime_type.h:478
Definition: conc_function_queue.h:11
Definition: runtime_type.h:665
static constexpr f_copy_construct make() noexcept
Definition: runtime_type.h:185
DENSITY_NODISCARD size_t operator()(const void *i_source) const noexcept
Definition: runtime_type.h:448
void operator()(void *i_dest, const void *i_source) const
Definition: runtime_type.h:197
static constexpr f_alignment make() noexcept
Definition: runtime_type.h:132
void default_construct(void *i_dest) const
Definition: runtime_type.h:849
Definition: runtime_type.h:1061
static constexpr f_move_assign make() noexcept
Definition: runtime_type.h:291
static constexpr f_default_construct make() noexcept
Definition: runtime_type.h:157
const std::type_info & type_info() const noexcept
Definition: runtime_type.h:966
Definition: runtime_type.h:394
constexpr size_t size() const noexcept
Definition: runtime_type.h:798
static constexpr f_destroy make() noexcept
Definition: runtime_type.h:325
DENSITY_NODISCARD constexpr size_t operator()() const noexcept
Definition: runtime_type.h:143
#define DENSITY_ASSERT(...)
Definition: density_config.h:19
void operator()(void *i_object) const noexcept
Definition: runtime_type.h:335
static constexpr f_copy_assign make() noexcept
Definition: runtime_type.h:254
void move_construct(void *i_dest, void *i_source) const
Definition: runtime_type.h:914
Definition: runtime_type.h:153
Definition: runtime_type.h:181
void operator()(void *i_dest, void *i_source) const
Definition: runtime_type.h:233
friend void swap(runtime_type &i_first, runtime_type &i_second) noexcept
Definition: runtime_type.h:760
Definition: runtime_type.h:128
bool operator()(void const *i_first, void const *i_second) const noexcept
Definition: runtime_type.h:370
void operator()(void *i_dest, void *i_source) const
Definition: runtime_type.h:303
constexpr bool is() const noexcept
Definition: runtime_type.h:1039
bool operator()(void const *i_first, void const *i_second) const
Definition: runtime_type.h:410
static constexpr f_hash make() noexcept
Definition: runtime_type.h:439
DENSITY_CPP14_CONSTEXPR void clear() noexcept
Definition: runtime_type.h:776
static constexpr f_less make() noexcept
Definition: runtime_type.h:398
Definition: runtime_type.h:468
constexpr bool operator!=(const runtime_type &i_other) const noexcept
Definition: runtime_type.h:1028
constexpr bool empty() const noexcept
Definition: runtime_type.h:768
Definition: runtime_type.h:321
void operator()(void *i_dest) const
Definition: runtime_type.h:166
void destroy(void *i_dest) const noexcept
Definition: runtime_type.h:942
static constexpr f_size make() noexcept
Definition: runtime_type.h:109
Definition: runtime_type.h:250
DENSITY_CPP14_CONSTEXPR runtime_type & operator=(const runtime_type< OTHER_FEATURES... > &i_source) noexcept
Definition: runtime_type.h:749
Definition: runtime_type.h:46
bool are_equal(const void *i_first, const void *i_second) const noexcept
Definition: runtime_type.h:994
typename feature_list_type::tuple_type tuple_type
Definition: runtime_type.h:679
Definition: runtime_type.h:217
static constexpr f_move_construct make() noexcept
Definition: runtime_type.h:221
Definition: runtime_type.h:287
Definition: runtime_type.h:435
constexpr runtime_type(const runtime_type< OTHER_FEATURES... > &i_source) noexcept
Definition: runtime_type.h:712
Definition: runtime_type.h:105
Definition: runtime_type.h:509
#define DENSITY_ASSUME(bool_expr,...)
Definition: density_config.h:46
static constexpr f_equal make() noexcept
Definition: runtime_type.h:358
Definition: runtime_type.h:100
constexpr bool operator==(const runtime_type &i_other) const noexcept
Definition: runtime_type.h:1020
void copy_construct(void *i_dest, const void *i_source) const
Definition: runtime_type.h:881
constexpr size_t alignment() const noexcept
Definition: runtime_type.h:820
void operator()(void *i_dest, const void *i_source) const
Definition: runtime_type.h:266