1 #ifndef BOOST_THREAD_QUEUE_ADAPTOR_HPP 2 #define BOOST_THREAD_QUEUE_ADAPTOR_HPP 3 4 ////////////////////////////////////////////////////////////////////////////// 5 // 6 // (C) Copyright Vicente J. Botet Escriba 2014. Distributed under the Boost 7 // Software License, Version 1.0. (See accompanying file 8 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 // 10 // See http://www.boost.org/libs/thread for documentation. 11 // 12 ////////////////////////////////////////////////////////////////////////////// 13 14 #include <boost/thread/detail/config.hpp> 15 #include <boost/thread/detail/move.hpp> 16 #include <boost/thread/concurrent_queues/queue_op_status.hpp> 17 #include <boost/thread/concurrent_queues/queue_base.hpp> 18 19 #include <boost/config/abi_prefix.hpp> 20 21 namespace boost 22 { 23 namespace concurrent 24 { 25 namespace detail 26 { 27 28 template <typename Queue> 29 class queue_adaptor_copyable_only : 30 public boost::queue_base<typename Queue::value_type, typename Queue::size_type> 31 { 32 Queue queue; 33 public: 34 typedef typename Queue::value_type value_type; 35 typedef typename Queue::size_type size_type; 36 37 // Constructors/Assignment/Destructors queue_adaptor_copyable_only()38 queue_adaptor_copyable_only() {} 39 40 // Observers empty() const41 bool empty() const { return queue.empty(); } full() const42 bool full() const { return queue.full(); } size() const43 size_type size() const { return queue.size(); } closed() const44 bool closed() const { return queue.closed(); } 45 46 // Modifiers close()47 void close() { queue.close(); } 48 push(const value_type & x)49 void push(const value_type& x) { queue.push(x); } 50 pull(value_type & x)51 void pull(value_type& x) { queue.pull(x); }; pull()52 value_type pull() { return queue.pull(); } 53 try_push(const value_type & x)54 queue_op_status try_push(const value_type& x) { return queue.try_push(x); } try_pull(value_type & x)55 queue_op_status try_pull(value_type& x) { return queue.try_pull(x); } 56 nonblocking_push(const value_type & x)57 queue_op_status nonblocking_push(const value_type& x) { return queue.nonblocking_push(x); } nonblocking_pull(value_type & x)58 queue_op_status nonblocking_pull(value_type& x) { return queue.nonblocking_pull(x); } 59 wait_push(const value_type & x)60 queue_op_status wait_push(const value_type& x) { return queue.wait_push(x); } wait_pull(value_type & x)61 queue_op_status wait_pull(value_type& x) { return queue.wait_pull(x); } 62 63 }; 64 template <typename Queue> 65 class queue_adaptor_movable_only : 66 public boost::queue_base<typename Queue::value_type, typename Queue::size_type> 67 { 68 Queue queue; 69 public: 70 typedef typename Queue::value_type value_type; 71 typedef typename Queue::size_type size_type; 72 73 // Constructors/Assignment/Destructors 74 queue_adaptor_movable_only()75 queue_adaptor_movable_only() {} 76 77 // Observers empty() const78 bool empty() const { return queue.empty(); } full() const79 bool full() const { return queue.full(); } size() const80 size_type size() const { return queue.size(); } closed() const81 bool closed() const { return queue.closed(); } 82 83 // Modifiers close()84 void close() { queue.close(); } 85 86 pull(value_type & x)87 void pull(value_type& x) { queue.pull(x); }; 88 // enable_if is_nothrow_copy_movable<value_type> pull()89 value_type pull() { return queue.pull(); } 90 try_pull(value_type & x)91 queue_op_status try_pull(value_type& x) { return queue.try_pull(x); } 92 nonblocking_pull(value_type & x)93 queue_op_status nonblocking_pull(value_type& x) { return queue.nonblocking_pull(x); } 94 wait_pull(value_type & x)95 queue_op_status wait_pull(value_type& x) { return queue.wait_pull(x); } 96 push(BOOST_THREAD_RV_REF (value_type)x)97 void push(BOOST_THREAD_RV_REF(value_type) x) { queue.push(boost::move(x)); } try_push(BOOST_THREAD_RV_REF (value_type)x)98 queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push(boost::move(x)); } nonblocking_push(BOOST_THREAD_RV_REF (value_type)x)99 queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push(boost::move(x)); } wait_push(BOOST_THREAD_RV_REF (value_type)x)100 queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push(boost::move(x)); } 101 }; 102 103 template <typename Queue> 104 class queue_adaptor_copyable_and_movable : 105 public boost::queue_base<typename Queue::value_type, typename Queue::size_type> 106 { 107 Queue queue; 108 public: 109 typedef typename Queue::value_type value_type; 110 typedef typename Queue::size_type size_type; 111 112 // Constructors/Assignment/Destructors 113 queue_adaptor_copyable_and_movable()114 queue_adaptor_copyable_and_movable() {} 115 116 // Observers empty() const117 bool empty() const { return queue.empty(); } full() const118 bool full() const { return queue.full(); } size() const119 size_type size() const { return queue.size(); } closed() const120 bool closed() const { return queue.closed(); } 121 122 // Modifiers close()123 void close() { queue.close(); } 124 125 push(const value_type & x)126 void push(const value_type& x) { queue.push(x); } 127 pull(value_type & x)128 void pull(value_type& x) { queue.pull(x); }; 129 // enable_if is_nothrow_copy_movable<value_type> pull()130 value_type pull() { return queue.pull(); } 131 try_push(const value_type & x)132 queue_op_status try_push(const value_type& x) { return queue.try_push(x); } try_pull(value_type & x)133 queue_op_status try_pull(value_type& x) { return queue.try_pull(x); } 134 nonblocking_push(const value_type & x)135 queue_op_status nonblocking_push(const value_type& x) { return queue.nonblocking_push(x); } nonblocking_pull(value_type & x)136 queue_op_status nonblocking_pull(value_type& x) { return queue.nonblocking_pull(x); } 137 wait_push(const value_type & x)138 queue_op_status wait_push(const value_type& x) { return queue.wait_push(x); } wait_pull(value_type & x)139 queue_op_status wait_pull(value_type& x) { return queue.wait_pull(x); } 140 push(BOOST_THREAD_RV_REF (value_type)x)141 void push(BOOST_THREAD_RV_REF(value_type) x) { queue.push(boost::move(x)); } try_push(BOOST_THREAD_RV_REF (value_type)x)142 queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.try_push(boost::move(x)); } nonblocking_push(BOOST_THREAD_RV_REF (value_type)x)143 queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.nonblocking_push(boost::move(x)); } wait_push(BOOST_THREAD_RV_REF (value_type)x)144 queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue.wait_push(boost::move(x)); } 145 }; 146 147 148 template <class Q, class T, 149 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES 150 #if defined __GNUC__ && ! defined __clang__ 151 #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) || !defined(__GXX_EXPERIMENTAL_CXX0X__) 152 bool Copyable = is_copy_constructible<T>::value, 153 bool Movable = true 154 #else 155 bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value, 156 bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value 157 #endif // __GNUC__ 158 #elif defined _MSC_VER 159 #if _MSC_VER < 1700 160 bool Copyable = is_copy_constructible<T>::value, 161 bool Movable = true 162 #else 163 bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value, 164 bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value 165 #endif // _MSC_VER 166 #else 167 bool Copyable = std::is_copy_constructible<T>::value && std::is_copy_assignable<T>::value, 168 bool Movable = std::is_move_constructible<T>::value && std::is_move_assignable<T>::value 169 #endif 170 #else 171 bool Copyable = is_copy_constructible<T>::value, 172 bool Movable = has_move_emulation_enabled<T>::value 173 #endif 174 > 175 struct queue_adaptor; 176 177 template <class Q, class T> 178 struct queue_adaptor<Q, T, true, true> { 179 typedef queue_adaptor_copyable_and_movable<Q> type; 180 }; 181 template <class Q, class T> 182 struct queue_adaptor<Q, T, true, false> { 183 typedef queue_adaptor_copyable_only<Q> type; 184 }; 185 template <class Q, class T> 186 struct queue_adaptor<Q, T, false, true> { 187 typedef queue_adaptor_movable_only<Q> type; 188 }; 189 190 } 191 192 template <typename Queue> 193 class queue_adaptor : 194 public detail::queue_adaptor<Queue, typename Queue::value_type>::type 195 { 196 public: 197 typedef typename Queue::value_type value_type; 198 typedef typename Queue::size_type size_type; 199 // Constructors/Assignment/Destructors ~queue_adaptor()200 virtual ~queue_adaptor() {}; 201 }; 202 } 203 using concurrent::queue_adaptor; 204 205 } 206 207 #include <boost/config/abi_suffix.hpp> 208 209 #endif 210