Skip to content

Instantly share code, notes, and snippets.

@vczh
Last active March 28, 2024 07:22
Show Gist options
  • Save vczh/e06334bb12c54a8281ea1e0935a02ce3 to your computer and use it in GitHub Desktop.
Save vczh/e06334bb12c54a8281ea1e0935a02ce3 to your computer and use it in GitHub Desktop.
TypeListOp.cpp
#include <variant>
#include <type_traits>
// =================================================================
template<typename ...TArgs>
struct WhateverTypes
{
template<typename TOp>
auto operator |(TOp op)
{
return op.Apply(*this);
}
template<template<typename ...UArgs> class T>
using As = T<TArgs...>;
};
// =================================================================
template<typename T>
struct AppendOp
{
template<typename ...TArgs>
auto Apply(WhateverTypes<TArgs...>) -> WhateverTypes<TArgs..., T> { return {}; }
};
template<typename T>
AppendOp<T> append() { return {}; }
// =================================================================
struct ReverseOp
{
auto Apply(WhateverTypes<> ts) { return ts; }
template<typename T>
auto Apply(WhateverTypes<T> ts) { return ts; }
template<typename T, typename ...TArgs>
auto Apply(WhateverTypes<T, TArgs...>)
{
return WhateverTypes<TArgs...>{} | *this | append<T>();
}
};
inline ReverseOp reverse() { return {}; }
// =================================================================
template<int N>
struct Drop
{
template<typename ...TArgs>
auto Apply(WhateverTypes<TArgs...> ts)
{
return ts | drop<1>() | drop<N - 1>();
}
};
template<>
struct Drop<1>
{
template<typename T, typename ...TArgs>
auto Apply(WhateverTypes<T, TArgs...> ts) -> WhateverTypes<TArgs...> { return {}; }
};
template<>
struct Drop<0>
{
template<typename ...TArgs>
auto Apply(WhateverTypes<TArgs...> ts) { return ts; }
};
template<int N>
Drop<N> drop() { return {}; }
// =================================================================
template<typename T>
struct Whatever;
template<template<typename...> class T, typename ...TArgs>
struct Whatever<T<TArgs...>>
{
using Extract = WhateverTypes<TArgs...>;
};
// =================================================================
using namespace std;
int main()
{
static_assert(is_same_v<
decltype(Whatever<variant<int, double, float>>::Extract{} | reverse() | drop<1>())::As<variant>,
variant<double, int>
>);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment