1 #ifndef ENTT_CORE_IDENT_HPP
2 #define ENTT_CORE_IDENT_HPP
3 
4 
5 #include <cstddef>
6 #include <utility>
7 #include <type_traits>
8 #include "../config/config.h"
9 #include "fwd.hpp"
10 #include "type_traits.hpp"
11 
12 
13 namespace entt {
14 
15 
16 /**
17  * @brief Types identifiers.
18  *
19  * Variable template used to generate identifiers at compile-time for the given
20  * types. Use the `get` member function to know what's the identifier associated
21  * to the specific type.
22  *
23  * @note
24  * Identifiers are constant expression and can be used in any context where such
25  * an expression is required. As an example:
26  * @code{.cpp}
27  * using id = entt::identifier<a_type, another_type>;
28  *
29  * switch(a_type_identifier) {
30  * case id::type<a_type>:
31  *     // ...
32  *     break;
33  * case id::type<another_type>:
34  *     // ...
35  *     break;
36  * default:
37  *     // ...
38  * }
39  * @endcode
40  *
41  * @tparam Types List of types for which to generate identifiers.
42  */
43 template<typename... Types>
44 class identifier {
45     template<typename Type, std::size_t... Index>
get(std::index_sequence<Index...>)46     [[nodiscard]] static constexpr id_type get(std::index_sequence<Index...>) {
47         static_assert(std::disjunction_v<std::is_same<Type, Types>...>, "Invalid type");
48         return (0 + ... + (std::is_same_v<Type, type_list_element_t<Index, type_list<std::decay_t<Types>...>>> ? id_type{Index} : id_type{}));
49     }
50 
51 public:
52     /*! @brief Unsigned integer type. */
53     using identifier_type = id_type;
54 
55     /*! @brief Statically generated unique identifier for the given type. */
56     template<typename Type>
57     static constexpr identifier_type type = get<std::decay_t<Type>>(std::index_sequence_for<Types...>{});
58 };
59 
60 
61 }
62 
63 
64 #endif
65