C++
CMake
c++ source #1
Output
Compile to binary object
Link to binary
Execute the code
Intel asm syntax
Demangle identifiers
Filters
Unused labels
Library functions
Directives
Comments
Horizontal whitespace
Debug intrinsics
Compiler
CPP Meta
Clang
Options
Source code
#include <variant> using namespace std::meta; consteval void variant_proxy_interface(class_builder& b, class_decl interface); template <class Interface, class... Elements> class variant_proxy : public std::variant<Elements...> { public : using std::variant<Elements...>::operator=; %variant_proxy_interface(^Interface); }; template <std::meta::identifier id, class... Args> constexpr auto dispatcher(Args&&... args) { return [&args...] (auto&& obj) -> decltype(auto) { return %make_call_expr( ^(obj), id, expr_list{^(args)...} ); }; } consteval void variant_proxy_interface(class_builder& b, class_decl interface) { for (auto m : methods(interface)) { method_prototype mp; for (auto p : inner_parameters(m)) append_parameter(mp, identifier_of(p), type_of(p)); auto obj = remove_reference(object_type(m)); auto new_obj = make_lvalue_reference( make_const(decl_of(b), is_const(obj)) ); object_type(mp, new_obj); return_type(mp, return_type(m)); if (is_constexpr(m)) set_constexpr(mp); else if (is_consteval(m)) set_consteval(mp); append_method( b, name_of(m), mp, [m] (method_builder& b) { expr_list args; for (auto p : inner_parameters(decl_of(b))) push_back(args, make_decl_ref_expr(p)); auto vis = make_call_expr(^dispatcher, template_arguments{identifier_of(m)}, args); auto obj = make_deref_expr(make_this_expr(b)); auto res = make_call_expr(^std::visit, expr_list{vis, obj}); append_return(b, res); }); } } // Tests #include <string> struct Interface { constexpr std::size_t hash() const; constexpr std::string dump() const; }; struct A { constexpr std::size_t hash() const { return 1; } constexpr std::string dump() const { return "A"; } }; struct B { constexpr std::size_t hash() const { return 2; } constexpr std::string dump() const { return "B"; } }; // libcxx is not up to date online at the moment of writing, // so we don't have constexpr variant #include <cassert> void test() { variant_proxy<Interface, A, B> s { A{} }; assert( s.hash() == 1 ); assert( s.dump() == "A" ); s.emplace<B>(); assert( s.hash() == 2 ); assert( s.dump() == "B" ); } int main() { test(); }
Become a Patron
Sponsor on GitHub
Donate via PayPal
Source on GitHub
Mailing list
Installed libraries
Wiki
Report an issue
How it works
Contact the author
CE on Mastodon
About the author
Statistics
Changelog
Version tree