Skip to content

Latest commit

 

History

History
138 lines (104 loc) · 2.91 KB

290.md

File metadata and controls

138 lines (104 loc) · 2.91 KB
Info

Example

static_assert(typeid([]{}) != typeid([]{}));

template<auto = []{}>
struct foo{};

foo f1, f2;
static_assert(typeid(f1) != typeid(f2));

https://godbolt.org/z/Wrhfqba69

Puzzle

  • Can you implement create which creates given type as a unique type or same type?

    • Note: For type uniqueness inheritance might be used
class same;
class unique;

template<class...>
[[nodiscard]] constexpr auto create(); // TODO

struct foo {};
static_assert(typeid(create<foo>()) == typeid(create<foo>()));
static_assert(typeid(create<foo, class unique>()) != typeid(create<foo, class unique>()));

https://godbolt.org/z/YKKej87dE

Solutions

template <typename T, auto UniqueTag>
struct wrap_unique: T {};

template<class T, typename UniqueOrSame = class same, auto UniqueTag = []{}>
[[nodiscard]] constexpr std::convertible_to<T> auto create()
{
    if constexpr (std::same_as<UniqueOrSame, class unique>) {
        return wrap_unique<T, UniqueTag>{};
    } else {
        return T{};
    }
}

https://godbolt.org/z/j5xvPzd47

template <class T, auto = []{}>
struct uniquify : T {};

template <class T, class C = same, class U = uniquify<T>>
[[nodiscard]] constexpr auto create()
  -> std::conditional_t<std::same_as<C, unique>, U, T>;

https://godbolt.org/z/s6o7E4Kj6

template <class T, auto>
struct uniquify : T {};

template <class T, class U = same, auto V = [] {}>
[[nodiscard]] constexpr auto create() {
  if constexpr (std::same_as<U, unique>) {
    return uniquify<T, V>{};
  } else {
    return T{};
  }
}

https://godbolt.org/z/K8q3KdGbx

template<class T, class U = same, auto UniqueLambda = []{}>
[[nodiscard]] constexpr auto create() {
    if constexpr (std::is_same_v<U, unique>) {
        return UniqueLambda;
    }
}

https://godbolt.org/z/nTb5h5x4o

template <class first, class second = same, auto = [] {}>
[[nodiscard]] constexpr auto create() {
  if constexpr (std::is_same_v<second, same>) {
    return first{};
  } else {
    return [] {};
  }
}

https://godbolt.org/z/Msodn95Tf

template<class Tp, auto = []{}>
class Holder : Tp {};

template<class Tp, class Option = same, class Held = Holder<Tp> >
[[nodiscard]] constexpr auto create() {
    if constexpr (std::is_same_v<Option, same>)
        return Tp{};
    else
        return Held{};
}

https://godbolt.org/z/r8jcWz5ee

template <class T, auto = []{}>
class diff : T{};

template<class T, class U = same, class V = diff<T>>
[[nodiscard]] constexpr auto create(){
    if constexpr(std::is_same_v<U, unique>){
        return V{};
    }
}

https://godbolt.org/z/47Wc8r5js