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);
557template<
size_t Start,
size_t End,
typename OpT>
560 typelist_internal::TSForEachIndexImpl<OpT, Start, End>(op);
563template<
size_t Start,
size_t End,
typename OpT,
typename RetT>
566 return typelist_internal::TSEvalFirstIndex<OpT, RetT, Start, End>(op, def);
574template<
typename... Ts>
583 static constexpr size_t Size =
sizeof...(Ts);
588 using Get =
typename typelist_internal::TSGetElementImpl<Self, N>::type;
605 static constexpr bool Contains = typelist_internal::TSHasTypeImpl<Self, T>::Value;
621 static constexpr int64_t
Index = typelist_internal::TSHasTypeImpl<Self, T>::Index;
635 template<
typename ListT = TypeList<>>
636 using Unique =
typename typelist_internal::TSRecurseAppendUniqueImpl<ListT, Ts...>::type;
653 template<
typename... TypesToAppend>
654 using Append =
typename typelist_internal::TSAppendImpl<
Self, TypesToAppend...>::type;
666 template<
typename... TypesToRemove>
667 using Remove =
typename typelist_internal::TSRemoveImpl<
Self, TypesToRemove...>::type;
682 using PopFront =
typename typelist_internal::TSRemoveFirstImpl<Self>::type;
697 using PopBack =
typename typelist_internal::TSRemoveLastImpl<Self>::type;
713 template <
size_t First,
size_t Last>
714 using RemoveByIndex =
typename typelist_internal::TSRemoveIndicesImpl<Self, First, Last>::type;
733 template<
template <
typename>
class OpT>
734 using Transform =
typename typelist_internal::TSTranformImpl<OpT, Ts...>::type;
753 template<
template <
typename>
class OpT>
755 typelist_internal::TSForEachImpl<OpT, Ts...>();
778 template<
typename OpT>
780 typelist_internal::TSForEachImpl<OpT, Ts...>(op);
783 template<
typename OpT>
788 template<
typename OpT,
typename RetT>
828 template<
typename OpT,
typename BaseT>
830 return typelist_internal::TSApplyImpl<OpT, BaseT, Self>::apply(obj, op);
847template<
typename... Ts>
856 constexpr auto size() {
return std::tuple_size_v<TupleT>; }
860 template <
size_t Idx>
constexpr auto&
get() {
return std::get<Idx>(mTuple); }
861 template <
size_t Idx>
constexpr auto&
get()
const {
return std::get<Idx>(mTuple); }
878 template<
typename OpT>
880 typelist_internal::TSForEachImpl<0, AsTypeList::Size>(op, mTuple);
906 template<
class Pred,
class OpT>
909 typelist_internal::TSEvalFirstPredImpl
938 template<
class Pred,
class OpT,
typename RetT>
941 return typelist_internal::TSEvalFirstPredImpl
943 (pred, op, mTuple, def);
960 constexpr auto size() {
return std::tuple_size_v<TupleT>; }
964 template <
size_t Idx>
inline constexpr auto&
get() {
return std::get<Idx>(mTuple); }
965 template <
size_t Idx>
inline constexpr auto&
get()
const {
return std::get<Idx>(mTuple); }
967 template<
typename OpT>
constexpr void foreach(OpT) {}
969 template<
class Pred,
class OpT,
typename RetT>
#define OPENVDB_TYPELIST_FORCE_INLINE
Definition TypeList.h:31
OPENVDB_FORCE_INLINE auto foreachIndex(OpT op)
Definition TypeList.h:558
OPENVDB_FORCE_INLINE RetT evalFirstIndex(OpT op, const RetT def=RetT())
Definition TypeList.h:564
Definition Exceptions.h:13
std::tuple<> TupleT
Definition TypeList.h:956
constexpr void evalFirstPred(Pred, OpT)
Definition TypeList.h:968
TupleT & tuple()
Definition TypeList.h:961
const TupleT & tuple() const
Definition TypeList.h:962
constexpr auto & get()
Definition TypeList.h:964
constexpr auto size()
Definition TypeList.h:960
constexpr auto & get() const
Definition TypeList.h:965
constexpr RetT evalFirstPred(Pred, OpT, RetT def)
Definition TypeList.h:970
TypeList<> AsTypeList
Definition TypeList.h:955
A trivial wrapper around a std::tuple but with compatible TypeList methods. Importantly can be instat...
Definition TypeList.h:849
std::tuple< Ts... > TupleT
Definition TypeList.h:851
constexpr TupleT & tuple()
Definition TypeList.h:857
constexpr auto & get()
Definition TypeList.h:860
constexpr auto size()
Definition TypeList.h:856
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:939
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:907
constexpr TupleT & tuple() const
Definition TypeList.h:858
TupleList(Ts &&... args)
Definition TypeList.h:854
constexpr auto & get() const
Definition TypeList.h:861
TypeList< Ts... > AsTypeList
Definition TypeList.h:850
A list of types (not necessarily unique)
Definition TypeList.h:576
static constexpr bool Contains
Definition TypeList.h:605
typename typelist_internal::TSRemoveImpl< Self, TypesToRemove... >::type Remove
Definition TypeList.h:667
static constexpr int64_t Index
Definition TypeList.h:621
Get< 0 > Front
Definition TypeList.h:589
Get< Size-1 > Back
Definition TypeList.h:590
typename typelist_internal::TSGetElementImpl< Self, N >::type Get
Definition TypeList.h:588
typename typelist_internal::TSRemoveIndicesImpl< Self, First, Last >::type RemoveByIndex
Definition TypeList.h:714
typename typelist_internal::TSRecurseAppendUniqueImpl< ListT, Ts... >::type Unique
Definition TypeList.h:636
typename typelist_internal::TSRemoveFirstImpl< Self >::type PopFront
Definition TypeList.h:682
TupleList< Ts... > AsTupleList
Definition TypeList.h:580
static constexpr size_t Size
Definition TypeList.h:583
static OPENVDB_FORCE_INLINE void foreachIndex(OpT op)
Definition TypeList.h:784
typename typelist_internal::TSTranformImpl< OpT, Ts... >::type Transform
Definition TypeList.h:734
static OPENVDB_FORCE_INLINE RetT foreachIndex(OpT op, RetT def)
Definition TypeList.h:789
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:829
typename typelist_internal::TSRemoveLastImpl< Self >::type PopBack
Definition TypeList.h:697
typename typelist_internal::TSAppendImpl< Self, TypesToAppend... >::type Append
Definition TypeList.h:654
TypeList Self
Definition TypeList.h:578
#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:218