Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
188 lines (136 sloc) 4.96 KB
#pragma once
namespace hfsm2 {
namespace detail {
////////////////////////////////////////////////////////////////////////////////
template <typename... Ts>
struct TL_ {
static constexpr LongIndex SIZE = sizeof...(Ts);
};
//------------------------------------------------------------------------------
template <typename...>
struct PrependT;
template <typename T, typename... Ts>
struct PrependT<T, TL_<Ts...>> {
using Type = TL_<T, Ts...>;
};
template <typename... Ts>
using Prepend = typename PrependT<Ts...>::Type;
//------------------------------------------------------------------------------
template <LongIndex, LongIndex, typename...>
struct LesserT;
template <LongIndex H, LongIndex I, typename TFirst, typename... TRest>
struct LesserT<H, I, TFirst, TRest...> {
using Type = typename std::conditional<(I < H),
Prepend<TFirst, typename LesserT<H, I + 1, TRest...>::Type>,
typename LesserT<H, I + 1, TRest...>::Type>::type;
};
template <LongIndex H, LongIndex I>
struct LesserT<H, I> {
using Type = TL_<>;
};
template <typename... Ts>
using SplitL = typename LesserT<sizeof...(Ts) / 2, 0, Ts...>::Type;
//------------------------------------------------------------------------------
template <LongIndex, LongIndex, typename...>
struct GreaterT;
template <LongIndex H, LongIndex I, typename TFirst, typename... TRest>
struct GreaterT<H, I, TFirst, TRest...> {
using Type = typename std::conditional<(I < H),
typename GreaterT<H, I + 1, TRest...>::Type,
TL_<TFirst, TRest...>>::type;
};
template <LongIndex H, LongIndex I>
struct GreaterT<H, I> {
using Type = TL_<>;
};
template <typename... Ts>
using SplitR = typename GreaterT<sizeof...(Ts) / 2, 0, Ts...>::Type;
////////////////////////////////////////////////////////////////////////////////
template<LongIndex N>
struct IndexConstant {};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<LongIndex... Ns>
struct IndexSequence {
using Type = IndexSequence<Ns...>;
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<typename, typename>
struct MakeIndexSequence_Impl {};
template<LongIndex N, LongIndex... Ns>
struct MakeIndexSequence_Impl<IndexConstant<N>,
IndexSequence<Ns...>>
: MakeIndexSequence_Impl<IndexConstant<N - 1>,
IndexSequence<N - 1, Ns...>>
{};
template<LongIndex... Ns>
struct MakeIndexSequence_Impl<IndexConstant<0>,
IndexSequence<Ns...>>
: IndexSequence<Ns...>
{};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<LongIndex N>
using MakeIndexSequence = typename MakeIndexSequence_Impl<IndexConstant<N>,
IndexSequence<>>::Type;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<class... Ts>
using IndexSequenceFor = MakeIndexSequence<sizeof...(Ts)>;
////////////////////////////////////////////////////////////////////////////////
template <typename T>
struct IndexedTypeList_EntryT {};
template <typename T, LongIndex N>
struct IndexedTypeList_EntryN
: IndexedTypeList_EntryT<T>
{};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template <typename...>
struct IndexedTypeList_Impl;
template <LongIndex... Ns, typename... Ts>
struct IndexedTypeList_Impl<IndexSequence<Ns...>, Ts...>
: IndexedTypeList_EntryN<Ts, Ns>...
{
template <typename T, LongIndex N>
static constexpr LongIndex select(IndexedTypeList_EntryN<T, N>) { return (LongIndex) N; }
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template <typename... Ts>
struct ITL_
: private IndexedTypeList_Impl<IndexSequenceFor<Ts...>, Ts...>
{
using Base = IndexedTypeList_Impl<IndexSequenceFor<Ts...>, Ts...>;
static constexpr LongIndex SIZE = sizeof...(Ts);
template <typename T>
static constexpr bool contains() { return std::is_base_of<IndexedTypeList_EntryT<T>, ITL_>::value; }
template <typename T>
static constexpr
typename std::enable_if< std::is_base_of<IndexedTypeList_EntryT<T>, ITL_>::value, LongIndex>::type
index() {
return Base::template select<T>(ITL_{});
}
template <typename T>
static constexpr
typename std::enable_if<!std::is_base_of<IndexedTypeList_EntryT<T>, ITL_>::value, LongIndex>::type
index() {
return INVALID_LONG_INDEX;
}
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template <typename...>
struct IndexedT;
template <typename... Ts>
struct IndexedT<TL_<Ts...>> {
using Type = ITL_<Ts...>;
};
template <typename T>
using Indexed = typename IndexedT<T>::Type;
//------------------------------------------------------------------------------
template <typename...>
struct MergeT;
template <typename... Ts1, typename... Ts2>
struct MergeT<TL_<Ts1...>, TL_<Ts2...>> {
using TypeList = TL_<Ts1..., Ts2...>;
};
template <typename... Ts>
using Merge = typename MergeT<Ts...>::TypeList;
////////////////////////////////////////////////////////////////////////////////
}
}
You can’t perform that action at this time.