Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <type_traits>
- #include <utility>
- #include <iostream>
- #include <cassert>
- #include <cstdlib>
- namespace details
- {
- template< typename visitor, typename ...visitors >
- struct composite_visitor
- : std::decay_t< visitor >
- , composite_visitor< visitors... >
- {
- using std::decay_t< visitor >::operator ();
- using composite_visitor< visitors... >::operator ();
- composite_visitor(visitor && _visitor, visitors &&... _visitors)
- : std::decay_t< visitor >(std::forward< visitor >(_visitor))
- , composite_visitor< visitors... >{std::forward< visitors >(_visitors)...}
- { ; }
- };
- template< typename visitor >
- struct composite_visitor< visitor >
- : std::decay_t< visitor >
- {
- using std::decay_t< visitor >::operator ();
- composite_visitor(visitor && _visitor)
- : std::decay_t< visitor >(std::forward< visitor >(_visitor))
- { ; }
- };
- }
- template< typename visitor, typename ...visitors >
- details::composite_visitor< visitor, visitors... >
- compose_visitors(visitor && _visitor, visitors &&... _visitors)
- {
- return {std::forward< visitor >(_visitor), std::forward< visitors >(_visitors)...};
- }
- #define PP { std::cout << __PRETTY_FUNCTION__ << std::endl; }
- struct A
- {
- A() = default;
- A(A &&) PP
- A(A const &&) PP
- A(A &) PP
- A(A const &) PP
- };
- int
- main()
- {
- auto const l = [] (auto && arg) -> std::enable_if_t< std::is_lvalue_reference< decltype(arg) >{}, int >
- {
- static_assert(std::is_lvalue_reference< decltype(arg) >{});
- return std::is_const< std::remove_reference_t< decltype(arg) > >{} ? 1 : 0;
- };
- {
- A v;
- A const c{};
- assert(l(v) == 0);
- assert(l(c) == 1);
- }
- auto const r = [] (auto && arg) -> std::enable_if_t< std::is_rvalue_reference< decltype(arg) >{}, int >
- {
- static_assert(std::is_rvalue_reference< decltype(arg) >{});
- return std::is_const< std::remove_reference_t< decltype(arg) > >{} ? 3 : 2;
- };
- {
- A v;
- A const c{};
- assert(r(std::move(v)) == 2);
- assert(r(std::move(c)) == 3);
- }
- auto const lr = compose_visitors(l, r);
- {
- A v;
- A const c{};
- assert(lr(v) == 0);
- assert(lr(c) == 1);
- assert(lr(std::move(v)) == 2);
- assert(lr(std::move(c)) == 3);
- }
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment