12 #ifndef OPENVDB_TYPELIST_HAS_BEEN_INCLUDED
13 #define OPENVDB_TYPELIST_HAS_BEEN_INCLUDED
18 #include <type_traits>
28 #ifdef OPENVDB_TYPELIST_NO_FORCE_INLINE
29 #define OPENVDB_TYPELIST_FORCE_INLINE inline
31 #define OPENVDB_TYPELIST_FORCE_INLINE OPENVDB_FORCE_INLINE
41 template<
typename... Ts>
struct TypeList;
42 template<
typename... Ts>
struct TupleList;
44 namespace typelist_internal {
59 template<
typename ListT,
size_t Idx,
typename =
void>
struct TSGetElementImpl;
64 template<
typename... Ts,
size_t Idx>
65 struct TSGetElementImpl<TypeList<Ts...>, Idx,
66 typename std::enable_if<(Idx < sizeof...(Ts) && sizeof...(Ts))>::type> {
67 using type =
typename std::tuple_element<Idx, std::tuple<Ts...>>
::type;
74 template<
typename... Ts,
size_t Idx>
75 struct TSGetElementImpl<TypeList<Ts...>, Idx,
76 typename std::enable_if<!(Idx < sizeof...(Ts) && sizeof...(Ts))>::type> {
77 using type = NullType;
93 template <
typename ListT,
typename T,
size_t=0>
101 template <
typename T,
size_t Idx>
102 struct TSHasTypeImpl<TypeList<>, T, Idx> {
103 static constexpr
bool Value =
false;
104 static constexpr int64_t
Index = -1;
114 template <
typename U,
typename T,
typename... Ts,
size_t Idx>
115 struct TSHasTypeImpl<TypeList<U, Ts...>, T, Idx> :
116 TSHasTypeImpl<TypeList<Ts...>, T, Idx+1> {};
123 template <
typename T,
typename... Ts,
size_t Idx>
124 struct TSHasTypeImpl<TypeList<T, Ts...>, T, Idx>
126 static constexpr
bool Value =
true;
127 static constexpr int64_t
Index =
static_cast<int64_t
>(Idx);
136 template <
typename U,
typename ListT,
137 bool ListContainsType = TSHasTypeImpl<ListT, U>::Value>
138 struct TSAppendUniqueImpl;
144 template <
typename U,
typename... Ts>
145 struct TSAppendUniqueImpl<U, TypeList<Ts...>, true> {
147 using RemovedU =
typename TypeList<Ts...>::template Remove<U>;
159 using type =
typename TypeList<U>::template Append<RemovedU>;
166 template <
typename U,
typename... Ts>
167 struct TSAppendUniqueImpl<U, TypeList<Ts...>, false> {
168 using type = TypeList<U, Ts...>;
181 template <
typename... Ts>
182 struct TSRecurseAppendUniqueImpl;
186 struct TSRecurseAppendUniqueImpl<> {
187 using type = TypeList<>;
194 template <
typename... Ts,
typename... OtherTs>
195 struct TSRecurseAppendUniqueImpl<TypeList<Ts...>, OtherTs...> {
196 using type =
typename TSRecurseAppendUniqueImpl<OtherTs..., Ts...>
::type;
204 template <
typename U,
typename... Ts>
205 struct TSRecurseAppendUniqueImpl<U, Ts...>
207 using type =
typename TSAppendUniqueImpl<U,
208 typename TSRecurseAppendUniqueImpl<Ts...>
::type
217 template<
typename ListT,
typename... Ts>
struct TSAppendImpl;
223 template<
typename... Ts,
typename... OtherTs>
224 struct TSAppendImpl<TypeList<Ts...>, OtherTs...> {
225 using type = TypeList<Ts..., OtherTs...>;
232 template<
typename... Ts,
typename... OtherTs>
233 struct TSAppendImpl<TypeList<Ts...>, TypeList<OtherTs...>> {
234 using type = TypeList<Ts..., OtherTs...>;
242 template<
typename ListT,
typename T>
struct TSEraseImpl;
247 struct TSEraseImpl<TypeList<>, T> {
using type = TypeList<>; };
254 template<
typename... Ts,
typename T>
255 struct TSEraseImpl<TypeList<T, Ts...>, T> {
256 using type =
typename TSEraseImpl<TypeList<Ts...>, T>
::type;
265 template<
typename T2,
typename... Ts,
typename T>
266 struct TSEraseImpl<TypeList<T2, Ts...>, T> {
267 using type =
typename TSAppendImpl<TypeList<T2>,
277 template<
typename ListT,
typename... Ts>
struct TSRemoveImpl;
281 template<
typename ListT>
282 struct TSRemoveImpl<ListT> {
using type = ListT; };
289 template<
typename ListT,
typename T,
typename... Ts>
290 struct TSRemoveImpl<ListT, T, Ts...> {
299 template<
typename ListT,
typename... Ts>
300 struct TSRemoveImpl<ListT, TypeList<Ts...>> {
301 using type =
typename TSRemoveImpl<ListT, Ts...>
::type;
309 struct TSRemoveFirstImpl {
310 using type = TypeList<>;
317 template<
typename T,
typename... Ts>
318 struct TSRemoveFirstImpl<TypeList<T, Ts...>> {
319 using type = TypeList<Ts...>;
328 struct TSRemoveLastImpl {
using type = TypeList<>; };
337 struct TSRemoveLastImpl<TypeList<T>> : TSRemoveLastImpl<T> {};
345 template<
typename T,
typename... Ts>
346 struct TSRemoveLastImpl<TypeList<T, Ts...>>
349 typename TypeList<T>::template
350 Append<
typename TSRemoveLastImpl<TypeList<Ts...>>
::type>;
366 template<
typename ListT,
size_t First,
size_t Last,
size_t Idx=0>
367 struct TSRemoveIndicesImpl;
373 template<
size_t First,
size_t Last,
size_t Idx>
374 struct TSRemoveIndicesImpl<TypeList<>, First, Last, Idx> {
375 using type = TypeList<>;
383 template<
typename T,
size_t First,
size_t Last,
size_t Idx>
384 struct TSRemoveIndicesImpl<TypeList<T>, First, Last, Idx>
387 static constexpr
bool Remove = Idx >= First && Idx <= Last;
389 using type =
typename std::conditional<Remove, TypeList<>, TypeList<T>>
::type;
404 template<
typename T,
typename... Ts,
size_t First,
size_t Last,
size_t Idx>
405 struct TSRemoveIndicesImpl<TypeList<T, Ts...>, First, Last, Idx>
408 using ThisList =
typename TSRemoveIndicesImpl<TypeList<T>, First, Last, Idx>
::type;
409 using NextList =
typename TSRemoveIndicesImpl<TypeList<Ts...>, First, Last, Idx+1>
::type;
411 using type =
typename ThisList::template Append<NextList>;
421 template<
template <
typename>
class OpT,
typename... Ts>
struct TSTranformImpl;
425 template<
template <
typename>
class OpT>
426 struct TSTranformImpl<OpT> {
427 using type = TypeList<>;
434 template<
template <
typename>
class OpT,
typename T,
typename... Ts>
435 struct TSTranformImpl<OpT, T, Ts...> {
437 using NextList =
typename TSTranformImpl<OpT, Ts...>
::type;
441 using type =
typename TSTranformImpl<OpT>::type::template
442 Append<OpT<T>>::template
451 template<
typename OpT,
typename BaseT,
typename T,
typename ...Ts>
452 struct TSApplyImpl {
static bool apply(
BaseT&, OpT&) {
return false; } };
462 template<
typename OpT,
typename BaseT,
typename T,
typename ...Ts>
463 struct TSApplyImpl<OpT, BaseT, TypeList<T, Ts...>>
468 static bool apply(BaseT& obj, OpT& op)
470 if (obj.template isType<T>()) {
471 op(static_cast<CastT&>(obj));
474 return TSApplyImpl<OpT,
BaseT, TypeList<Ts...>>::apply(obj, op);
478 template<
template <
typename>
class OpT>
inline void TSForEachImpl() {}
479 template<
template <
typename>
class OpT,
typename T,
typename... Ts>
480 inline void TSForEachImpl() { OpT<T>()(); TSForEachImpl<OpT, Ts...>(); }
482 template<
typename OpT>
inline void TSForEachImpl(OpT) {}
483 template<
typename OpT,
typename T,
typename... Ts>
485 op(T()); TSForEachImpl<OpT, Ts...>(op);
492 template<
size_t Iter,
size_t End,
typename OpT,
typename TupleT>
494 [[maybe_unused]] OpT op,
495 [[maybe_unused]] TupleT& tup)
497 if constexpr(Iter<End) {
498 op(std::get<Iter>(tup));
499 TSForEachImpl<Iter+1, End, OpT, TupleT>(op, tup);
503 template<
typename OpT,
size_t Iter,
size_t End>
506 if constexpr(Iter<End) {
507 op(std::integral_constant<std::size_t, Iter>());
508 TSForEachIndexImpl<OpT, Iter+1, End>(op);
512 template<
typename OpT,
typename RetT,
size_t Iter,
size_t End>
515 if constexpr(Iter<End) {
516 if (
auto ret = op(std::integral_constant<std::size_t, Iter>()))
return ret;
517 return TSEvalFirstIndex<OpT, RetT, Iter+1, End>(op, def);
522 template<
class Pred,
class OpT,
typename TupleT,
size_t Iter,
size_t End>
524 void TSEvalFirstPredImpl(
525 [[maybe_unused]] Pred pred,
526 [[maybe_unused]] OpT op,
527 [[maybe_unused]] TupleT& tup)
529 if constexpr (Iter<End) {
530 constexpr
auto Idx = std::integral_constant<std::size_t, Iter>();
531 if (pred(Idx)) op(std::get<Idx>(tup));
532 else TSEvalFirstPredImpl<Pred, OpT, TupleT, Iter+1, End>(pred, op, tup);
536 template<
class Pred,
class OpT,
typename TupleT,
typename RetT,
size_t Iter,
size_t End>
538 RetT TSEvalFirstPredImpl(
539 [[maybe_unused]] Pred pred,
540 [[maybe_unused]] OpT op,
541 [[maybe_unused]] TupleT& tup,
544 if constexpr (Iter<End) {
545 constexpr
auto Idx = std::integral_constant<std::size_t, Iter>();
546 if (pred(Idx))
return op(std::get<Idx>(tup));
547 else return TSEvalFirstPredImpl
548 <Pred, OpT, TupleT, RetT, Iter+1, End>(pred, op, tup, def);
559 template<
size_t Start,
size_t End,
typename OpT>
562 typelist_internal::TSForEachIndexImpl<OpT, Start, End>(op);
565 template<
size_t Start,
size_t End,
typename OpT,
typename RetT>
568 return typelist_internal::TSEvalFirstIndex<OpT, RetT, Start, End>(op, def);
576 template<
typename... Ts>
585 static constexpr
size_t Size =
sizeof...(Ts);
607 static constexpr
bool Contains = typelist_internal::TSHasTypeImpl<Self, T>::Value;
637 template<
typename ListT = TypeList<>>
638 using Unique =
typename typelist_internal::TSRecurseAppendUniqueImpl<ListT, Ts...>
::type;
655 template<
typename... TypesToAppend>
668 template<
typename... TypesToRemove>
715 template <
size_t First,
size_t Last>
735 template<
template <
typename>
class OpT>
755 template<
template <
typename>
class OpT>
757 typelist_internal::TSForEachImpl<OpT, Ts...>();
780 template<
typename OpT>
782 typelist_internal::TSForEachImpl<OpT, Ts...>(op);
785 template<
typename OpT>
787 foreachIndex<OpT, 0, Size>(op);
790 template<
typename OpT,
typename RetT>
792 return foreachIndex<OpT, RetT, 0, Size>(op, def);
830 template<
typename OpT,
typename BaseT>
832 return typelist_internal::TSApplyImpl<OpT, BaseT, Self>::apply(obj, op);
849 template<
typename... Ts>
858 constexpr
auto size() {
return std::tuple_size_v<TupleT>; }
862 template <
size_t Idx> constexpr
auto&
get() {
return std::get<Idx>(mTuple); }
863 template <
size_t Idx> constexpr
auto&
get()
const {
return std::get<Idx>(mTuple); }
880 template<
typename OpT>
882 typelist_internal::TSForEachImpl<0, AsTypeList::Size>(op, mTuple);
908 template<
class Pred,
class OpT>
911 typelist_internal::TSEvalFirstPredImpl
940 template<
class Pred,
class OpT,
typename RetT>
943 return typelist_internal::TSEvalFirstPredImpl
945 (pred, op, mTuple, def);
962 constexpr
auto size() {
return std::tuple_size_v<TupleT>; }
966 template <
size_t Idx>
inline constexpr
auto&
get() {
return std::get<Idx>(mTuple); }
967 template <
size_t Idx>
inline constexpr
auto&
get()
const {
return std::get<Idx>(mTuple); }
969 template<
typename OpT> constexpr
void foreach(OpT) {}
971 template<
class Pred,
class OpT,
typename RetT>
982 #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...
GLsizei const GLfloat * value
A trivial wrapper around a std::tuple but with compatible TypeList methods. Importantly can be instat...
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.
const TupleT & tuple() const
#define OPENVDB_USE_VERSION_NAMESPACE
static OPENVDB_TYPELIST_FORCE_INLINE 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...
OPENVDB_TYPELIST_FORCE_INLINE RetT evalFirstPred(Pred pred, OpT op, RetT def)
Run a function on the first element in the underlying std::tuple that satisfies the provided predicat...
OPENVDB_TYPELIST_FORCE_INLINE void evalFirstPred(Pred pred, OpT op)
Run a function on the first element in the underlying std::tuple that satisfies the provided predicat...
static OPENVDB_TYPELIST_FORCE_INLINE RetT foreachIndex(OpT op, RetT def)
#define OPENVDB_TYPELIST_FORCE_INLINE
A generic, discriminated value, whose type may be queried dynamically.
constexpr TupleT & tuple()
LeafFnBase< CoordT, MaskT, LOG2DIM > BaseT
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...
constexpr RetT evalFirstPred(Pred, OpT, RetT def)
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.
static OPENVDB_TYPELIST_FORCE_INLINE void foreachIndex(OpT op)
Library and file format version numbers.
OPENVDB_TYPELIST_FORCE_INLINE RetT evalFirstIndex(OpT op, const RetT def=RetT())
constexpr void evalFirstPred(Pred, OpT)
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...
constexpr TupleT & tuple() const
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...
**If you just want to fire and args
OPENVDB_TYPELIST_FORCE_INLINE auto foreachIndex(OpT op)
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)
std::tuple< Ts...> TupleT
static constexpr size_t Size
The number of types in the type list.