Last active
March 28, 2024 07:22
-
-
Save vczh/e06334bb12c54a8281ea1e0935a02ce3 to your computer and use it in GitHub Desktop.
TypeListOp.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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