12 #ifndef OPENVDB_TYPELIST_HAS_BEEN_INCLUDED
13 #define OPENVDB_TYPELIST_HAS_BEEN_INCLUDED
18 #include <type_traits>
26 template<
typename... Ts>
struct TypeList;
28 namespace typelist_internal {
43 template<
typename ListT,
size_t Idx,
typename =
void>
struct TSGetElementImpl;
48 template<
typename... Ts,
size_t Idx>
49 struct TSGetElementImpl<TypeList<Ts...>, Idx,
50 typename
std::enable_if<(Idx < sizeof...(Ts) && sizeof...(Ts))>::type> {
51 using type =
typename std::tuple_element<Idx, std::tuple<Ts...>>::type;
58 template<
typename... Ts,
size_t Idx>
59 struct TSGetElementImpl<TypeList<Ts...>, Idx,
60 typename
std::enable_if<!(Idx < sizeof...(Ts) && sizeof...(Ts))>::type> {
61 using type = NullType;
77 template <
typename ListT,
typename T,
size_t=0>
85 template <
typename T,
size_t Idx>
86 struct TSHasTypeImpl<TypeList<>, T, Idx> {
87 static constexpr
bool Value =
false;
88 static constexpr int64_t
Index = -1;
98 template <
typename U,
typename T,
typename... Ts,
size_t Idx>
99 struct TSHasTypeImpl<TypeList<U, Ts...>, T, Idx> :
100 TSHasTypeImpl<TypeList<Ts...>, T, Idx+1> {};
107 template <
typename T,
typename... Ts,
size_t Idx>
108 struct TSHasTypeImpl<TypeList<T, Ts...>, T, Idx>
110 static constexpr
bool Value =
true;
111 static constexpr int64_t
Index =
static_cast<int64_t
>(Idx);
125 template <
typename ListT,
typename... Ts>
126 struct TSMakeUniqueImpl {
138 template <
typename... Ts,
typename U,
typename... Us>
139 struct TSMakeUniqueImpl<TypeList<Ts...>, U, Us...>
141 using type =
typename std::conditional<
142 TSHasTypeImpl<TypeList<Ts...>, U>::Value,
143 typename TSMakeUniqueImpl<TypeList<Ts...>, Us...>::type,
144 typename TSMakeUniqueImpl<TypeList<Ts..., U>, Us...>::type >::type;
152 template<
typename ListT,
typename... Ts>
struct TSAppendImpl;
158 template<
typename... Ts,
typename... OtherTs>
159 struct TSAppendImpl<TypeList<Ts...>, OtherTs...> {
160 using type = TypeList<Ts..., OtherTs...>;
167 template<
typename... Ts,
typename... OtherTs>
168 struct TSAppendImpl<TypeList<Ts...>, TypeList<OtherTs...>> {
169 using type = TypeList<Ts..., OtherTs...>;
177 template<
typename ListT,
typename T>
struct TSEraseImpl;
182 struct TSEraseImpl<TypeList<>, T> {
using type = TypeList<>; };
189 template<
typename... Ts,
typename T>
190 struct TSEraseImpl<TypeList<T, Ts...>, T> {
191 using type =
typename TSEraseImpl<TypeList<Ts...>, T>::type;
200 template<
typename T2,
typename... Ts,
typename T>
201 struct TSEraseImpl<TypeList<T2, Ts...>, T> {
202 using type =
typename TSAppendImpl<TypeList<T2>,
203 typename TSEraseImpl<TypeList<Ts...>, T>::type>::type;
212 template<
typename ListT,
typename... Ts>
struct TSRemoveImpl;
216 template<
typename ListT>
217 struct TSRemoveImpl<ListT> {
using type = ListT; };
224 template<
typename ListT,
typename T,
typename... Ts>
225 struct TSRemoveImpl<ListT, T, Ts...> {
226 using type =
typename TSRemoveImpl<typename TSEraseImpl<ListT, T>::type, Ts...>::type;
234 template<
typename ListT,
typename... Ts>
235 struct TSRemoveImpl<ListT, TypeList<Ts...>> {
236 using type =
typename TSRemoveImpl<ListT, Ts...>::type;
244 struct TSRemoveFirstImpl {
245 using type = TypeList<>;
252 template<
typename T,
typename... Ts>
253 struct TSRemoveFirstImpl<TypeList<T, Ts...>> {
254 using type = TypeList<Ts...>;
263 struct TSRemoveLastImpl {
using type = TypeList<>; };
272 struct TSRemoveLastImpl<TypeList<T>> : TSRemoveLastImpl<T> {};
280 template<
typename T,
typename... Ts>
281 struct TSRemoveLastImpl<TypeList<T, Ts...>>
284 typename TypeList<T>::template
285 Append<
typename TSRemoveLastImpl<TypeList<Ts...>>::type>;
301 template<
typename ListT,
size_t First,
size_t Last,
size_t Idx=0>
302 struct TSRemoveIndicesImpl;
308 template<
size_t First,
size_t Last,
size_t Idx>
309 struct TSRemoveIndicesImpl<TypeList<>, First, Last, Idx> {
310 using type = TypeList<>;
318 template<
typename T,
size_t First,
size_t Last,
size_t Idx>
319 struct TSRemoveIndicesImpl<TypeList<T>, First, Last, Idx>
322 static constexpr
bool Remove = Idx >= First && Idx <= Last;
324 using type =
typename std::conditional<Remove, TypeList<>, TypeList<T>>::type;
339 template<
typename T,
typename... Ts,
size_t First,
size_t Last,
size_t Idx>
340 struct TSRemoveIndicesImpl<TypeList<T, Ts...>, First, Last, Idx>
343 using ThisList =
typename TSRemoveIndicesImpl<TypeList<T>, First, Last, Idx>::type;
344 using NextList =
typename TSRemoveIndicesImpl<TypeList<Ts...>, First, Last, Idx+1>::type;
346 using type =
typename ThisList::template Append<NextList>;
350 template<
typename OpT>
inline void TSForEachImpl(OpT) {}
351 template<
typename OpT,
typename T,
typename... Ts>
352 inline void TSForEachImpl(OpT op) { op(T()); TSForEachImpl<OpT, Ts...>(op); }
364 template<
typename... Ts>
371 static constexpr
size_t Size =
sizeof...(Ts);
376 using Get =
typename typelist_internal::TSGetElementImpl<Self, N>::type;
393 static constexpr
bool Contains = typelist_internal::TSHasTypeImpl<Self, T>::Value;
423 template<
typename ListT = TypeList<>>
424 using Unique =
typename typelist_internal::TSMakeUniqueImpl<ListT, Ts...>::type;
439 template<
typename... TypesToAppend>
440 using Append =
typename typelist_internal::TSAppendImpl<
Self, TypesToAppend...>::type;
452 template<
typename... TypesToRemove>
453 using Remove =
typename typelist_internal::TSRemoveImpl<
Self, TypesToRemove...>::type;
468 using PopFront =
typename typelist_internal::TSRemoveFirstImpl<Self>::type;
483 using PopBack =
typename typelist_internal::TSRemoveLastImpl<Self>::type;
499 template <
size_t First,
size_t Last>
500 using RemoveByIndex =
typename typelist_internal::TSRemoveIndicesImpl<Self, First, Last>::type;
522 template<
typename OpT>
523 static void foreach(OpT op) { typelist_internal::TSForEachImpl<OpT, Ts...>(op); }
531 #endif // OPENVDB_TYPELIST_HAS_BEEN_INCLUDED