Skip to content

Latest commit

 

History

History
131 lines (95 loc) · 3.91 KB

285.md

File metadata and controls

131 lines (95 loc) · 3.91 KB
Info

Example

template<class T> concept fooable = requires(T t) { t.foo; };
template<class T> concept barable = requires(T t) { t.bar; };

template<class T> constexpr auto foobar = "unknown"sv;
template<fooable T> constexpr auto foobar<T> = "foo"sv;
template<barable T> constexpr auto foobar<T> = "bar"sv;

struct none {};
static_assert("unknown"sv == foobar<none>);
struct f { int foo; };
static_assert("foo"sv == foobar<f>);
struct b { int bar; };
static_assert("bar"sv == foobar<b>);

https://godbolt.org/z/r3ro915Gv

Puzzle

  • Can you implement foobars specialization which is { complete : when its passed with fooable/barable type list, in-complete : otherwise}?
template<class T> concept fooable = requires(T t) { t.foo; };
template<class T> concept barable = requires(T t) { t.bar; };

template<class...> struct foobars; // TODO

struct none {};
struct f { int foo; };
struct b { int bar; };

template<class T>
concept is_complete = requires { sizeof(T); };

static_assert(not is_complete<foobars<std::tuple<none>, std::tuple<>>>);
static_assert(not is_complete<foobars<std::tuple<none>, std::tuple<none>>>);
static_assert(not is_complete<foobars<std::tuple<b>, std::tuple<>>>);
static_assert(not is_complete<foobars<std::tuple<>, std::tuple<f>>>);
static_assert(not is_complete<foobars<std::tuple<f, b>, std::tuple<b>>>);
static_assert(not is_complete<foobars<std::tuple<f, f, f>, std::tuple<b, f, b>>>);

static_assert(is_complete<foobars<std::tuple<>, std::tuple<>>>);
static_assert(is_complete<foobars<std::tuple<f>, std::tuple<>>>);
static_assert(is_complete<foobars<std::tuple<f>, std::tuple<b>>>);
static_assert(is_complete<foobars<std::tuple<f, f>, std::tuple<b>>>);
static_assert(is_complete<foobars<std::tuple<f, f, f>, std::tuple<b, b>>>);
static_assert(is_complete<foobars<boost::mp11::mp_list<>, boost::mp11::mp_list<b>>>);
static_assert(is_complete<foobars<boost::mp11::mp_list<f>, boost::mp11::mp_list<b>>>);
static_assert(is_complete<foobars<boost::mp11::mp_list<f, f, f>, boost::mp11::mp_list<b, b>>>);

https://godbolt.org/z/dzM13WTa3

Solutions

template<class...> struct foobars;
template<template <typename...> typename FTL, template <typename ...> typename BTL,
         fooable... Fs, barable... Bs>
struct foobars<FTL<Fs...>, BTL<Bs...>> {};

https://godbolt.org/z/M9E9ozjT8

template <template <typename...> typename TFooables,
          template <typename...> typename TBarables,
          fooable... Fooables,
          barable... Barables>
struct foobars<TFooables<Fooables...>, TBarables<Barables...>> {};

https://godbolt.org/z/7fMK6zazz

template <typename, typename>
struct foobars;

template <template <typename...> class TContainer, fooable... TFoos,
          barable... TBars>
struct foobars<TContainer<TFoos...>, TContainer<TBars...>> {};

https://godbolt.org/z/9dWE6MEec

template<class...> struct foobars;

template <template <class...> class TList, fooable... Ts, barable... Us>
struct foobars<TList<Ts...>, TList<Us...>> {};

https://godbolt.org/z/fjY7eP6T1

template<class...> struct foobars;

template <template <class...> class List, fooable... Ts, barable... Us>
struct foobars<List<Ts...>, List<Us...>> {};

https://godbolt.org/z/EYMWd5vcE

template<class...> struct foobars;

template<template <class...> class TList,
  fooable... TFoos, barable... TBars>
struct foobars<TList<TFoos...>, TList<TBars...>> {};

https://godbolt.org/z/ns7M1KMPd

template<class...> struct foobars;
template<template<typename...> typename C, fooable... fs, barable... bs>
struct foobars<C<fs...>, C<bs...>> {};

https://godbolt.org/z/jcGqv3nW3