12#ifndef OPENVDB_TYPELIST_HAS_BEEN_INCLUDED
13#define OPENVDB_TYPELIST_HAS_BEEN_INCLUDED
28#ifdef OPENVDB_TYPELIST_NO_FORCE_INLINE
29#define OPENVDB_TYPELIST_FORCE_INLINE inline
31#define OPENVDB_TYPELIST_FORCE_INLINE OPENVDB_FORCE_INLINE
41template<
typename... Ts>
struct TypeList;
42template<
typename... Ts>
struct TupleList;
44namespace typelist_internal {
59template<
typename ListT,
size_t Idx,
typename =
void>
struct TSGetElementImpl;
64template<
typename... Ts,
size_t Idx>
65struct 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;
74template<
typename... Ts,
size_t Idx>
75struct TSGetElementImpl<TypeList<Ts...>, Idx,
76 typename
std::enable_if<!(Idx < sizeof...(Ts) && sizeof...(Ts))>::type> {
77 using type = NullType;
93template <
typename ListT,
typename T,
size_t=0>
101template <
typename T,
size_t Idx>
102struct TSHasTypeImpl<TypeList<>, T, Idx> {
103 static constexpr bool Value =
false;
104 static constexpr int64_t Index = -1;
114template <
typename U,
typename T,
typename... Ts,
size_t Idx>
115struct TSHasTypeImpl<TypeList<U, Ts...>, T, Idx> :
116 TSHasTypeImpl<TypeList<Ts...>, T, Idx+1> {};
123template <
typename T,
typename... Ts,
size_t Idx>
124struct TSHasTypeImpl<TypeList<T, Ts...>, T, Idx>
126 static constexpr bool Value =
true;
127 static constexpr int64_t Index =
static_cast<int64_t
>(Idx);
136template <
typename U,
typename ListT,
137 bool ListContainsType = TSHasTypeImpl<ListT, U>::Value>
138struct TSAppendUniqueImpl;
144template <
typename U,
typename... Ts>
145struct TSAppendUniqueImpl<U, TypeList<Ts...>, true> {
147 using RemovedU =
typename TypeList<Ts...>::template Remove<U>;
159 using type =
typename TypeList<U>::template Append<RemovedU>;
166template <
typename U,
typename... Ts>
167struct TSAppendUniqueImpl<U, TypeList<Ts...>, false> {
168 using type = TypeList<U, Ts...>;
181template <
typename... Ts>
182struct TSRecurseAppendUniqueImpl;
186struct TSRecurseAppendUniqueImpl<> {
187 using type = TypeList<>;
194template <
typename... Ts,
typename... OtherTs>
195struct TSRecurseAppendUniqueImpl<TypeList<Ts...>, OtherTs...> {
196 using type =
typename TSRecurseAppendUniqueImpl<OtherTs..., Ts...>::type;
204template <
typename U,
typename... Ts>
205struct TSRecurseAppendUniqueImpl<U, Ts...>
207 using type =
typename TSAppendUniqueImpl<U,
208 typename TSRecurseAppendUniqueImpl<Ts...>::type
217template<
typename ListT,
typename... Ts>
struct TSAppendImpl;
223template<
typename... Ts,
typename... OtherTs>
224struct TSAppendImpl<TypeList<Ts...>, OtherTs...> {
225 using type = TypeList<Ts..., OtherTs...>;
232template<
typename... Ts,
typename... OtherTs>
233struct TSAppendImpl<TypeList<Ts...>, TypeList<OtherTs...>> {
234 using type = TypeList<Ts..., OtherTs...>;
242template<
typename ListT,
typename T>
struct TSEraseImpl;
247struct TSEraseImpl<TypeList<>, T> {
using type = TypeList<>; };
254template<
typename... Ts,
typename T>
255struct TSEraseImpl<TypeList<T, Ts...>, T> {
256 using type =
typename TSEraseImpl<TypeList<Ts...>, T>::type;
265template<
typename T2,
typename... Ts,
typename T>
266struct TSEraseImpl<TypeList<T2, Ts...>, T> {
267 using type =
typename TSAppendImpl<TypeList<T2>,
268 typename TSEraseImpl<TypeList<Ts...>, T>::type>::type;
277template<
typename ListT,
typename... Ts>
struct TSRemoveImpl;
281template<
typename ListT>
282struct TSRemoveImpl<ListT> {
using type = ListT; };
289template<
typename ListT,
typename T,
typename... Ts>
290struct TSRemoveImpl<ListT, T, Ts...> {
291 using type =
typename TSRemoveImpl<typename TSEraseImpl<ListT, T>::type, Ts...>::type;
299template<
typename ListT,
typename... Ts>
300struct TSRemoveImpl<ListT, TypeList<Ts...>> {
301 using type =
typename TSRemoveImpl<ListT, Ts...>::type;
309struct TSRemoveFirstImpl {
310 using type = TypeList<>;
317template<
typename T,
typename... Ts>
318struct TSRemoveFirstImpl<TypeList<T, Ts...>> {
319 using type = TypeList<Ts...>;
328struct TSRemoveLastImpl {
using type = TypeList<>; };
337struct TSRemoveLastImpl<TypeList<T>> : TSRemoveLastImpl<T> {};
345template<
typename T,
typename... Ts>
346struct TSRemoveLastImpl<TypeList<T, Ts...>>
349 typename TypeList<T>::template
350 Append<
typename TSRemoveLastImpl<TypeList<Ts...>>::type>;
366template<
typename ListT,
size_t First,
size_t Last,
size_t Idx=0>
367struct TSRemoveIndicesImpl;
373template<
size_t First,
size_t Last,
size_t Idx>
374struct TSRemoveIndicesImpl<TypeList<>, First, Last, Idx> {
375 using type = TypeList<>;
383template<
typename T,
size_t First,
size_t Last,
size_t Idx>
384struct 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;
404template<
typename T,
typename... Ts,
size_t First,
size_t Last,
size_t Idx>
405struct 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>;
421template<
template <
typename>
class OpT,
typename... Ts>
struct TSTranformImpl;
425template<
template <
typename>
class OpT>
426struct TSTranformImpl<OpT> {
427 using type = TypeList<>;
434template<
template <
typename>
class OpT,
typename T,
typename... Ts>
435struct 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
451template<
typename OpT,
typename BaseT,
typename T,
typename ...Ts>
452struct TSApplyImpl {
static bool apply(BaseT&, OpT&) {
return false; } };
462template<
typename OpT,
typename BaseT,
typename T,
typename ...Ts>
463struct TSApplyImpl<OpT, BaseT, TypeList<T, Ts...>>
466 typename std::conditional<std::is_const<BaseT>::value,
const T, T>::type;
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);
478template<
template <
typename>
class OpT>
inline void TSForEachImpl() {}
479template<
template <
typename>
class OpT,
typename T,
typename... Ts>
480inline void TSForEachImpl() { OpT<T>()(); TSForEachImpl<OpT, Ts...>(); }
482template<
typename OpT>
inline void TSForEachImpl(OpT) {}
483template<
typename OpT,
typename T,
typename... Ts>
485 op(T()); TSForEachImpl<OpT, Ts...>(op);
492template<
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);
503template<
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);
512template<
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);
522template<
class Pred,
class OpT,
typename TupleT,
size_t Iter,
size_t End>
524void 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);
536template<
class Pred,
class OpT,
typename TupleT,
typename RetT,
size_t Iter,
size_t End>
538RetT 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);
559template<
size_t Start,
size_t End,
typename OpT>
562 typelist_internal::TSForEachIndexImpl<OpT, Start, End>(op);
565template<
size_t Start,
size_t End,
typename OpT,
typename RetT>
568 return typelist_internal::TSEvalFirstIndex<OpT, RetT, Start, End>(op, def);
576template<
typename... Ts>
585 static constexpr size_t Size =
sizeof...(Ts);
590 using Get =
typename typelist_internal::TSGetElementImpl<Self, N>::type;
607 static constexpr bool Contains = typelist_internal::TSHasTypeImpl<Self, T>::Value;
623 static constexpr int64_t
Index = typelist_internal::TSHasTypeImpl<Self, T>::Index;
637 template<
typename ListT = TypeList<>>
638 using Unique =
typename typelist_internal::TSRecurseAppendUniqueImpl<ListT, Ts...>::type;
655 template<
typename... TypesToAppend>
656 using Append =
typename typelist_internal::TSAppendImpl<
Self, TypesToAppend...>::type;
668 template<
typename... TypesToRemove>
669 using Remove =
typename typelist_internal::TSRemoveImpl<
Self, TypesToRemove...>::type;
684 using PopFront =
typename typelist_internal::TSRemoveFirstImpl<Self>::type;
699 using PopBack =
typename typelist_internal::TSRemoveLastImpl<Self>::type;
715 template <
size_t First,
size_t Last>
716 using RemoveByIndex =
typename typelist_internal::TSRemoveIndicesImpl<Self, First, Last>::type;
735 template<
template <
typename>
class OpT>
736 using Transform =
typename typelist_internal::TSTranformImpl<OpT, Ts...>::type;
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);
849template<
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
912 <Pred, OpT,
TupleT, 0, AsTypeList::Size>
940 template<
class Pred,
class OpT,
typename RetT>
943 return typelist_internal::TSEvalFirstPredImpl
944 <Pred, OpT,
TupleT, RetT, 0, AsTypeList::Size>
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>
#define OPENVDB_TYPELIST_FORCE_INLINE
Definition TypeList.h:31
Index32 Index
Definition Types.h:54
OPENVDB_FORCE_INLINE auto foreachIndex(OpT op)
Definition TypeList.h:560
OPENVDB_FORCE_INLINE RetT evalFirstIndex(OpT op, const RetT def=RetT())
Definition TypeList.h:566
Definition Exceptions.h:13
std::tuple<> TupleT
Definition TypeList.h:958
constexpr void evalFirstPred(Pred, OpT)
Definition TypeList.h:970
TupleT & tuple()
Definition TypeList.h:963
const TupleT & tuple() const
Definition TypeList.h:964
constexpr auto & get()
Definition TypeList.h:966
constexpr auto size()
Definition TypeList.h:962
constexpr auto & get() const
Definition TypeList.h:967
constexpr RetT evalFirstPred(Pred, OpT, RetT def)
Definition TypeList.h:972
A trivial wrapper around a std::tuple but with compatible TypeList methods. Importantly can be instat...
Definition TypeList.h:851
std::tuple< Ts... > TupleT
Definition TypeList.h:853
constexpr TupleT & tuple()
Definition TypeList.h:859
constexpr auto & get()
Definition TypeList.h:862
constexpr auto size()
Definition TypeList.h:858
OPENVDB_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...
Definition TypeList.h:941
OPENVDB_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...
Definition TypeList.h:909
constexpr TupleT & tuple() const
Definition TypeList.h:860
TupleList(Ts &&... args)
Definition TypeList.h:856
constexpr auto & get() const
Definition TypeList.h:863
A list of types (not necessarily unique)
Definition TypeList.h:578
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.
Definition TypeList.h:669
Get< 0 > Front
Definition TypeList.h:591
Get< Size-1 > Back
Definition TypeList.h:592
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...
Definition TypeList.h:590
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,...
Definition TypeList.h:716
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...
Definition TypeList.h:638
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.
Definition TypeList.h:684
static OPENVDB_FORCE_INLINE void foreachIndex(OpT op)
Definition TypeList.h:786
typename typelist_internal::TSTranformImpl< OpT, Ts... >::type Transform
Transform each type of this TypeList, rebuiling a new list of converted types. This method instantiat...
Definition TypeList.h:736
static OPENVDB_FORCE_INLINE RetT foreachIndex(OpT op, RetT def)
Definition TypeList.h:791
static OPENVDB_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...
Definition TypeList.h:831
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.
Definition TypeList.h:699
typename typelist_internal::TSAppendImpl< Self, TypesToAppend... >::type Append
Append types, or the members of another TypeList, to this list.
Definition TypeList.h:656
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:212