Skip to content

Latest commit

 

History

History
107 lines (79 loc) · 2.59 KB

196.md

File metadata and controls

107 lines (79 loc) · 2.59 KB
Info

  • Did you know that Lambdas in Unevaluated Context combined with Immediately Invoked Function Expressions (IIFE) can be used to simplify Template Meta-Programming?

Example

static_assert(not std::is_same_v<decltype([]{}), decltype([]{})>);
static_assert(std::is_same_v<void, decltype([]{}())>);
static_assert(std::is_same_v<decltype([]{}()), decltype([]{}())>);

https://godbolt.org/z/cr6Y5P

Puzzle

  • Can you implement an add_pointer routine which makes the usage of decltype(IIFE) and returns a list of pointer types to: { value field if present, void otherwise }?

    • Consider applying C++20 concepts and Design by Introspection for fields detection
template<class...> struct type_list {};

template<class... Ts>
constinit auto add_pointer = type_list</*TODO*/>{};

struct foo {
  int value;
};

struct bar { };

static_assert(std::is_same_v<type_list<>, decltype(add_pointer<>)>);
static_assert(std::is_same_v<type_list<int*>, decltype(add_pointer<foo>)>);
static_assert(std::is_same_v<type_list<void*>, decltype(add_pointer<bar>)>);
static_assert(std::is_same_v<type_list<int*, void*>, decltype(add_pointer<foo, bar>)>);

https://godbolt.org/z/MKvWj9

Solutions

constexpr auto value_from = [] (auto t) {
  if constexpr (requires { t.value; }) {
    return t.value;
  }
};

template <class T>
using value_t = std::add_pointer_t<decltype(value_from(std::declval<T>()))>;

template<class... Ts>
constinit auto add_pointer = type_list<value_t<Ts>...>{};

https://godbolt.org/z/PKc9c4

template<class... Ts>
constinit auto add_pointer = type_list<decltype(
  [] {
    if constexpr (requires(Ts t) { t.value; } ) {
      return Ts{}.value;
    }
  }())*...>{};

https://godbolt.org/z/ehhxsh

template<typename T>
concept HasValue = requires(T t) { t.value; };

auto ValueOrVoidPtr = []<typename T>(const T&) {
    if constexpr (HasValue<T>)
        return (decltype(T::value)*)(nullptr);
    else
        return (void*)(nullptr);
};

template<class... Ts>
constinit auto add_pointer = type_list< decltype(ValueOrVoidPtr(Ts())) ...>{};

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

template<class... Ts>
constinit auto add_pointer = type_list<decltype([](auto v)
{
    if constexpr (requires { v.value; })
    {
        return v.value;
    }
    else
    {
        return;
    }
}(std::declval<Ts>()))*...>{};

https://godbolt.org/z/Pn8v7Y