Skip to content

Instantly share code, notes, and snippets.

@apaprocki
Created November 7, 2014 23:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apaprocki/a9b37f525825e386f261 to your computer and use it in GitHub Desktop.
Save apaprocki/a9b37f525825e386f261 to your computer and use it in GitHub Desktop.
Possible variadic template bslmf::TypeList implementation
#if defined(BSLS_COMPILERFEATURES_SUPPORT_VARIADIC_TEMPLATES)
// =========================
// struct TypeListImp_TypeOf
// =========================
template <typename T>
struct TypeListImp_TypeOfId {
using Type = T;
using TypeOrDefault = T;
};
template <int N, typename... TYPES>
struct TypeListImp_TypeOf;
template <int N, typename T, typename... TYPES>
struct TypeListImp_TypeOf<N, T, TYPES...> :
TypeListImp_TypeOf<N-1, TYPES...> { };
template <typename T, typename... TYPES>
struct TypeListImp_TypeOf<0, T, TYPES...> : TypeListImp_TypeOfId<T> { };
// =====================
// struct TypeListTypeOf
// =====================
template <int N, class LIST, class DEFAULTTYPE = Nil,
int INRANGE = ((N > 0 && N <= (int)LIST::LENGTH) ? 1 : 0)>
struct TypeListTypeOf {
// This template is specialized below to return the type the 'INDEX'th
// member of the typelist 'LIST'. If '0 > INDEX <= LIST::LENGTH' then
// 'Type' will be defined as the type of the member. Note that INDEX is
// relative to 1.
// PUBLIC TYPES
using ListType = LIST;
enum { LENGTH = ListType::LENGTH };
using TypeOrDefault = DEFAULTTYPE;
};
template <int N, class LIST, class DEFAULTTYPE>
struct TypeListTypeOf<N, LIST, DEFAULTTYPE, 1> {
using Type = typename LIST::template TypeOfRaw<N>::Type;
using TypeOrDefault = typename LIST::template TypeOfRaw<N>::TypeOrDefault;
};
#ifndef BDE_OMIT_INTERNAL_DEPRECATED
// ========================
// struct TypeListImp_TypeN
// ========================
template <int N, typename... TYPES>
struct TypeListImp_TypeN;
// Explicit named members 'Type#' are deprecated in favor of the templated
// interface so that C++11 code does not need to derive from the
// 'TypeListImp_TypeN' type in order to provide these names. Equivalent
// functionality is delivered by the 'TypeOf<N>::Type' template member.
#endif // BDE_OMIT_INTERNAL_DEPRECATED
// ===============
// struct TypeList
// ===============
template <typename... TYPES>
#ifdef BDE_OMIT_INTERNAL_DEPRECATED
struct TypeList {
#else
struct TypeList : public TypeListImp_TypeN<sizeof...(TYPES), TYPES...> {
#endif // BDE_OMIT_INTERNAL_DEPRECATED
// This template declares a typelist of N types. For each type
// specified, a corresponding type will be declared as "Type<N>" where
// where 'N' is the Nth parameter to this typelist(relative to 1).
// Additionally, the enumeration 'LENGTH' is declared with a value equal to
// the length of this typelist. Each typelist also declares a member
// template 'TypeOf' such that 'TypeOf<N>::Type' evaluates to the type of
// the Nth the in this typelist. The the type 'Type' is also declared a
// length specific version of this typelist.
typedef TypeList<TYPES...> ListType;
enum { LENGTH = sizeof...(TYPES) };
template <int N> using TypeOf = TypeListTypeOf<N, ListType>;
template <int N> using TypeOfRaw = TypeListImp_TypeOf<N-1, TYPES...>;
typedef ListType Type;
};
// Once C++11 variadic template argument support is guaranteed on all
// supported platforms, deprecate the specialized type versions because
// their only reason for existing is reduced symbol size in pre-C++11 code.
#define TypeList0 TypeList<>
#define TypeList1 TypeList
#define TypeList2 TypeList
#define TypeList3 TypeList
#define TypeList4 TypeList
#define TypeList5 TypeList
#define TypeList6 TypeList
#define TypeList7 TypeList
#define TypeList8 TypeList
#define TypeList9 TypeList
#define TypeList10 TypeList
#define TypeList11 TypeList
#define TypeList12 TypeList
#define TypeList13 TypeList
#define TypeList14 TypeList
#define TypeList15 TypeList
#define TypeList16 TypeList
#define TypeList17 TypeList
#define TypeList18 TypeList
#define TypeList19 TypeList
#define TypeList20 TypeList
#ifndef BDE_OMIT_INTERNAL_DEPRECATED
// ------------------------
// struct TypeListImp_TypeN
// ------------------------
// Explicit named members 'Type#' are deprecated in favor of the templated
// interface so that C++11 code does not need to derive from the
// 'TypeListImp_TypeN' type in order to provide these names. Equivalent
// functionality is delivered by the 'TypeOf<N>::Type' template member.
// SPECIALIZATIONS
template <typename... TYPES>
struct TypeListImp_TypeN<0, TYPES...> {
enum { Length = sizeof...(TYPES) };
};
template <typename... TYPES>
struct TypeListImp_TypeN<1, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<2, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<3, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<4, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<5, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<6, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
using Type6 = typename TypeListImp_TypeOf<5, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<7, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
using Type6 = typename TypeListImp_TypeOf<5, TYPES...>::Type;
using Type7 = typename TypeListImp_TypeOf<6, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<8, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
using Type6 = typename TypeListImp_TypeOf<5, TYPES...>::Type;
using Type7 = typename TypeListImp_TypeOf<6, TYPES...>::Type;
using Type8 = typename TypeListImp_TypeOf<7, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<9, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
using Type6 = typename TypeListImp_TypeOf<5, TYPES...>::Type;
using Type7 = typename TypeListImp_TypeOf<6, TYPES...>::Type;
using Type8 = typename TypeListImp_TypeOf<7, TYPES...>::Type;
using Type9 = typename TypeListImp_TypeOf<8, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<10, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
using Type6 = typename TypeListImp_TypeOf<5, TYPES...>::Type;
using Type7 = typename TypeListImp_TypeOf<6, TYPES...>::Type;
using Type8 = typename TypeListImp_TypeOf<7, TYPES...>::Type;
using Type9 = typename TypeListImp_TypeOf<8, TYPES...>::Type;
using Type10 = typename TypeListImp_TypeOf<9, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<11, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
using Type6 = typename TypeListImp_TypeOf<5, TYPES...>::Type;
using Type7 = typename TypeListImp_TypeOf<6, TYPES...>::Type;
using Type8 = typename TypeListImp_TypeOf<7, TYPES...>::Type;
using Type9 = typename TypeListImp_TypeOf<8, TYPES...>::Type;
using Type10 = typename TypeListImp_TypeOf<9, TYPES...>::Type;
using Type11 = typename TypeListImp_TypeOf<10, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<12, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
using Type6 = typename TypeListImp_TypeOf<5, TYPES...>::Type;
using Type7 = typename TypeListImp_TypeOf<6, TYPES...>::Type;
using Type8 = typename TypeListImp_TypeOf<7, TYPES...>::Type;
using Type9 = typename TypeListImp_TypeOf<8, TYPES...>::Type;
using Type10 = typename TypeListImp_TypeOf<9, TYPES...>::Type;
using Type11 = typename TypeListImp_TypeOf<10, TYPES...>::Type;
using Type12 = typename TypeListImp_TypeOf<11, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<13, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
using Type6 = typename TypeListImp_TypeOf<5, TYPES...>::Type;
using Type7 = typename TypeListImp_TypeOf<6, TYPES...>::Type;
using Type8 = typename TypeListImp_TypeOf<7, TYPES...>::Type;
using Type9 = typename TypeListImp_TypeOf<8, TYPES...>::Type;
using Type10 = typename TypeListImp_TypeOf<9, TYPES...>::Type;
using Type11 = typename TypeListImp_TypeOf<10, TYPES...>::Type;
using Type12 = typename TypeListImp_TypeOf<11, TYPES...>::Type;
using Type13 = typename TypeListImp_TypeOf<12, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<14, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
using Type6 = typename TypeListImp_TypeOf<5, TYPES...>::Type;
using Type7 = typename TypeListImp_TypeOf<6, TYPES...>::Type;
using Type8 = typename TypeListImp_TypeOf<7, TYPES...>::Type;
using Type9 = typename TypeListImp_TypeOf<8, TYPES...>::Type;
using Type10 = typename TypeListImp_TypeOf<9, TYPES...>::Type;
using Type11 = typename TypeListImp_TypeOf<10, TYPES...>::Type;
using Type12 = typename TypeListImp_TypeOf<11, TYPES...>::Type;
using Type13 = typename TypeListImp_TypeOf<12, TYPES...>::Type;
using Type14 = typename TypeListImp_TypeOf<13, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<15, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
using Type6 = typename TypeListImp_TypeOf<5, TYPES...>::Type;
using Type7 = typename TypeListImp_TypeOf<6, TYPES...>::Type;
using Type8 = typename TypeListImp_TypeOf<7, TYPES...>::Type;
using Type9 = typename TypeListImp_TypeOf<8, TYPES...>::Type;
using Type10 = typename TypeListImp_TypeOf<9, TYPES...>::Type;
using Type11 = typename TypeListImp_TypeOf<10, TYPES...>::Type;
using Type12 = typename TypeListImp_TypeOf<11, TYPES...>::Type;
using Type13 = typename TypeListImp_TypeOf<12, TYPES...>::Type;
using Type14 = typename TypeListImp_TypeOf<13, TYPES...>::Type;
using Type15 = typename TypeListImp_TypeOf<14, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<16, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
using Type6 = typename TypeListImp_TypeOf<5, TYPES...>::Type;
using Type7 = typename TypeListImp_TypeOf<6, TYPES...>::Type;
using Type8 = typename TypeListImp_TypeOf<7, TYPES...>::Type;
using Type9 = typename TypeListImp_TypeOf<8, TYPES...>::Type;
using Type10 = typename TypeListImp_TypeOf<9, TYPES...>::Type;
using Type11 = typename TypeListImp_TypeOf<10, TYPES...>::Type;
using Type12 = typename TypeListImp_TypeOf<11, TYPES...>::Type;
using Type13 = typename TypeListImp_TypeOf<12, TYPES...>::Type;
using Type14 = typename TypeListImp_TypeOf<13, TYPES...>::Type;
using Type15 = typename TypeListImp_TypeOf<14, TYPES...>::Type;
using Type16 = typename TypeListImp_TypeOf<15, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<17, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
using Type6 = typename TypeListImp_TypeOf<5, TYPES...>::Type;
using Type7 = typename TypeListImp_TypeOf<6, TYPES...>::Type;
using Type8 = typename TypeListImp_TypeOf<7, TYPES...>::Type;
using Type9 = typename TypeListImp_TypeOf<8, TYPES...>::Type;
using Type10 = typename TypeListImp_TypeOf<9, TYPES...>::Type;
using Type11 = typename TypeListImp_TypeOf<10, TYPES...>::Type;
using Type12 = typename TypeListImp_TypeOf<11, TYPES...>::Type;
using Type13 = typename TypeListImp_TypeOf<12, TYPES...>::Type;
using Type14 = typename TypeListImp_TypeOf<13, TYPES...>::Type;
using Type15 = typename TypeListImp_TypeOf<14, TYPES...>::Type;
using Type16 = typename TypeListImp_TypeOf<15, TYPES...>::Type;
using Type17 = typename TypeListImp_TypeOf<16, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<18, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
using Type6 = typename TypeListImp_TypeOf<5, TYPES...>::Type;
using Type7 = typename TypeListImp_TypeOf<6, TYPES...>::Type;
using Type8 = typename TypeListImp_TypeOf<7, TYPES...>::Type;
using Type9 = typename TypeListImp_TypeOf<8, TYPES...>::Type;
using Type10 = typename TypeListImp_TypeOf<9, TYPES...>::Type;
using Type11 = typename TypeListImp_TypeOf<10, TYPES...>::Type;
using Type12 = typename TypeListImp_TypeOf<11, TYPES...>::Type;
using Type13 = typename TypeListImp_TypeOf<12, TYPES...>::Type;
using Type14 = typename TypeListImp_TypeOf<13, TYPES...>::Type;
using Type15 = typename TypeListImp_TypeOf<14, TYPES...>::Type;
using Type16 = typename TypeListImp_TypeOf<15, TYPES...>::Type;
using Type17 = typename TypeListImp_TypeOf<16, TYPES...>::Type;
using Type18 = typename TypeListImp_TypeOf<17, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<19, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
using Type6 = typename TypeListImp_TypeOf<5, TYPES...>::Type;
using Type7 = typename TypeListImp_TypeOf<6, TYPES...>::Type;
using Type8 = typename TypeListImp_TypeOf<7, TYPES...>::Type;
using Type9 = typename TypeListImp_TypeOf<8, TYPES...>::Type;
using Type10 = typename TypeListImp_TypeOf<9, TYPES...>::Type;
using Type11 = typename TypeListImp_TypeOf<10, TYPES...>::Type;
using Type12 = typename TypeListImp_TypeOf<11, TYPES...>::Type;
using Type13 = typename TypeListImp_TypeOf<12, TYPES...>::Type;
using Type14 = typename TypeListImp_TypeOf<13, TYPES...>::Type;
using Type15 = typename TypeListImp_TypeOf<14, TYPES...>::Type;
using Type16 = typename TypeListImp_TypeOf<15, TYPES...>::Type;
using Type17 = typename TypeListImp_TypeOf<16, TYPES...>::Type;
using Type18 = typename TypeListImp_TypeOf<17, TYPES...>::Type;
using Type19 = typename TypeListImp_TypeOf<18, TYPES...>::Type;
};
template <typename... TYPES>
struct TypeListImp_TypeN<20, TYPES...> {
using Type1 = typename TypeListImp_TypeOf<0, TYPES...>::Type;
using Type2 = typename TypeListImp_TypeOf<1, TYPES...>::Type;
using Type3 = typename TypeListImp_TypeOf<2, TYPES...>::Type;
using Type4 = typename TypeListImp_TypeOf<3, TYPES...>::Type;
using Type5 = typename TypeListImp_TypeOf<4, TYPES...>::Type;
using Type6 = typename TypeListImp_TypeOf<5, TYPES...>::Type;
using Type7 = typename TypeListImp_TypeOf<6, TYPES...>::Type;
using Type8 = typename TypeListImp_TypeOf<7, TYPES...>::Type;
using Type9 = typename TypeListImp_TypeOf<8, TYPES...>::Type;
using Type10 = typename TypeListImp_TypeOf<9, TYPES...>::Type;
using Type11 = typename TypeListImp_TypeOf<10, TYPES...>::Type;
using Type12 = typename TypeListImp_TypeOf<11, TYPES...>::Type;
using Type13 = typename TypeListImp_TypeOf<12, TYPES...>::Type;
using Type14 = typename TypeListImp_TypeOf<13, TYPES...>::Type;
using Type15 = typename TypeListImp_TypeOf<14, TYPES...>::Type;
using Type16 = typename TypeListImp_TypeOf<15, TYPES...>::Type;
using Type17 = typename TypeListImp_TypeOf<16, TYPES...>::Type;
using Type18 = typename TypeListImp_TypeOf<17, TYPES...>::Type;
using Type19 = typename TypeListImp_TypeOf<18, TYPES...>::Type;
using Type20 = typename TypeListImp_TypeOf<19, TYPES...>::Type;
};
#endif // BDE_OMIT_INTERNAL_DEPRECATED
#endif // BSLS_COMPILERFEATURES_SUPPORT_VARIADIC_TEMPLATES
@apaprocki
Copy link
Author

@mversche Can you take a look at this? This compiles cleanly and the test driver passes. I can explain parts of it if it isn't apparent what is going on. I want to deprecate the explicit ::Type# way of accessing the types in favor of ::TypeOf<#>::Type. If that was done then the last 300 lines of the file would eventually go away and the implementation would be < 100 lines.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment