Dukales

make container consumable if possible

Dec 3rd, 2014
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.11 KB | None | 0 0
  1. #include <utility>
  2. #include <iterator>
  3. #include <type_traits>
  4.  
  5. template< typename container, bool = std::is_const< std::remove_reference_t< container > >::value >
  6. struct consumable_container;
  7.  
  8. template< typename container >
  9. struct consumable_container< container, false >
  10. {
  11.    
  12.     consumable_container(container && _container) noexcept
  13.         : container_(std::forward< container >(_container))
  14.     { ; }
  15.    
  16.     auto
  17.     begin() noexcept
  18.     {
  19.         return std::make_move_iterator(std::begin(container_));
  20.     }
  21.    
  22.     auto
  23.     end() noexcept
  24.     {
  25.         return std::make_move_iterator(std::end(container_));
  26.     }
  27.    
  28. private :
  29.  
  30.     container container_;
  31.    
  32. };
  33.  
  34. template< typename container >
  35. struct consumable_container< container, true >
  36. {
  37.    
  38.     static_assert(!std::is_rvalue_reference< container >::value);
  39.    
  40.     consumable_container(container && _container) noexcept
  41.         : container_(std::forward< container >(_container))
  42.     { ; }
  43.    
  44.     auto
  45.     begin() const noexcept
  46.     {
  47.         return std::cbegin(container_);
  48.     }
  49.    
  50.     auto
  51.     end() const noexcept
  52.     {
  53.         return std::cend(container_);
  54.     }
  55.    
  56. private :
  57.  
  58.     container container_;
  59.    
  60. };
  61.  
  62. template< typename container >
  63. consumable_container< container >
  64. move_if_not_const(container && _container) noexcept
  65. {
  66.     return std::forward< container >(_container);
  67. }
  68.  
  69. #include <list>
  70.  
  71. template< typename container >
  72. auto
  73. transform_to_list(container && _container) noexcept
  74. {
  75.     static_assert(std::is_reference< container >::value || !std::is_const< container >::value);
  76.     std::list< typename std::remove_reference_t< container >::value_type > list_;
  77.     for (auto && value_ : move_if_not_const(std::forward< container >(_container))) {
  78.         list_.push_back(std::forward< decltype(value_) >(value_));
  79.     }
  80.     return list_;
  81. }
  82.  
  83. #include <iostream>
  84.  
  85. struct A
  86. {
  87.    
  88.     A() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
  89.     ~A() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
  90.    
  91.     A(A const &) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
  92.     A(A &) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
  93.     A(A &&) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
  94.    
  95.     A & operator = (A const &) { std::cout << __PRETTY_FUNCTION__ << std::endl; return *this; }
  96.     A & operator = (A &) { std::cout << __PRETTY_FUNCTION__ << std::endl; return *this; }
  97.     A & operator = (A &&) { std::cout << __PRETTY_FUNCTION__ << std::endl; return *this; }
  98.    
  99. };
  100.  
  101. #include <deque>
  102. #include <forward_list>
  103. #include <vector>
  104.  
  105. #include <cstdlib>
  106.  
  107. int
  108. main()
  109. {
  110.     {
  111.         std::deque< A > const deque_(1);
  112.         std::list< A > ld_ = transform_to_list(deque_);
  113.     }
  114.     std::cout << std::endl;
  115.     {
  116.         std::forward_list< A > forward_list_;
  117.         forward_list_.push_front(A{});
  118.         std::list< A > ls_ = transform_to_list(forward_list_);
  119.     }
  120.     std::cout << std::endl;
  121.     {
  122.         std::vector< A > vector_;
  123.         vector_.push_back(A{});
  124.         std::list< A > lv_ = transform_to_list(std::move(vector_));
  125.     }
  126.     return EXIT_SUCCESS;
  127. }
Advertisement
Add Comment
Please, Sign In to add comment