Skip to content

Commit

Permalink
tlist: implement
Browse files Browse the repository at this point in the history
  • Loading branch information
multun committed Jul 9, 2018
1 parent e684c61 commit f71e818
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 0 deletions.
31 changes: 31 additions & 0 deletions test_tlist.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <cstddef>
#include <iostream>
#include "type_utils.hxx"


template<class T>
struct SizeofReducer {
constexpr auto operator()() {
return sizeof(T);
}

template<class NT>
constexpr auto feed() {
if constexpr (sizeof(NT) > sizeof(T))
return SizeofReducer<NT>{};
else
return SizeofReducer<T>{};
}
};

using size_list = TList<char, int, long long>;
constexpr size_t max_size = size_list::template reduce<SizeofReducer>()();

int main() {
using my_list = TList<char, int>;

static_assert(static_type_eq<my_list,
decltype(my_list::template apply<TList>())>());

std::cout << max_size << std::endl;
}
74 changes: 74 additions & 0 deletions tlist.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include <cstddef>

#define MYCLASS MYTEMPL class

template<MYCLASS ...Elems>
struct TNAME {
using type = TNAME<Elems...>;

template<template<MYCLASS...> class Templ, MYCLASS ...Args>
struct TParam {
using type = Templ<Args...>;
};

template<template<MYCLASS...> class Templ>
static constexpr auto apply() {
return typename TParam<Templ, Elems...>::type{};
}

template<MYCLASS T>
static constexpr auto push_front() {
return TNAME<T, Elems...>{};
}

// unit helps working around syntaxical limitations
// where templated types need guiding. Good luck writting the stop
// case of the map function without a similar trick
template<MYCLASS T>
static constexpr auto unit() {
return TNAME<T>{};
}

template<MYCLASS T>
static constexpr auto push_back() {
return TNAME<Elems..., T>{};
}

template<template <MYCLASS> class F>
struct mapper {
template<MYCLASS First, MYCLASS Second, MYCLASS ...More>
static constexpr auto map() {
auto tail = mapper<F>::template map<Second, More...>();
return tail.template push_front<F<First>::type>();
}

template<MYCLASS Elem>
static constexpr auto map() {
return unit<F<Elem>::type>();
}
};

template<template <MYCLASS> class F>
static constexpr auto map() {
return mapper<F>::template map<Elems...>();
}

template<template<MYCLASS> class Reducer>
struct reducer {
template<MYCLASS First, MYCLASS Second, MYCLASS ...More>
static constexpr auto reduce() {
auto tail = reducer<Reducer>::template reduce<Second, More...>();
return tail.template feed<First>();
}

template<MYCLASS Elem>
static constexpr auto reduce() {
return Reducer<Elem>{};
}
};

template<template<MYCLASS> class Reducer>
static constexpr auto reduce() {
return reducer<Reducer>::template reduce<Elems...>();
}
};
13 changes: 13 additions & 0 deletions type_utils.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,16 @@ constexpr bool map_pack_contains() {
else
return map_pack_contains<TParm, Elem, HHList, Rest...>();
}


#define MYTEMPL
#define TNAME TList
#include "tlist.hxx"
#undef TNAME
#undef MYTEMPL

#define MYTEMPL template<class>
#define TNAME TTList
#include "tlist.hxx"
#undef TNAME
#undef MYTEMPL

0 comments on commit f71e818

Please sign in to comment.