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>,
268 typename TSEraseImpl<TypeList<Ts...>, T>::type>::type;
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...> {
291 using type =
typename TSRemoveImpl<typename TSEraseImpl<ListT, T>::type, Ts...>::type;
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...>>
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);
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);
590 using Get =
typename typelist_internal::TSGetElementImpl<Self, N>::type;
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>
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);
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
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>
982 #endif // OPENVDB_TYPELIST_HAS_BEEN_INCLUDED 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
Get< Size-1 > Back
Definition: TypeList.h:592
constexpr RetT evalFirstPred(Pred, OpT, RetT def)
Definition: TypeList.h:972
static OPENVDB_FORCE_INLINE void foreachIndex(OpT op)
Definition: TypeList.h:786
constexpr TupleT & tuple()
Definition: TypeList.h:859
A list of types (not necessarily unique)
Definition: TypeList.h:577
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
typename typelist_internal::TSAppendImpl< Self, TypesToAppend... >::type Append
Append types, or the members of another TypeList, to this list.
Definition: TypeList.h:656
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
const TupleT & tuple() const
Definition: TypeList.h:964
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
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
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::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
A trivial wrapper around a std::tuple but with compatible TypeList methods. Importantly can be instat...
Definition: TypeList.h:850
Get< 0 > Front
Definition: TypeList.h:591
constexpr TupleT & tuple() const
Definition: TypeList.h:860
#define OPENVDB_TYPELIST_FORCE_INLINE
Definition: TypeList.h:31
constexpr auto size()
Definition: TypeList.h:962
Definition: Exceptions.h:13
TupleT & tuple()
Definition: TypeList.h:963
Index32 Index
Definition: Types.h:54
std::tuple<> TupleT
Definition: TypeList.h:958
TupleList(Ts &&...args)
Definition: TypeList.h:856
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
std::tuple< Ts... > TupleT
Definition: TypeList.h:853
constexpr auto size()
Definition: TypeList.h:858
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
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
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
constexpr void evalFirstPred(Pred, OpT)
Definition: TypeList.h:970
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
static OPENVDB_FORCE_INLINE RetT foreachIndex(OpT op, RetT def)
Definition: TypeList.h:791
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:212