Skip to content
Flecs v4.1
pair.hpp
Go to the documentation of this file.
1/**
2 * @file addons/cpp/pair.hpp
3 * @brief Utilities for working with compile-time pairs.
4 */
5
6#pragma once
7
8namespace flecs {
9
10namespace _ {
11 struct pair_base { };
12} // namespace _
13
14
15/**
16 * @defgroup cpp_pair_type Pair type
17 * @ingroup cpp_core
18 * Compile-time utilities for working with relationship pairs.
19 *
20 * @{
21 */
22
23/** Type that represents a pair.
24 * The pair type can be used to represent a pair at compile time and is able
25 * to automatically derive the storage type associated with the pair, accessible
26 * through pair::type.
27 *
28 * The storage type is derived using the following rules:
29 * - if pair::first is non-empty, the storage type is pair::first
30 * - if pair::first is empty and pair::second is non-empty, the storage type is pair::second
31 *
32 * The pair type can hold a temporary value so that it can be used in the
33 * signatures of queries.
34 */
35template <typename First, typename Second>
37 using type = conditional_t<!is_empty<First>::value || is_empty<Second>::value, First, Second>; /**< The storage type of the pair. */
38 using first = First; /**< The first element type of the pair. */
39 using second = Second; /**< The second element type of the pair. */
40
41 /** Construct pair from a mutable reference to the storage type.
42 *
43 * @param v Reference to the value.
44 */
45 pair(type& v) : ref_(v) { }
46
47 /** Construct pair from a const reference to the storage type.
48 * This allows the class to be used as a temporary object.
49 *
50 * @param v Const reference to the value.
51 */
52 pair(const type& v) : ref_(const_cast<type&>(v)) { }
53
54 /** Conversion to mutable reference of the storage type. */
55 operator type&() {
56 return ref_;
57 }
58
59 /** Conversion to const reference of the storage type. */
60 operator const type&() const {
61 return ref_;
62 }
63
64 /** Arrow operator for mutable access. */
66 return &ref_;
67 }
68
69 /** Arrow operator for const access. */
70 const type* operator->() const {
71 return &ref_;
72 }
73
74 /** Dereference operator for mutable access. */
76 return ref_;
77 }
78
79 /** Dereference operator for const access. */
80 const type& operator*() const {
81 return ref_;
82 }
83
84private:
85 type& ref_;
86};
87
88/** Alias for pair when First is empty (tag). */
89template <typename First, typename Second, if_t<is_empty<First>::value> = 0>
91
92/** Get the raw type by removing pointer and reference qualifiers. */
93template <typename T>
94using raw_type_t = remove_pointer_t<remove_reference_t<T>>;
95
96/** Test if a type is a pair. */
97template <typename T>
98struct is_pair {
99 static constexpr bool value = is_base_of_v<_::pair_base, raw_type_t<T>>;
100};
101
102/** Convenience variable template to check if a type is a pair. */
103template <typename T>
104inline constexpr bool is_pair_v = is_pair<T>::value;
105
106/** Get pair::first from a pair while preserving cv qualifiers. */
107template <typename P>
109
110/** Get pair::second from a pair while preserving cv qualifiers. */
111template <typename P>
113
114/** Get the pair::type type from a pair while preserving cv qualifiers and pointer type. */
115template <typename P>
117
118/** Get the actual type from a regular type or pair. */
119template <typename T, typename U = int>
121
122template <typename T>
123struct actual_type<T, if_not_t< is_pair<T>::value >> {
124 using type = T;
125};
126
127template <typename T>
128struct actual_type<T, if_t< is_pair<T>::value >> {
129 using type = pair_type_t<T>;
130};
131
132template <typename T>
133using actual_type_t = typename actual_type<T>::type;
134
135
136/** Get the type without const, *, and &. */
137template<typename T>
138struct base_type {
139 using type = decay_t< actual_type_t<T> >;
140};
141
142/** Convenience alias for base_type. */
143template <typename T>
144using base_type_t = typename base_type<T>::type;
145
146
147/** Get the type without * and & (retains const, which is useful for function args). */
148template<typename T>
150 using type = remove_pointer_t< remove_reference_t< actual_type_t<T> > >;
151};
152
153/** Convenience alias for base_arg_type. */
154template <typename T>
155using base_arg_type_t = typename base_arg_type<T>::type;
156
157
158/** Test if a type is the same as its actual type. */
159template <typename T>
160struct is_actual {
161 static constexpr bool value = is_same_v<T, actual_type_t<T>>;
162};
163
164/** Convenience variable template to check if a type is its own actual type. */
165template <typename T>
166inline constexpr bool is_actual_v = is_actual<T>::value;
167
168namespace _ {
169
170template <typename T>
172 static constexpr bool value = !is_pointer<T>::value &&
173 !is_empty<actual_type_t<T>>::value && is_actual<T>::value &&
175};
176
177template <typename T>
179 static constexpr bool value = is_sparse_field<T>::value &&
181 flecs::on_instantiate::inherit;
182};
183
184template <typename ... Components>
186 static constexpr bool value = sizeof...(Components) != 0 &&
187 (is_sparse_query_field<remove_reference_t<Components>>::value && ...);
188};
189
190/** Test if a component is sparse at compile time. Components with the
191 * DontFragment trait are always sparse. */
192template <typename T>
194 static constexpr bool value =
197};
198
199/** Test if get/get_mut for a component can use ecs_get_sparse_id(). */
200template <typename T>
202 static constexpr bool value = is_sparse_component<T>::value &&
204 flecs::on_instantiate::inherit;
205};
206
207} // namespace _
208
209/** @} */
210
211} // namespace flecs
pair< First, Second > pair_object
Alias for pair when First is empty (tag).
Definition pair.hpp:90
constexpr bool is_pair_v
Convenience variable template to check if a type is a pair.
Definition pair.hpp:104
transcribe_cvp_t< remove_reference_t< P >, typename raw_type_t< P >::type > pair_type_t
Get the pair::type type from a pair while preserving cv qualifiers and pointer type.
Definition pair.hpp:116
constexpr bool is_actual_v
Convenience variable template to check if a type is its own actual type.
Definition pair.hpp:166
transcribe_cv_t< remove_reference_t< P >, typename raw_type_t< P >::second > pair_second_t
Get pair::second from a pair while preserving cv qualifiers.
Definition pair.hpp:112
remove_pointer_t< remove_reference_t< T > > raw_type_t
Get the raw type by removing pointer and reference qualifiers.
Definition pair.hpp:94
typename base_type< T >::type base_type_t
Convenience alias for base_type.
Definition pair.hpp:144
typename base_arg_type< T >::type base_arg_type_t
Convenience alias for base_arg_type.
Definition pair.hpp:155
transcribe_cv_t< remove_reference_t< P >, typename raw_type_t< P >::first > pair_first_t
Get pair::first from a pair while preserving cv qualifiers.
Definition pair.hpp:108
Int to enum.
Definition component.hpp:18
Test if get/get_mut for a component can use ecs_get_sparse_id().
Definition pair.hpp:201
Test if a component is sparse at compile time.
Definition pair.hpp:193
Get the actual type from a regular type or pair.
Definition pair.hpp:120
Get the type without * and & (retains const, which is useful for function args).
Definition pair.hpp:149
Get the type without const, *, and &.
Definition pair.hpp:138
Trait that marks a component as DontFragment at compile time.
Definition utils.hpp:178
Test if a type is the same as its actual type.
Definition pair.hpp:160
Test if a type is a pair.
Definition pair.hpp:98
Trait that assigns an OnInstantiate policy to a component at compile time.
Definition utils.hpp:204
Type that represents a pair.
Definition pair.hpp:36
Second second
The second element type of the pair.
Definition pair.hpp:39
type & operator*()
Dereference operator for mutable access.
Definition pair.hpp:75
pair(const type &v)
Construct pair from a const reference to the storage type.
Definition pair.hpp:52
pair(type &v)
Construct pair from a mutable reference to the storage type.
Definition pair.hpp:45
type * operator->()
Arrow operator for mutable access.
Definition pair.hpp:65
conditional_t<!is_empty< First >::value||is_empty< Second >::value, First, Second > type
The storage type of the pair.
Definition pair.hpp:37
const type & operator*() const
Dereference operator for const access.
Definition pair.hpp:80
First first
The first element type of the pair.
Definition pair.hpp:38
const type * operator->() const
Arrow operator for const access.
Definition pair.hpp:70
Trait that marks a component as Sparse at compile time.
Definition utils.hpp:187
Type class.
Definition type.hpp:21
enable_if_t< false==V, int > if_not_t
Convenience enable_if alias for negated conditions.
Definition utils.hpp:172
enable_if_t< V, int > if_t
Convenience enable_if alias using int as default type.
Definition utils.hpp:168
transcribe_cv_t< Src, transcribe_pointer_t< Src, Dst > > transcribe_cvp_t
Apply const, volatile, and pointer from source type to destination type.
Definition utils.hpp:156
transcribe_const_t< Src, transcribe_volatile_t< Src, Dst > > transcribe_cv_t
Apply const and volatile from source type to destination type.
Definition utils.hpp:148