/Src/Dependencies/Boost/boost/interprocess/detail/move.hpp

http://hadesmem.googlecode.com/ · C++ Header · 1157 lines · 623 code · 223 blank · 311 comment · 26 complexity · 67e45e127a10e6e967f36694b3d586ea MD5 · raw file

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright David Abrahams, Vicente Botet 2009.
  4. // (C) Copyright Ion Gaztanaga 2009-2010.
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // See http://www.boost.org/libs/move for documentation.
  10. //
  11. //////////////////////////////////////////////////////////////////////////////
  12. //! \file
  13. #ifndef BOOST_MOVE_DETAIL_MOVE_HPP
  14. #define BOOST_MOVE_DETAIL_MOVE_HPP
  15. #include <boost/config.hpp>
  16. #include <algorithm> //copy, copy_backward
  17. #include <memory> //uninitialized_copy
  18. #include <iterator> //std::iterator
  19. #include <boost/mpl/if.hpp>
  20. #include <boost/utility/enable_if.hpp>
  21. #include <boost/mpl/bool.hpp>
  22. #include <boost/type_traits/has_trivial_destructor.hpp>
  23. #include <boost/utility/addressof.hpp>
  24. //! Defining or undefining this macro will change Boost.Move behaviour
  25. //! for copyable and movable classes when assigning from non-const rvalues:
  26. //! \code
  27. //! copyable_and_movable produce(){ return copyable_and_movable(); }
  28. //! \endcode
  29. //! If the macro is NOT defined:
  30. //! \code
  31. //! copyable_and_movable cm;
  32. //! cm = copyable_and_movable(); //object is COPIED (missed optimization)
  33. //! \endcode
  34. //! If the macro IS defined:
  35. //! \code
  36. //! copyable_and_movable cm;
  37. //! cm = copyable_and_movable(); //object is MOVED
  38. //! \endcode
  39. //! However, the second option has also some downsides. See documentation for more details.
  40. #define BOOST_MOVE_OPTIMIZED_EMULATION
  41. /// @cond
  42. //Define to easily port between Boost.Move and internal Boost.Interprocess move emulation
  43. //
  44. // This configuration is temporary. Boost.Interprocess emulation uses
  45. // different macros to avoid any redefinition of a top-levl Boost macro.
  46. // It will disappear once the library is accepted and
  47. // Boost.Interprocess is updated to the standard interface.
  48. //
  49. #define BOOST_MOVE_IN_BOOST_INTERPROCESS_NAMESPACE
  50. #ifdef BOOST_MOVE_IN_BOOST_INTERPROCESS_NAMESPACE
  51. #define INTERPROCESS_NAMESPACE_BEGIN namespace interprocess {
  52. #define INTERPROCESS_NAMESPACE_END }// namespace interprocess {
  53. #define BOOST_MOVE_NAMESPACE boost::interprocess
  54. #else //BOOST_MOVE_IN_BOOST_INTERPROCESS_NAMESPACE
  55. #define INTERPROCESS_NAMESPACE_BEGIN
  56. #define INTERPROCESS_NAMESPACE_END
  57. #define BOOST_MOVE_NAMESPACE boost
  58. #endif //BOOST_MOVE_IN_BOOST_INTERPROCESS_NAMESPACE
  59. namespace boost {
  60. INTERPROCESS_NAMESPACE_BEGIN
  61. namespace move_detail {
  62. template <class T>
  63. struct identity
  64. {
  65. typedef T type;
  66. };
  67. template <class T, class U>
  68. class is_convertible
  69. {
  70. typedef char true_t;
  71. class false_t { char dummy[2]; };
  72. static true_t dispatch(U);
  73. static false_t dispatch(...);
  74. static T trigger();
  75. public:
  76. enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
  77. };
  78. } //namespace move_detail {
  79. INTERPROCESS_NAMESPACE_END
  80. } //namespace boost {
  81. /// @endcond
  82. #if !defined(BOOST_NO_RVALUE_REFERENCES)
  83. #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 5)
  84. #define BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
  85. #else
  86. #if defined(_MSC_VER) && (_MSC_VER == 1600)
  87. #define BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
  88. #endif
  89. #endif
  90. #endif
  91. #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
  92. #include <boost/type_traits/is_fundamental.hpp>
  93. #include <boost/type_traits/is_pointer.hpp>
  94. #include <boost/type_traits/is_same.hpp>
  95. #ifdef __GNUC__
  96. # define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
  97. #else
  98. # define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS
  99. #endif
  100. namespace boost {
  101. INTERPROCESS_NAMESPACE_BEGIN
  102. //////////////////////////////////////////////////////////////////////////////
  103. //
  104. // struct rv
  105. //
  106. //////////////////////////////////////////////////////////////////////////////
  107. template <class T>
  108. class rv : public T
  109. {
  110. rv();
  111. ~rv();
  112. rv(rv const&);
  113. void operator=(rv const&);
  114. } BOOST_MOVE_ATTRIBUTE_MAY_ALIAS;
  115. //////////////////////////////////////////////////////////////////////////////
  116. //
  117. // move_detail::is_rv
  118. //
  119. //////////////////////////////////////////////////////////////////////////////
  120. namespace move_detail {
  121. template <class T>
  122. struct is_rv
  123. {
  124. static const bool value = false;
  125. };
  126. template <class T>
  127. struct is_rv< rv<T> >
  128. {
  129. static const bool value = true;
  130. };
  131. } //namespace move_detail {
  132. //////////////////////////////////////////////////////////////////////////////
  133. //
  134. // is_movable
  135. //
  136. //////////////////////////////////////////////////////////////////////////////
  137. template<class T>
  138. struct is_movable
  139. : public ::boost::mpl::bool_<move_detail::is_convertible<T, rv<T>&>::value>
  140. {
  141. };
  142. template<class T>
  143. struct is_movable< rv<T> >
  144. : public ::boost::mpl::bool_<false>
  145. {
  146. };
  147. template <class T>
  148. struct has_nothrow_move
  149. : public ::boost::mpl::bool_<false>
  150. {
  151. };
  152. //////////////////////////////////////////////////////////////////////////////
  153. //
  154. // move()
  155. //
  156. //////////////////////////////////////////////////////////////////////////////
  157. template <class T>
  158. typename ::boost::disable_if<is_movable<T>, T&>::type move(T& x)
  159. {
  160. return x;
  161. }
  162. template <class T>
  163. typename enable_if<is_movable<T>, rv<T>&>::type move(T& x)
  164. {
  165. return *static_cast<rv<T>* >(boost::addressof(x));
  166. }
  167. template <class T>
  168. typename enable_if<is_movable<T>, rv<T>&>::type move(rv<T>& x)
  169. {
  170. return x;
  171. }
  172. #define BOOST_RV_REF(TYPE)\
  173. ::BOOST_MOVE_NAMESPACE::rv< TYPE >& \
  174. //
  175. #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
  176. ::BOOST_MOVE_NAMESPACE::rv< TYPE<ARG1, ARG2> >& \
  177. //
  178. #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
  179. ::BOOST_MOVE_NAMESPACE::rv< TYPE<ARG1, ARG2, ARG3> >& \
  180. //
  181. #define BOOST_FWD_REF(TYPE)\
  182. const TYPE & \
  183. //
  184. #define BOOST_CATCH_CONST_RLVALUE(TYPE)\
  185. const ::BOOST_MOVE_NAMESPACE::rv< TYPE >& \
  186. //
  187. #ifdef BOOST_MOVE_OPTIMIZED_EMULATION
  188. #define BOOST_COPY_ASSIGN_REF(TYPE)\
  189. const ::BOOST_MOVE_NAMESPACE::rv< TYPE >& \
  190. //
  191. #define BOOST_MOVE_MACRO_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
  192. const ::BOOST_MOVE_NAMESPACE::rv< TYPE<ARG1, ARG2> >& \
  193. //
  194. #define BOOST_MOVE_MACRO_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
  195. const ::BOOST_MOVE_NAMESPACE::rv< TYPE<ARG1, ARG2, ARG3> >& \
  196. //
  197. //////////////////////////////////////////////////////////////////////////////
  198. //
  199. // forward()
  200. //
  201. //////////////////////////////////////////////////////////////////////////////
  202. template <class T>
  203. typename enable_if< ::BOOST_MOVE_NAMESPACE::move_detail::is_rv<T>, T &>::type
  204. forward(const typename move_detail::identity<T>::type &x)
  205. {
  206. return const_cast<T&>(x);
  207. }
  208. template <class T>
  209. typename disable_if< ::BOOST_MOVE_NAMESPACE::move_detail::is_rv<T>, const T &>::type
  210. forward(const typename move_detail::identity<T>::type &x)
  211. {
  212. return x;
  213. }
  214. #else //BOOST_MOVE_OPTIMIZED_EMULATION
  215. #define BOOST_COPY_ASSIGN_REF(TYPE)\
  216. const TYPE & \
  217. //
  218. #define BOOST_MOVE_MACRO_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
  219. const TYPE< ARG1, ARG2 >& \
  220. //
  221. #define BOOST_MOVE_MACRO_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
  222. const TYPE< ARG1, ARG2, ARG3 > & \
  223. //
  224. //////////////////////////////////////////////////////////////////////////////
  225. //
  226. // forward()
  227. //
  228. //////////////////////////////////////////////////////////////////////////////
  229. //Catches const lvalues for movable types
  230. template <class T>
  231. const T&
  232. forward( BOOST_CATCH_CONST_RLVALUE(T) x
  233. , typename ::boost::enable_if_c< ::BOOST_MOVE_NAMESPACE::is_movable<T>::value >::type* = 0)
  234. {
  235. return static_cast<const T&>(x);
  236. }
  237. //Catches const lvalues for non-movable types
  238. template <class T>
  239. const T&
  240. forward( const T &x
  241. , typename ::boost::enable_if_c< !::BOOST_MOVE_NAMESPACE::is_movable<T>::value &&
  242. !::boost::move_detail::is_rv<T>::value
  243. >::type* = 0)
  244. {
  245. return static_cast<const T&>(x);
  246. }
  247. //Catches forwarded ::boost::rv<T> via BOOST_FWD_REFs
  248. template <class T>
  249. T &
  250. forward( const T &t
  251. , typename ::boost::enable_if_c< ::boost::move_detail::is_rv<T>::value >::type* = 0)
  252. {
  253. return const_cast<T&>(t);
  254. }
  255. //Catches forwarded ::boost::rv<T>
  256. template <class T, class U>
  257. const T &
  258. forward( const U &u
  259. , typename ::boost::enable_if_c< ::boost::is_same< ::boost::rv<T>, U >::value >::type * = 0)
  260. {
  261. return static_cast<const T&>(u);
  262. }
  263. //Catches non-const lvalues
  264. template <class T>
  265. T&
  266. forward( typename move_detail::identity<T>::type &x
  267. , typename ::boost::enable_if_c< !::boost::move_detail::is_rv<T>::value >::type* = 0)
  268. {
  269. return x;
  270. }
  271. //Catches non-const rvalues
  272. template <class T>
  273. typename enable_if<is_movable<T>, ::boost::rv<T> & >::type
  274. forward(BOOST_RV_REF(T) x)
  275. { return x; }
  276. #endif
  277. //////////////////////////////////////////////////////////////////////////////
  278. //
  279. // BOOST_MOVABLE_BUT_NOT_COPYABLE
  280. //
  281. //////////////////////////////////////////////////////////////////////////////
  282. #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
  283. private:\
  284. TYPE(TYPE &);\
  285. TYPE& operator=(TYPE &);\
  286. public:\
  287. operator ::BOOST_MOVE_NAMESPACE::rv<TYPE>&() \
  288. { return *static_cast< ::BOOST_MOVE_NAMESPACE::rv<TYPE>* >(this); }\
  289. operator const ::BOOST_MOVE_NAMESPACE::rv<TYPE>&() const \
  290. { return *static_cast<const ::BOOST_MOVE_NAMESPACE::rv<TYPE>* >(this); }\
  291. private:\
  292. //
  293. //////////////////////////////////////////////////////////////////////////////
  294. //
  295. // BOOST_COPYABLE_AND_MOVABLE
  296. //
  297. //////////////////////////////////////////////////////////////////////////////
  298. #ifdef BOOST_MOVE_OPTIMIZED_EMULATION
  299. #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
  300. public:\
  301. TYPE& operator=(TYPE &t)\
  302. { this->operator=(static_cast<const ::BOOST_MOVE_NAMESPACE::rv<TYPE> &>(const_cast<const TYPE &>(t))); return *this;}\
  303. public:\
  304. operator ::BOOST_MOVE_NAMESPACE::rv<TYPE>&() \
  305. { return *static_cast< ::BOOST_MOVE_NAMESPACE::rv<TYPE>* >(this); }\
  306. operator const ::BOOST_MOVE_NAMESPACE::rv<TYPE>&() const \
  307. { return *static_cast<const ::BOOST_MOVE_NAMESPACE::rv<TYPE>* >(this); }\
  308. private:\
  309. //
  310. #else //#ifdef BOOST_MOVE_OPTIMIZED_EMULATION
  311. #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
  312. public:\
  313. operator ::BOOST_MOVE_NAMESPACE::rv<TYPE>&() \
  314. { return *static_cast< ::BOOST_MOVE_NAMESPACE::rv<TYPE>* >(this); }\
  315. operator const ::BOOST_MOVE_NAMESPACE::rv<TYPE>&() const \
  316. { return *static_cast<const ::BOOST_MOVE_NAMESPACE::rv<TYPE>* >(this); }\
  317. private:\
  318. //
  319. #endif
  320. INTERPROCESS_NAMESPACE_END
  321. } //namespace boost
  322. #else //BOOST_NO_RVALUE_REFERENCES
  323. #include <boost/type_traits/remove_reference.hpp>
  324. namespace boost {
  325. INTERPROCESS_NAMESPACE_BEGIN
  326. /// @cond
  327. namespace move_detail {
  328. template<class T>
  329. struct is_lvalue_reference
  330. : public ::boost::mpl::bool_<false>
  331. {};
  332. template<class T>
  333. struct is_lvalue_reference<T&>
  334. : public ::boost::mpl::bool_<true>
  335. {};
  336. typedef char one;
  337. struct two {one _[2];};
  338. template <class T>
  339. struct internal_member_value_traits
  340. {
  341. template <class U> static one test(...);
  342. template <class U> static two test(typename U::boost_move_emulation_t* = 0);
  343. static const bool value = sizeof(test<T>(0)) == sizeof(two);
  344. };
  345. } //namespace move_detail {
  346. /// @endcond
  347. //////////////////////////////////////////////////////////////////////////////
  348. //
  349. // is_movable
  350. //
  351. //////////////////////////////////////////////////////////////////////////////
  352. //! For compilers with rvalue references, this traits class returns true
  353. //! if BOOST_ENABLE_MOVE_EMULATION is activated.
  354. //!
  355. //! For other compilers returns true if T is convertible to <i>::boost::rv<T>&</i>
  356. template<class T>
  357. struct is_movable
  358. : public ::boost::mpl::bool_<move_detail::internal_member_value_traits<T>::value>
  359. {
  360. };
  361. //! By default this traits returns false. Classes with non-thworing move construction
  362. //! and assignment should specialize this trait to obtain some performance improvements.
  363. template <class T>
  364. struct has_nothrow_move
  365. : public ::boost::mpl::bool_<false>
  366. {};
  367. //////////////////////////////////////////////////////////////////////////////
  368. //
  369. // move
  370. //
  371. //////////////////////////////////////////////////////////////////////////////
  372. #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
  373. //! This function provides a way to convert a reference into a rvalue reference
  374. //! in compilers with rvalue references. For other compilers converts T & into
  375. //! <i>::boost::rv<T> &</i> so that move emulation is activated.
  376. template <class T> inline
  377. rvalue_reference move (input_reference);
  378. #else //BOOST_MOVE_DOXYGEN_INVOKED
  379. #if defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
  380. //Old move approach, lvalues could bind to rvalue references
  381. template <class T> inline
  382. typename remove_reference<T>::type && move(T&& t)
  383. { return t; }
  384. #else //Old move
  385. template <class T> inline
  386. typename remove_reference<T>::type && move(T&& t)
  387. { return static_cast<typename remove_reference<T>::type &&>(t); }
  388. #endif //Old move
  389. #endif //BOOST_MOVE_DOXYGEN_INVOKED
  390. //////////////////////////////////////////////////////////////////////////////
  391. //
  392. // forward
  393. //
  394. //////////////////////////////////////////////////////////////////////////////
  395. #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
  396. //! This function provides limited form of forwarding that is usually enough for
  397. //! in-place construction and avoids the exponential overloading necessary for
  398. //! perfect forwarding in C++03.
  399. //!
  400. //! For compilers with rvalue references this function provides perfect forwarding.
  401. //!
  402. //! Otherwise:
  403. //! * If input_reference binds to const ::boost::rv<T> & then it output_reference is
  404. //! ::boost::rev<T> &
  405. //!
  406. //! * Else, input_reference is equal to output_reference is equal to input_reference.
  407. template <class T> inline output_reference forward(input_reference);
  408. #else
  409. #if defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
  410. //Old move approach, lvalues could bind to rvalue references
  411. template <class T> inline
  412. T&& forward (typename move_detail::identity<T>::type&& t)
  413. { return t; }
  414. #else //Old move
  415. //Implementation #5 from N2951, thanks to Howard Hinnant
  416. template <class T, class U>
  417. inline T&& forward(U&& t
  418. , typename enable_if_c<
  419. move_detail::is_lvalue_reference<T>::value ? move_detail::is_lvalue_reference<U>::value : true>::type * = 0/*
  420. , typename enable_if_c<
  421. move_detail::is_convertible
  422. <typename remove_reference<U>::type*, typename remove_reference<T>::type*>::value>::type * = 0*/)
  423. { return static_cast<T&&>(t); }
  424. #endif //Old move
  425. #endif //BOOST_MOVE_DOXYGEN_INVOKED
  426. //////////////////////////////////////////////////////////////////////////////
  427. //
  428. // BOOST_ENABLE_MOVE_EMULATION
  429. //
  430. //////////////////////////////////////////////////////////////////////////////
  431. ///@cond
  432. #define BOOST_ENABLE_MOVE_EMULATION(TYPE)\
  433. typedef int boost_move_emulation_t;
  434. \
  435. //
  436. /// @endcond
  437. //! This macro marks a type as movable but not copyable, disabling copy construction
  438. //! and assignment. The user will need to write a move constructor/assignment as explained
  439. //! in the documentation to fully write a movable but not copyable class.
  440. #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
  441. public:\
  442. typedef int boost_move_emulation_t;\
  443. private:\
  444. TYPE(const TYPE &);\
  445. TYPE& operator=(const TYPE &);\
  446. //
  447. //! This macro marks a type as copyable and movable.
  448. //! The user will need to write a move constructor/assignment and a copy assignment
  449. //! as explained in the documentation to fully write a copyable and movable class.
  450. #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
  451. typedef int boost_move_emulation_t;
  452. //
  453. /// @cond
  454. #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
  455. TYPE<ARG1, ARG2> && \
  456. //
  457. #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
  458. TYPE<ARG1, ARG2, ARG3> && \
  459. //
  460. /// @endcond
  461. //!This macro is used to achieve portable syntax in move
  462. //!constructors and assignments for classes marked as
  463. //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE
  464. #define BOOST_RV_REF(TYPE)\
  465. TYPE && \
  466. //
  467. //!This macro is used to achieve portable syntax in copy
  468. //!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE.
  469. #define BOOST_COPY_ASSIGN_REF(TYPE)\
  470. const TYPE & \
  471. //
  472. /// @cond
  473. #define BOOST_COPY_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
  474. const TYPE<ARG1, ARG2> & \
  475. //
  476. #define BOOST_COPY_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
  477. TYPE<ARG1, ARG2, ARG3>& \
  478. //
  479. /// @endcond
  480. //! This macro is used to implement portable perfect forwarding
  481. //! as explained in the documentation.
  482. #define BOOST_FWD_REF(TYPE)\
  483. TYPE && \
  484. //
  485. /// @cond
  486. #define BOOST_CATCH_CONST_RLVALUE(TYPE)\
  487. const TYPE & \
  488. //
  489. /// @endcond
  490. INTERPROCESS_NAMESPACE_END
  491. } //namespace boost {
  492. #endif //BOOST_NO_RVALUE_REFERENCES
  493. namespace boost {
  494. INTERPROCESS_NAMESPACE_BEGIN
  495. //////////////////////////////////////////////////////////////////////////////
  496. //
  497. // move_iterator
  498. //
  499. //////////////////////////////////////////////////////////////////////////////
  500. //! Class template move_iterator is an iterator adaptor with the same behavior
  501. //! as the underlying iterator except that its dereference operator implicitly
  502. //! converts the value returned by the underlying iterator's dereference operator
  503. //! to an rvalue reference. Some generic algorithms can be called with move
  504. //! iterators to replace copying with moving.
  505. template <class It>
  506. class move_iterator
  507. {
  508. public:
  509. typedef It iterator_type;
  510. typedef typename std::iterator_traits<iterator_type>::value_type value_type;
  511. #if !defined(BOOST_NO_RVALUE_REFERENCES) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
  512. typedef value_type && reference;
  513. #else
  514. typedef typename ::boost::mpl::if_
  515. < ::BOOST_MOVE_NAMESPACE::is_movable<value_type>
  516. , ::BOOST_MOVE_NAMESPACE::rv<value_type>&
  517. , value_type & >::type reference;
  518. #endif
  519. typedef It pointer;
  520. typedef typename std::iterator_traits<iterator_type>::difference_type difference_type;
  521. typedef typename std::iterator_traits<iterator_type>::iterator_category iterator_category;
  522. move_iterator()
  523. {}
  524. explicit move_iterator(It i)
  525. : m_it(i)
  526. {}
  527. template <class U>
  528. move_iterator(const move_iterator<U>& u)
  529. : m_it(u.base())
  530. {}
  531. iterator_type base() const
  532. { return m_it; }
  533. reference operator*() const
  534. {
  535. #if defined(BOOST_NO_RVALUE_REFERENCES) || defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
  536. return *m_it;
  537. #else
  538. return ::BOOST_MOVE_NAMESPACE::move(*m_it);
  539. #endif
  540. }
  541. pointer operator->() const
  542. { return m_it; }
  543. move_iterator& operator++()
  544. { ++m_it; return *this; }
  545. move_iterator<iterator_type> operator++(int)
  546. { move_iterator<iterator_type> tmp(*this); ++(*this); return tmp; }
  547. move_iterator& operator--()
  548. { --m_it; return *this; }
  549. move_iterator<iterator_type> operator--(int)
  550. { move_iterator<iterator_type> tmp(*this); --(*this); return tmp; }
  551. move_iterator<iterator_type> operator+ (difference_type n) const
  552. { return move_iterator<iterator_type>(m_it + n); }
  553. move_iterator& operator+=(difference_type n)
  554. { m_it += n; return *this; }
  555. move_iterator<iterator_type> operator- (difference_type n) const
  556. { return move_iterator<iterator_type>(m_it - n); }
  557. move_iterator& operator-=(difference_type n)
  558. { m_it -= n; return *this; }
  559. reference operator[](difference_type n) const
  560. {
  561. #if defined(BOOST_NO_RVALUE_REFERENCES) || defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
  562. return m_it[n];
  563. #else
  564. return ::BOOST_MOVE_NAMESPACE::move(m_it[n]);
  565. #endif
  566. }
  567. friend bool operator==(const move_iterator& x, const move_iterator& y)
  568. { return x.base() == y.base(); }
  569. friend bool operator!=(const move_iterator& x, const move_iterator& y)
  570. { return x.base() != y.base(); }
  571. friend bool operator< (const move_iterator& x, const move_iterator& y)
  572. { return x.base() < y.base(); }
  573. friend bool operator<=(const move_iterator& x, const move_iterator& y)
  574. { return x.base() <= y.base(); }
  575. friend bool operator> (const move_iterator& x, const move_iterator& y)
  576. { return x.base() > y.base(); }
  577. friend bool operator>=(const move_iterator& x, const move_iterator& y)
  578. { return x.base() >= y.base(); }
  579. friend difference_type operator-(const move_iterator& x, const move_iterator& y)
  580. { return x.base() - y.base(); }
  581. friend move_iterator operator+(difference_type n, const move_iterator& x)
  582. { return move_iterator(x.base() + n); }
  583. private:
  584. It m_it;
  585. };
  586. //is_move_iterator
  587. namespace move_detail {
  588. template <class I>
  589. struct is_move_iterator
  590. : public ::boost::mpl::bool_<false>
  591. {
  592. };
  593. template <class I>
  594. struct is_move_iterator< ::BOOST_MOVE_NAMESPACE::move_iterator<I> >
  595. : public ::boost::mpl::bool_<true>
  596. {
  597. };
  598. } //namespace move_detail {
  599. //////////////////////////////////////////////////////////////////////////////
  600. //
  601. // move_iterator
  602. //
  603. //////////////////////////////////////////////////////////////////////////////
  604. //!
  605. //! <b>Returns</b>: move_iterator<It>(i).
  606. template<class It>
  607. move_iterator<It> make_move_iterator(const It &it)
  608. { return move_iterator<It>(it); }
  609. //////////////////////////////////////////////////////////////////////////////
  610. //
  611. // back_move_insert_iterator
  612. //
  613. //////////////////////////////////////////////////////////////////////////////
  614. //! A move insert iterator that move constructs elements at the
  615. //! back of a container
  616. template <typename C> // C models Container
  617. class back_move_insert_iterator
  618. : public std::iterator<std::output_iterator_tag, void, void, void, void>
  619. {
  620. C* container_m;
  621. public:
  622. typedef C container_type;
  623. explicit back_move_insert_iterator(C& x) : container_m(&x) { }
  624. back_move_insert_iterator& operator=(typename C::reference x)
  625. { container_m->push_back(BOOST_MOVE_NAMESPACE::move(x)); return *this; }
  626. back_move_insert_iterator& operator*() { return *this; }
  627. back_move_insert_iterator& operator++() { return *this; }
  628. back_move_insert_iterator& operator++(int) { return *this; }
  629. };
  630. //!
  631. //! <b>Returns</b>: back_move_insert_iterator<C>(x).
  632. template <typename C> // C models Container
  633. inline back_move_insert_iterator<C> back_move_inserter(C& x)
  634. {
  635. return back_move_insert_iterator<C>(x);
  636. }
  637. //////////////////////////////////////////////////////////////////////////////
  638. //
  639. // front_move_insert_iterator
  640. //
  641. //////////////////////////////////////////////////////////////////////////////
  642. //! A move insert iterator that move constructs elements int the
  643. //! front of a container
  644. template <typename C> // C models Container
  645. class front_move_insert_iterator
  646. : public std::iterator<std::output_iterator_tag, void, void, void, void>
  647. {
  648. C* container_m;
  649. public:
  650. typedef C container_type;
  651. explicit front_move_insert_iterator(C& x) : container_m(&x) { }
  652. front_move_insert_iterator& operator=(typename C::reference x)
  653. { container_m->push_front(BOOST_MOVE_NAMESPACE::move(x)); return *this; }
  654. front_move_insert_iterator& operator*() { return *this; }
  655. front_move_insert_iterator& operator++() { return *this; }
  656. front_move_insert_iterator& operator++(int) { return *this; }
  657. };
  658. //!
  659. //! <b>Returns</b>: front_move_insert_iterator<C>(x).
  660. template <typename C> // C models Container
  661. inline front_move_insert_iterator<C> front_move_inserter(C& x)
  662. {
  663. return front_move_insert_iterator<C>(x);
  664. }
  665. //////////////////////////////////////////////////////////////////////////////
  666. //
  667. // insert_move_iterator
  668. //
  669. //////////////////////////////////////////////////////////////////////////////
  670. template <typename C> // C models Container
  671. class move_insert_iterator
  672. : public std::iterator<std::output_iterator_tag, void, void, void, void>
  673. {
  674. C* container_m;
  675. typename C::iterator pos_;
  676. public:
  677. typedef C container_type;
  678. explicit move_insert_iterator(C& x, typename C::iterator pos)
  679. : container_m(&x), pos_(pos)
  680. {}
  681. move_insert_iterator& operator=(typename C::reference x)
  682. {
  683. pos_ = container_m->insert(pos_, ::BOOST_MOVE_NAMESPACE::move(x));
  684. ++pos_;
  685. return *this;
  686. }
  687. move_insert_iterator& operator*() { return *this; }
  688. move_insert_iterator& operator++() { return *this; }
  689. move_insert_iterator& operator++(int) { return *this; }
  690. };
  691. //!
  692. //! <b>Returns</b>: move_insert_iterator<C>(x, it).
  693. template <typename C> // C models Container
  694. inline move_insert_iterator<C> move_inserter(C& x, typename C::iterator it)
  695. {
  696. return move_insert_iterator<C>(x, it);
  697. }
  698. //////////////////////////////////////////////////////////////////////////////
  699. //
  700. // move
  701. //
  702. //////////////////////////////////////////////////////////////////////////////
  703. //! <b>Effects</b>: Moves elements in the range [first,last) into the range [result,result + (last -
  704. //! first)) starting from first and proceeding to last. For each non-negative integer n < (last-first),
  705. //! performs *(result + n) = ::boost::move (*(first + n)).
  706. //!
  707. //! <b>Effects</b>: result + (last - first).
  708. //!
  709. //! <b>Requires</b>: result shall not be in the range [first,last).
  710. //!
  711. //! <b>Complexity</b>: Exactly last - first move assignments.
  712. template <typename I, // I models InputIterator
  713. typename O> // O models OutputIterator
  714. O move(I f, I l, O result)
  715. {
  716. while (f != l) {
  717. *result = ::BOOST_MOVE_NAMESPACE::move(*f);
  718. ++f; ++result;
  719. }
  720. return result;
  721. }
  722. //////////////////////////////////////////////////////////////////////////////
  723. //
  724. // move_backward
  725. //
  726. //////////////////////////////////////////////////////////////////////////////
  727. //! <b>Effects</b>: Moves elements in the range [first,last) into the range
  728. //! [result - (last-first),result) starting from last - 1 and proceeding to
  729. //! first. For each positive integer n <= (last - first),
  730. //! performs *(result - n) = ::boost::move(*(last - n)).
  731. //!
  732. //! <b>Requires</b>: result shall not be in the range [first,last).
  733. //!
  734. //! <b>Returns</b>: result - (last - first).
  735. //!
  736. //! <b>Complexity</b>: Exactly last - first assignments.
  737. template <typename I, // I models BidirectionalIterator
  738. typename O> // O models BidirectionalIterator
  739. O move_backward(I f, I l, O result)
  740. {
  741. while (f != l) {
  742. --l; --result;
  743. *result = ::BOOST_MOVE_NAMESPACE::move(*l);
  744. }
  745. return result;
  746. }
  747. //////////////////////////////////////////////////////////////////////////////
  748. //
  749. // uninitialized_move
  750. //
  751. //////////////////////////////////////////////////////////////////////////////
  752. //! <b>Effects</b>:
  753. //! \code
  754. //! for (; first != last; ++result, ++first)
  755. //! new (static_cast<void*>(&*result))
  756. //! typename iterator_traits<ForwardIterator>::value_type(boost::move(*first));
  757. //! \endcode
  758. //!
  759. //! <b>Returns</b>: result
  760. template
  761. <typename I, // I models InputIterator
  762. typename F> // F models ForwardIterator
  763. F uninitialized_move(I f, I l, F r
  764. /// @cond
  765. ,typename enable_if<is_movable<typename std::iterator_traits<I>::value_type> >::type* = 0
  766. /// @endcond
  767. )
  768. {
  769. typedef typename std::iterator_traits<I>::value_type input_value_type;
  770. while (f != l) {
  771. ::new(static_cast<void*>(&*r)) input_value_type(BOOST_MOVE_NAMESPACE::move(*f));
  772. ++f; ++r;
  773. }
  774. return r;
  775. }
  776. /// @cond
  777. template
  778. <typename I, // I models InputIterator
  779. typename F> // F models ForwardIterator
  780. F uninitialized_move(I f, I l, F r,
  781. typename disable_if<is_movable<typename std::iterator_traits<I>::value_type> >::type* = 0)
  782. {
  783. return std::uninitialized_copy(f, l, r);
  784. }
  785. //////////////////////////////////////////////////////////////////////////////
  786. //
  787. // uninitialized_copy_or_move
  788. //
  789. //////////////////////////////////////////////////////////////////////////////
  790. namespace move_detail {
  791. template
  792. <typename I, // I models InputIterator
  793. typename F> // F models ForwardIterator
  794. F uninitialized_move_move_iterator(I f, I l, F r,
  795. typename enable_if< is_movable<typename I::value_type> >::type* = 0)
  796. {
  797. return ::BOOST_MOVE_NAMESPACE::uninitialized_move(f, l, r);
  798. }
  799. template
  800. <typename I, // I models InputIterator
  801. typename F> // F models ForwardIterator
  802. F uninitialized_move_move_iterator(I f, I l, F r,
  803. typename disable_if< is_movable<typename I::value_type> >::type* = 0)
  804. {
  805. return std::uninitialized_copy(f.base(), l.base(), r);
  806. }
  807. } //namespace move_detail {
  808. template
  809. <typename I, // I models InputIterator
  810. typename F> // F models ForwardIterator
  811. F uninitialized_copy_or_move(I f, I l, F r,
  812. typename enable_if< move_detail::is_move_iterator<I> >::type* = 0)
  813. {
  814. return ::BOOST_MOVE_NAMESPACE::move_detail::uninitialized_move_move_iterator(f, l, r);
  815. }
  816. //////////////////////////////////////////////////////////////////////////////
  817. //
  818. // copy_or_move
  819. //
  820. //////////////////////////////////////////////////////////////////////////////
  821. namespace move_detail {
  822. template
  823. <typename I, // I models InputIterator
  824. typename F> // F models ForwardIterator
  825. F move_move_iterator(I f, I l, F r,
  826. typename enable_if< is_movable<typename I::value_type> >::type* = 0)
  827. {
  828. return ::BOOST_MOVE_NAMESPACE::move(f, l, r);
  829. }
  830. template
  831. <typename I, // I models InputIterator
  832. typename F> // F models ForwardIterator
  833. F move_move_iterator(I f, I l, F r,
  834. typename disable_if< is_movable<typename I::value_type> >::type* = 0)
  835. {
  836. return std::copy(f.base(), l.base(), r);
  837. }
  838. } //namespace move_detail {
  839. template
  840. <typename I, // I models InputIterator
  841. typename F> // F models ForwardIterator
  842. F copy_or_move(I f, I l, F r,
  843. typename enable_if< move_detail::is_move_iterator<I> >::type* = 0)
  844. {
  845. return ::BOOST_MOVE_NAMESPACE::move_detail::move_move_iterator(f, l, r);
  846. }
  847. /// @endcond
  848. //! <b>Effects</b>:
  849. //! \code
  850. //! for (; first != last; ++result, ++first)
  851. //! new (static_cast<void*>(&*result))
  852. //! typename iterator_traits<ForwardIterator>::value_type(*first);
  853. //! \endcode
  854. //!
  855. //! <b>Returns</b>: result
  856. //!
  857. //! <b>Note</b>: This function is provided because
  858. //! <i>std::uninitialized_copy</i> from some STL implementations
  859. //! is not compatible with <i>move_iterator</i>
  860. template
  861. <typename I, // I models InputIterator
  862. typename F> // F models ForwardIterator
  863. F uninitialized_copy_or_move(I f, I l, F r
  864. /// @cond
  865. ,typename disable_if< move_detail::is_move_iterator<I> >::type* = 0
  866. /// @endcond
  867. )
  868. {
  869. return std::uninitialized_copy(f, l, r);
  870. }
  871. //! <b>Effects</b>:
  872. //! \code
  873. //! for (; first != last; ++result, ++first)
  874. //! *result = *first;
  875. //! \endcode
  876. //!
  877. //! <b>Returns</b>: result
  878. //!
  879. //! <b>Note</b>: This function is provided because
  880. //! <i>std::uninitialized_copy</i> from some STL implementations
  881. //! is not compatible with <i>move_iterator</i>
  882. template
  883. <typename I, // I models InputIterator
  884. typename F> // F models ForwardIterator
  885. F copy_or_move(I f, I l, F r
  886. /// @cond
  887. ,typename disable_if< move_detail::is_move_iterator<I> >::type* = 0
  888. /// @endcond
  889. )
  890. {
  891. return std::copy(f, l, r);
  892. }
  893. //! If this trait yields to true
  894. //! (<i>has_trivial_destructor_after_move &lt;T&gt;::value == true</i>)
  895. //! means that if T is used as argument of a move construction/assignment,
  896. //! there is no need to call T's destructor.
  897. //! This optimization tipically is used to improve containers' performance.
  898. //!
  899. //! By default this trait is true if the type has trivial destructor,
  900. //! every class should specialize this trait if it wants to improve performance
  901. //! when inserted in containers.
  902. template <class T>
  903. struct has_trivial_destructor_after_move
  904. : public ::boost::has_trivial_destructor<T>
  905. {};
  906. #ifndef BOOST_MOVE_DOXYGEN_INVOKED
  907. #ifdef BOOST_MOVE_IN_BOOST_INTERPROCESS_NAMESPACE
  908. #define BOOST_INTERPROCESS_ENABLE_MOVE_EMULATION(TYPE) BOOST_ENABLE_MOVE_EMULATION(TYPE)
  909. #define BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(TYPE) BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)
  910. #define BOOST_INTERPROCESS_COPYABLE_AND_MOVABLE(TYPE) BOOST_COPYABLE_AND_MOVABLE(TYPE)
  911. #define BOOST_INTERPROCESS_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2) BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)
  912. #define BOOST_INTERPROCESS_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3) BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)
  913. #define BOOST_INTERPROCESS_RV_REF(TYPE) BOOST_RV_REF(TYPE)
  914. #define BOOST_INTERPROCESS_COPY_ASSIGN_REF(TYPE) BOOST_COPY_ASSIGN_REF(TYPE)
  915. #define BOOST_INTERPROCESS_COPY_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2) BOOST_COPY_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)
  916. #define BOOST_INTERPROCESS_COPY_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3) BOOST_COPY_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)
  917. #define BOOST_INTERPROCESS_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
  918. #define BOOST_INTERPROCESS_CATCH_CONST_RLVALUE(TYPE) BOOST_CATCH_CONST_RLVALUE(TYPE)
  919. #endif
  920. #define BOOST_MOVE_MACRO_ENABLE_MOVE_EMULATION(TYPE) BOOST_ENABLE_MOVE_EMULATION(TYPE)
  921. #define BOOST_MOVE_MACRO_MOVABLE_BUT_NOT_COPYABLE(TYPE) BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)
  922. #define BOOST_MOVE_MACRO_COPYABLE_AND_MOVABLE(TYPE) BOOST_COPYABLE_AND_MOVABLE(TYPE)
  923. #define BOOST_MOVE_MACRO_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2) BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)
  924. #define BOOST_MOVE_MACRO_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3) BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)
  925. #define BOOST_MOVE_MACRO_RV_REF(TYPE) BOOST_RV_REF(TYPE)
  926. #define BOOST_MOVE_MACRO_COPY_ASSIGN_REF(TYPE) BOOST_COPY_ASSIGN_REF(TYPE)
  927. #define BOOST_MOVE_MACRO_COPY_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2) BOOST_COPY_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)
  928. #define BOOST_MOVE_MACRO_COPY_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3) BOOST_COPY_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)
  929. #define BOOST_MOVE_MACRO_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
  930. #define BOOST_MOVE_MACRO_CATCH_CONST_RLVALUE(TYPE) BOOST_CATCH_CONST_RLVALUE(TYPE)
  931. #endif //BOOST_MOVE_DOXYGEN_INVOKED
  932. INTERPROCESS_NAMESPACE_END
  933. } //namespace boost {
  934. #endif //#ifndef BOOST_MOVE_HPP