Manu343726
1/17/2017 - 7:46 PM

Using C++17 template deduction guides as metafunctions. See http://melpon.org/wandbox/permlink/lVFBj7shPP0fUMuQ

Using C++17 template deduction guides as metafunctions. See http://melpon.org/wandbox/permlink/lVFBj7shPP0fUMuQ

#include <iostream>
#include <string>
#include <vector>


// Basic vocabulary first:

// A function
template<typename Result>
struct Function
{
    template<typename Tag, typename... Args>
    constexpr Function(Tag, Args...) {}
    
    using type = Result;
};

// A type
template<typename T>
struct Type
{
    constexpr Type() = default;
    using type = T;  
};

template<typename T, typename U>
constexpr bool operator==(const Type<T>&, const Type<U>&)
{
    return std::is_same<T, U>::value;
}

template<typename T, typename U>
constexpr bool operator!=(const Type<T>&, const Type<U>&)
{
    return !std::is_same<T, U>::value;
}

// A type 'factory'
template<typename T>
constexpr Type<T> type = Type<T>();

// A function evaluation operation
template<typename Function>
constexpr auto eval(Function)
{
    return type<typename Function::type>;
}

// Now let's have fun:

struct AddConst {};
struct AddPointer {};

template<typename T>
Function(AddConst, Type<T>) -> Function<const T>;

template<typename T>
Function(AddPointer, Type<T>) -> Function<T*>;

constexpr auto constInt = eval(Function(AddConst(), type<int>));
constexpr auto intPtr   = eval(Function(AddPointer(), type<int>));

static_assert(type<const int> == constInt, "???");
static_assert(type<int*> == intPtr, "???");

int main()
{}