[go: up one dir, main page]

Skip to content

Latest commit

 

History

History
186 lines (141 loc) · 5.11 KB

335.md

File metadata and controls

186 lines (141 loc) · 5.11 KB
Info

Example

template <class T1, class T2>
[[nodiscard]] constexpr auto operator==(const T1&, const T2&) { return std::is_same_v<T1, T2>; }

template <class... Ts>
constexpr auto list = mp11::mp_list<Ts...>{};

static_assert(list<> == list<>);
static_assert(list<int> == list<int>);
static_assert(list<int, double> == list<int, double>);

https://godbolt.org/z/fTMsK8Moh

Puzzle

  • Can you implement DSL for boost.mp11
struct event {};
class foo1 : event {};
class foo2 : event { int i; };
class bar1 {};
class bar2 { int i; };

template<class... Ts>
constexpr auto unique_event_ptrs =
    list<Ts...>
  | unique
  | filter<is_base_of<event>>
  | transform<add_pointer>
  ;

static_assert(unique_event_ptrs<> == list<>);
static_assert(unique_event_ptrs<foo1> == list<foo1*>);
static_assert(unique_event_ptrs<foo1, foo1> == list<foo1*>);
static_assert(unique_event_ptrs<bar1> == list<>);
static_assert(unique_event_ptrs<bar1, bar1> == list<>);
static_assert(unique_event_ptrs<bar2, bar1> == list<>);
static_assert(unique_event_ptrs<foo2, foo1> == list<foo2*, foo1*>);
static_assert(unique_event_ptrs<foo1, foo2> == list<foo1*, foo2*>);
static_assert(unique_event_ptrs<foo1, foo2, foo2> == list<foo1*, foo2*>);
static_assert(unique_event_ptrs<foo1, foo1, foo2, foo2> == list<foo1*, foo2*>);
static_assert(unique_event_ptrs<foo1, foo2, foo1, foo2> == list<foo1*, foo2*>);
static_assert(unique_event_ptrs<foo1, bar1, foo1, foo2> == list<foo1*, foo2*>);
static_assert(unique_event_ptrs<foo1, bar1, foo1, foo2> == list<foo1*, foo2*>);
static_assert(unique_event_ptrs<foo1, bar1, foo1, foo1, bar1, bar2> == list<foo1*>);

https://godbolt.org/z/rjh6hhK6j

Solutions

template <class... Ts>
constexpr auto list = mp11::mp_list<Ts...>{};

struct unique {
} unique;
template <template <typename...> class List, typename... Ts>
constexpr auto operator|(const List<Ts...> &, struct unique)
    -> mp11::mp_unique<List<Ts...>> {
    return {};
};

template <typename F>
struct filter_t {};
template <typename F>
constexpr auto filter = filter_t<F>{};

template <class B>
struct is_base_of {
    template <class D>
    using fn = std::is_base_of<B, D>;
};

template <typename F, template <typename...> class List, typename... Ts>
constexpr auto operator|(const List<Ts...> &, const filter_t<F> &)
    -> mp11::mp_filter_q<F, List<Ts...>> {
    return {};
};

template <typename F>
struct transform_t {};
template <typename F>
constexpr auto transform = transform_t<F>{};

struct add_pointer {
    template <class T>
    using fn = T *;
};

template <typename F, template <typename...> class List, typename... Ts>
constexpr auto operator|(const List<Ts...> &, const transform_t<F> &)
    -> mp11::mp_transform_q<F, List<Ts...>> {
    return {};
};

template <class T1, class T2>
constexpr auto operator==(const T1 &, const T2 &) {
    return std::is_same_v<T1, T2>;
}

https://godbolt.org/z/rKc6rdfee

#include <boost/mp11.hpp>

using namespace boost::mp11;

template<class T1, class T2>
[[nodiscard]] constexpr auto operator==(const T1 &, const T2 &) { return std::is_same_v<T1, T2>; }

template<class T, class Q>
[[nodiscard]] constexpr auto operator|(const T &, const Q &) { return mp_invoke_q<Q, T>{}; }

template<class... Ts>
constexpr auto list = mp_list<Ts...>{};

constexpr mp_quote<mp_unique> unique;

template <class T>
using is_base_of = mp_bind_front<std::is_base_of, T>;

using add_pointer = mp_quote_trait<std::add_pointer>;

template<class Q>
constexpr mp_bind_front<mp_filter_q, Q> filter;

template<class Q>
constexpr mp_bind_front<mp_transform_q, Q> transform;


struct event {
};

class foo1 : event {
};

class foo2 : event {
    int i;
};

class bar1 {
};

class bar2 {
    int i;
};

template<class... Ts>
constexpr auto unique_event_ptrs =
        list<Ts...> | unique | filter<is_base_of<event>> | transform<add_pointer>;

static_assert(unique_event_ptrs<> == list<>);
static_assert(unique_event_ptrs<foo1> == list<foo1*>);
static_assert(unique_event_ptrs<foo1, foo1> == list<foo1*>);
static_assert(unique_event_ptrs<bar1> == list<>);
static_assert(unique_event_ptrs<bar1, bar1> == list<>);
static_assert(unique_event_ptrs<bar2, bar1> == list<>);
static_assert(unique_event_ptrs<foo2, foo1> == list<foo2*, foo1*>);
static_assert(unique_event_ptrs<foo1, foo2> == list<foo1*, foo2*>);
static_assert(unique_event_ptrs<foo1, foo2, foo2> == list<foo1*, foo2*>);
static_assert(unique_event_ptrs<foo1, foo1, foo2, foo2> == list<foo1*, foo2*>);
static_assert(unique_event_ptrs<foo1, foo2, foo1, foo2> == list<foo1*, foo2*>);
static_assert(unique_event_ptrs<foo1, bar1, foo1, foo2> == list<foo1*, foo2*>);
static_assert(unique_event_ptrs<foo1, bar1, foo1, foo2> == list<foo1*, foo2*>);
static_assert(unique_event_ptrs<foo1, bar1, foo1, foo1, bar1, bar2> ==
              list<foo1*>);

https://godbolt.org/z/1bf3noEhG