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);
120 template <
typename U,
typename ListT,
121 bool ListContainsType = TSHasTypeImpl<ListT, U>::Value>
122 struct TSAppendUniqueImpl;
128 template <
typename U,
typename... Ts>
129 struct TSAppendUniqueImpl<U, TypeList<Ts...>, true> {
131 using RemovedU =
typename TypeList<Ts...>::template Remove<U>;
143 using type =
typename TypeList<U>::template Append<RemovedU>;
150 template <
typename U,
typename... Ts>
151 struct TSAppendUniqueImpl<U, TypeList<Ts...>, false> {
152 using type = TypeList<U, Ts...>;
165 template <
typename... Ts>
166 struct TSRecurseAppendUniqueImpl;
170 struct TSRecurseAppendUniqueImpl<> {
171 using type = TypeList<>;
178 template <
typename... Ts,
typename... OtherTs>
179 struct TSRecurseAppendUniqueImpl<TypeList<Ts...>, OtherTs...> {
180 using type =
typename TSRecurseAppendUniqueImpl<OtherTs..., Ts...>
::type;
188 template <
typename U,
typename... Ts>
189 struct TSRecurseAppendUniqueImpl<U, Ts...>
191 using type =
typename TSAppendUniqueImpl<U,
192 typename TSRecurseAppendUniqueImpl<Ts...>
::type
201 template<
typename ListT,
typename... Ts>
struct TSAppendImpl;
207 template<
typename... Ts,
typename... OtherTs>
208 struct TSAppendImpl<TypeList<Ts...>, OtherTs...> {
209 using type = TypeList<Ts..., OtherTs...>;
216 template<
typename... Ts,
typename... OtherTs>
217 struct TSAppendImpl<TypeList<Ts...>, TypeList<OtherTs...>> {
218 using type = TypeList<Ts..., OtherTs...>;
226 template<
typename ListT,
typename T>
struct TSEraseImpl;
231 struct TSEraseImpl<TypeList<>,
T> {
using type = TypeList<>; };
238 template<
typename... Ts,
typename T>
239 struct TSEraseImpl<TypeList<
T, Ts...>,
T> {
240 using type =
typename TSEraseImpl<TypeList<Ts...>,
T>
::type;
249 template<
typename T2,
typename... Ts,
typename T>
250 struct TSEraseImpl<TypeList<T2, Ts...>,
T> {
251 using type =
typename TSAppendImpl<TypeList<T2>,
261 template<
typename ListT,
typename... Ts>
struct TSRemoveImpl;
265 template<
typename ListT>
266 struct TSRemoveImpl<ListT> {
using type = ListT; };
273 template<
typename ListT,
typename T,
typename... Ts>
274 struct TSRemoveImpl<ListT,
T, Ts...> {
283 template<
typename ListT,
typename... Ts>
284 struct TSRemoveImpl<ListT, TypeList<Ts...>> {
285 using type =
typename TSRemoveImpl<ListT, Ts...>
::type;
293 struct TSRemoveFirstImpl {
294 using type = TypeList<>;
301 template<
typename T,
typename... Ts>
302 struct TSRemoveFirstImpl<TypeList<
T, Ts...>> {
303 using type = TypeList<Ts...>;
312 struct TSRemoveLastImpl {
using type = TypeList<>; };
321 struct TSRemoveLastImpl<TypeList<
T>> : TSRemoveLastImpl<T> {};
329 template<
typename T,
typename... Ts>
330 struct TSRemoveLastImpl<TypeList<
T, Ts...>>
333 typename TypeList<T>::template
334 Append<
typename TSRemoveLastImpl<TypeList<Ts...>>
::type>;
350 template<
typename ListT,
size_t First,
size_t Last,
size_t Idx=0>
351 struct TSRemoveIndicesImpl;
357 template<
size_t First,
size_t Last,
size_t Idx>
358 struct TSRemoveIndicesImpl<TypeList<>, First,
Last, Idx> {
359 using type = TypeList<>;
367 template<
typename T,
size_t First,
size_t Last,
size_t Idx>
368 struct TSRemoveIndicesImpl<TypeList<
T>, First,
Last, Idx>
371 static constexpr
bool Remove = Idx >= First && Idx <=
Last;
373 using type =
typename std::conditional<Remove, TypeList<>, TypeList<T>>
::type;
388 template<
typename T,
typename... Ts,
size_t First,
size_t Last,
size_t Idx>
389 struct TSRemoveIndicesImpl<TypeList<
T, Ts...>, First,
Last, Idx>
392 using ThisList =
typename TSRemoveIndicesImpl<TypeList<T>, First,
Last, Idx>
::type;
393 using NextList =
typename TSRemoveIndicesImpl<TypeList<Ts...>, First,
Last, Idx+1>
::type;
395 using type =
typename ThisList::template Append<NextList>;
405 template<
template <
typename>
class OpT,
typename... Ts>
struct TSTranformImpl;
409 template<
template <
typename>
class OpT>
410 struct TSTranformImpl<OpT> {
411 using type = TypeList<>;
418 template<
template <
typename>
class OpT,
typename T,
typename... Ts>
419 struct TSTranformImpl<OpT,
T, Ts...> {
421 using NextList =
typename TSTranformImpl<OpT, Ts...>
::type;
425 using type =
typename TSTranformImpl<OpT>::type::template
426 Append<OpT<T>>::template
431 template<
typename OpT>
inline void TSForEachImpl(OpT) {}
432 template<
typename OpT,
typename T,
typename... Ts>
433 inline void TSForEachImpl(OpT op) { op(
T()); TSForEachImpl<OpT, Ts...>(op); }
435 template<
template <
typename>
class OpT>
inline void TSForEachImpl() {}
436 template<
template <
typename>
class OpT,
typename T,
typename... Ts>
437 inline void TSForEachImpl() { OpT<T>()(); TSForEachImpl<OpT, Ts...>(); }
445 template<
typename OpT,
typename BaseT,
typename T,
typename ...Ts>
446 struct TSApplyImpl {
static bool apply(BaseT&, OpT&) {
return false; } };
456 template<
typename OpT,
typename BaseT,
typename T,
typename ...Ts>
457 struct TSApplyImpl<OpT, BaseT, TypeList<
T, Ts...>>
462 static bool apply(BaseT&
obj, OpT& op)
464 if (obj.template isType<T>()) {
465 op(static_cast<CastT&>(obj));
468 return TSApplyImpl<OpT, BaseT, TypeList<Ts...>>::apply(obj, op);
482 template<
typename... Ts>
489 static constexpr
size_t Size =
sizeof...(Ts);
511 static constexpr
bool Contains = typelist_internal::TSHasTypeImpl<Self, T>::Value;
541 template<
typename ListT = TypeList<>>
542 using Unique =
typename typelist_internal::TSRecurseAppendUniqueImpl<ListT, Ts...>
::type;
559 template<
typename... TypesToAppend>
572 template<
typename... TypesToRemove>
619 template <
size_t First,
size_t Last>
639 template<
template <
typename>
class OpT>
659 template<
template <
typename>
class OpT>
660 static void foreach() { typelist_internal::TSForEachImpl<OpT, Ts...>(); }
682 template<
typename OpT>
683 static void foreach(OpT op) { typelist_internal::TSForEachImpl<OpT, Ts...>(op); }
720 template<
typename OpT,
typename BaseT>
722 return typelist_internal::TSApplyImpl<OpT, BaseT, Self>::apply(obj, op);
731 #endif // OPENVDB_TYPELIST_HAS_BEEN_INCLUDED
static constexpr bool Contains
True if this list contains the given type, false otherwise.
typename typelist_internal::TSRemoveFirstImpl< Self >::type PopFront
Remove the first element of this type list. Has no effect if the type list is already empty...
typename typelist_internal::TSRecurseAppendUniqueImpl< ListT, Ts...>::type Unique
Remove any duplicate types from this TypeList by rotating the next valid type left (maintains the ord...
typename typelist_internal::TSAppendImpl< Self, TypesToAppend...>::type Append
Append types, or the members of another TypeList, to this list.
#define OPENVDB_USE_VERSION_NAMESPACE
A generic, discriminated value, whose type may be queried dynamically.
static bool apply(OpT op, BaseT &obj)
Invoke a templated, unary functor on a provide obj of type BaseT only if said object is an applicable...
Mark the end – don't use this!
typename typelist_internal::TSRemoveImpl< Self, TypesToRemove...>::type Remove
Remove all occurrences of one or more types, or the members of another TypeList, from this list...
typename typelist_internal::TSRemoveIndicesImpl< Self, First, Last >::type RemoveByIndex
Return a new list with types removed by their location within the list. If First is equal to Last...
TypeList Self
The type of this list.
Library and file format version numbers.
typename typelist_internal::TSGetElementImpl< Self, N >::type Get
Access a particular element of this type list. If the index is out of range, typelist_internal::NullT...
typename typelist_internal::TSRemoveLastImpl< Self >::type PopBack
Remove the last element of this type list. Has no effect if the type list is already empty...
GLsizei const GLfloat * value
typename typelist_internal::TSTranformImpl< OpT, Ts...>::type Transform
Transform each type of this TypeList, rebuiling a new list of converted types. This method instantiat...
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
A list of types (not necessarily unique)
static constexpr size_t Size
The number of types in the type list.