Skip to content

Commit

Permalink
use tlists
Browse files Browse the repository at this point in the history
  • Loading branch information
multun committed Jul 9, 2018
1 parent 308906a commit 9f4ce28
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 127 deletions.
88 changes: 37 additions & 51 deletions auto.hh
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,21 @@

template<template<class> class PInterface,
template<class> class ...States>
class BaseAuto {
protected:
using base_auto_t = BaseAuto<PInterface, States...>;
using raw_tlist = TTList<States...>;
using Interface = PInterface<base_auto_t>;
class Auto {
using self_t = Auto<PInterface, States...>;
using intf_t = PInterface<self_t>;
using ttlist = TTList<States...>;

template<template<class> class State>
struct auto_t_mapper {
using type = State<base_auto_t>;
struct Automaker {
using type = State<self_t>;
};

using unsafe_tlist = decltype(raw_tlist::template Tmap<auto_t_mapper>());
using tlist = decltype(ttlist::template Tmap<Automaker>());

struct StateData {
alignas(unsafe_tlist::template reduce<AlignofReducer>()())
uint8_t state_data_[unsafe_tlist::template reduce<SizeofReducer>()()];
alignas(tlist::template reduce<AlignofReducer>()())
uint8_t state_data_[tlist::template reduce<SizeofReducer>()()];

template<class T>
T* get_data() {
Expand All @@ -37,14 +36,14 @@ protected:
template<template <class> class State, class ...Args>
auto enter(Args&& ...args) {
// TODO: move this assert at class construction time
static_assert(std::is_base_of<Interface, State<base_auto_t>>::value);
static_assert(map_pack_contains<base_auto_t, State, States...>());
return new (&state_data_) State<base_auto_t>(std::forward(args)...);
static_assert(std::is_base_of<intf_t, State<self_t>>::value);
// static_assert(map_pack_contains<self_t, State, States...>());
return new (&state_data_) State<self_t>(std::forward(args)...);
}

void leave() {
// The destructor must be virtual
get_data<Interface>()->~Interface();
get_data<intf_t>()->~intf_t();
}
};

Expand All @@ -59,57 +58,44 @@ protected:
return data_[!data_pos_];
}

template<template<class> class NewState, class ...Args>
void enter(Args&& ...args) {
other_data().template enter<NewState, args...>(
std::forward<Args>(args)...);
cur_data().leave();
data_pos_ = !data_pos_;
}

public:
auto &get_state() {
return *cur_data().template get_data<Interface>();
return *cur_data().template get_data<intf_t>();
}

BaseAuto() : data_pos_(0) {}
Auto() : data_pos_(0) {}

~BaseAuto() {
~Auto() {
cur_data().leave();
}

template<template<class> class InitialState, class ...Args>
void initialize(Args&& ...args) {
cur_data().template enter<InitialState, args...>(std::forward<Args>(args)...);
cur_data().template enter<InitialState, args...>(
std::forward<Args>(args)...);
}
};

template<template<class> class PInterface,
template<class> class ...States>
struct Auto : public BaseAuto<PInterface, States...> {
using base_auto_t = BaseAuto<PInterface, States...>;
using auto_t = Auto<PInterface, States...>;

template<template<class> class State>
struct AutoProxy : base_auto_t {
template<template<class> class NewState, class ...Args>
void enter(Args&& ...args) {
static_assert(auto_t::template check_transition<State, NewState>());
base_auto_t::template enter<NewState, Args...>(
std::forward<Args>(args)...);
}
};

template<template<class> class State>
struct StateMapper {
using type = State<auto_t::AutoProxy<State>>;
};

using tlist = decltype(base_auto_t::raw_tlist::template Tmap<StateMapper>());
template<template<class> class NewState, class ...Args>
void enter(Args&& ...args) {
other_data().template enter<NewState, args...>(
std::forward<Args>(args)...);
cur_data().leave();
data_pos_ = !data_pos_;
}

template<template<class> class Source, template<class> class Dest>
static bool constexpr check_transition() {
return true;
template<template<class> class NewState,
template<class> class OldState,
class ...Args>
void free_transit(Args&& ...args) {
// TODO: validate former state
enter<NewState, Args...>(std::forward<Args>(args)...);
}

template<template<class> class NewState,
template<class> class OldState,
class ...Args>
void transit(OldState<self_t> *st, Args&& ...args) {
free_transit<NewState, OldState, Args...>(std::forward<Args>(args)...);
}
};
4 changes: 2 additions & 2 deletions test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ struct ExInterface {


template<class Auto>
struct StateA : ExInterface<Auto::common> {
struct StateA : ExInterface<Auto> {
virtual void callback(Auto &a) override {
std::cout << "1" << std::endl;
}
};


template<class Auto>
struct StateB : ExInterface<Auto::common> {
struct StateB : ExInterface<Auto> {
virtual void callback(Auto &a) override {
std::cout << "B, entering 1" << std::endl;
a.template enter<StateA>();
Expand Down
26 changes: 13 additions & 13 deletions test_tlist.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
#include "type_utils.hxx"


template<class T>
struct SizeofReducer {
constexpr auto operator()() {
return sizeof(T);
}
// 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>{};
}
};
// 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>()();
Expand Down
22 changes: 22 additions & 0 deletions tlist.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,28 @@ struct TNAME {
return TNAME<Elems..., T>{};
}

// // maps can only produce TLists, couldn't make it output a TTList
// template<MYCLASS Key>
// struct contains_c {
// template<MYCLASS First, MYCLASS Second, MYCLASS ...More>
// static constexpr auto contains() {
// if constexpr (static_type_eq<Key, First>())
// return true;
// else
// return constains_c<Key>::template contains<Second, More...>();
// }

// template<MYCLASS Elem>
// static constexpr auto contains() {
// return static_type_eq<Key, Elem>()
// }
// };

// template<MYCLASS Key>
// static constexpr auto contains() {
// return contains_c<Key>::template contains<Elems...>();
// }

// maps can only produce TLists, couldn't make it output a TTList
template<template <MYCLASS> class F>
struct Tmapper {
Expand Down
83 changes: 22 additions & 61 deletions type_utils.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,46 @@
#include <stddef.h>


template<typename T, typename U>
template<template<class> class T, template<class> class U>
struct static_ttype_test
{
static const bool eq = false;
};


template<template<class> class T>
struct static_ttype_test<T, T>
{
static const bool eq = true;
};

template<class T, class U>
struct static_type_test
{
static const bool eq = false;
};


template<typename T>
template<class T>
struct static_type_test<T, T>
{
static const bool eq = true;
};


// tests whether two types are equal

template<typename T, typename U>
template<class T, class U>
constexpr bool static_type_eq()
{
return static_type_test<T, U>::eq;
}

template<template<class> class T, template<class> class U>
constexpr bool static_type_eq()
{
return static_ttype_test<T, U>::eq;
}


// counts the number of parameters of the template

Expand Down Expand Up @@ -60,63 +78,6 @@ constexpr size_t type_index()
return 0;
}


template <class T>
struct AlignofMap {
constexpr size_t operator()() {
return alignof(T);
}
};

template <class T>
struct SizeofMap {
constexpr size_t operator()() {
return sizeof(T);
}
};


// not really elegant, could be replaced by a map / reduce
// on a parameter pack object

template <class TArg, template <class> class f,
template<class> class Arg>
constexpr auto max_map_pack() {
return f<Arg<TArg>>()();
}

template <class TArg, template <class> class f,
template<class> class Arg,
template<class> class NArg,
template<class> class ...Args>
constexpr auto max_map_pack() {
auto prev = max_map_pack<TArg, f, NArg, Args...>();
auto cur = f<Arg<TArg>>()();
if (cur > prev)
return cur;
return prev;
}


template <class TParm,
template<class> class Elem,
template<class> class HList>
constexpr bool map_pack_contains() {
return static_type_eq<Elem<TParm>, HList<TParm>>();
}

template <class TParm,
template<class> class Elem,
template<class> class HList,
template<class> class HHList,
template<class> class ...Rest>
constexpr bool map_pack_contains() {
if (static_type_eq<Elem<TParm>, HList<TParm>>())
return true;
else
return map_pack_contains<TParm, Elem, HHList, Rest...>();
}

template<class ...Elems>
struct TList;

Expand Down

0 comments on commit 9f4ce28

Please sign in to comment.