Dukales

enable_if in lambda function

Sep 30th, 2015
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.39 KB | None | 0 0
  1. #include <type_traits>
  2. #include <utility>
  3. #include <iostream>
  4.  
  5. #include <cassert>
  6. #include <cstdlib>
  7.  
  8. namespace details
  9. {
  10.  
  11. template< typename visitor, typename ...visitors >
  12. struct composite_visitor
  13.     : std::decay_t< visitor >
  14.     , composite_visitor< visitors... >
  15. {
  16.  
  17.     using std::decay_t< visitor >::operator ();
  18.     using composite_visitor< visitors... >::operator ();
  19.  
  20.     composite_visitor(visitor && _visitor, visitors &&... _visitors)
  21.         : std::decay_t< visitor >(std::forward< visitor >(_visitor))
  22.         , composite_visitor< visitors... >{std::forward< visitors >(_visitors)...}
  23.     { ; }
  24.  
  25. };
  26.  
  27. template< typename visitor >
  28. struct composite_visitor< visitor >
  29.     : std::decay_t< visitor >
  30. {
  31.  
  32.     using std::decay_t< visitor >::operator ();
  33.  
  34.     composite_visitor(visitor && _visitor)
  35.         : std::decay_t< visitor >(std::forward< visitor >(_visitor))
  36.     { ; }
  37.  
  38. };
  39.  
  40. }
  41.  
  42. template< typename visitor, typename ...visitors >
  43. details::composite_visitor< visitor, visitors... >
  44. compose_visitors(visitor && _visitor, visitors &&... _visitors)
  45. {
  46.     return {std::forward< visitor >(_visitor), std::forward< visitors >(_visitors)...};
  47. }
  48.  
  49. #define PP { std::cout << __PRETTY_FUNCTION__ << std::endl; }
  50.  
  51. struct A
  52. {
  53.     A() = default;
  54.     A(A &&) PP
  55.     A(A const &&) PP
  56.     A(A &) PP
  57.     A(A const &) PP
  58. };
  59.  
  60. int
  61. main()
  62. {
  63.     auto const l = [] (auto && arg) -> std::enable_if_t< std::is_lvalue_reference< decltype(arg) >{}, int >
  64.     {
  65.         static_assert(std::is_lvalue_reference< decltype(arg) >{});
  66.         return std::is_const< std::remove_reference_t< decltype(arg) > >{} ? 1 : 0;
  67.     };
  68.     {
  69.         A v;
  70.         A const c{};
  71.         assert(l(v) == 0);
  72.         assert(l(c) == 1);
  73.     }
  74.     auto const r = [] (auto && arg) -> std::enable_if_t< std::is_rvalue_reference< decltype(arg) >{}, int >
  75.     {
  76.         static_assert(std::is_rvalue_reference< decltype(arg) >{});
  77.         return std::is_const< std::remove_reference_t< decltype(arg) > >{} ? 3 : 2;
  78.     };
  79.     {
  80.         A v;
  81.         A const c{};
  82.         assert(r(std::move(v)) == 2);
  83.         assert(r(std::move(c)) == 3);
  84.     }
  85.     auto const lr = compose_visitors(l, r);
  86.     {
  87.         A v;
  88.         A const c{};
  89.         assert(lr(v) == 0);
  90.         assert(lr(c) == 1);
  91.         assert(lr(std::move(v)) == 2);
  92.         assert(lr(std::move(c)) == 3);
  93.     }
  94.     return EXIT_SUCCESS;
  95. }
Advertisement
Add Comment
Please, Sign In to add comment