swap_ranges.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // Copyright Neil Groves 2009. Use, modification and
  2. // distribution is subject to the Boost Software License, Version
  3. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. //
  6. //
  7. // For more information, see http://www.boost.org/libs/range/
  8. //
  9. #ifndef BOOST_RANGE_ALGORITHM_SWAP_RANGES_HPP_INCLUDED
  10. #define BOOST_RANGE_ALGORITHM_SWAP_RANGES_HPP_INCLUDED
  11. #include <boost/assert.hpp>
  12. #include <boost/concept_check.hpp>
  13. #include <boost/iterator/iterator_categories.hpp>
  14. #include <boost/range/begin.hpp>
  15. #include <boost/range/end.hpp>
  16. #include <boost/range/concepts.hpp>
  17. #include <boost/range/iterator.hpp>
  18. #include <algorithm>
  19. namespace boost
  20. {
  21. namespace range_detail
  22. {
  23. template<class Iterator1, class Iterator2>
  24. void swap_ranges_impl(Iterator1 it1, Iterator1 last1,
  25. Iterator2 it2, Iterator2 last2,
  26. single_pass_traversal_tag,
  27. single_pass_traversal_tag)
  28. {
  29. ignore_unused_variable_warning(last2);
  30. for (; it1 != last1; ++it1, ++it2)
  31. {
  32. BOOST_ASSERT( it2 != last2 );
  33. std::iter_swap(it1, it2);
  34. }
  35. }
  36. template<class Iterator1, class Iterator2>
  37. void swap_ranges_impl(Iterator1 it1, Iterator1 last1,
  38. Iterator2 it2, Iterator2 last2,
  39. random_access_traversal_tag,
  40. random_access_traversal_tag)
  41. {
  42. ignore_unused_variable_warning(last2);
  43. BOOST_ASSERT( last2 - it2 >= last1 - it1 );
  44. std::swap_ranges(it1, last1, it2);
  45. }
  46. template<class Iterator1, class Iterator2>
  47. void swap_ranges_impl(Iterator1 first1, Iterator1 last1,
  48. Iterator2 first2, Iterator2 last2)
  49. {
  50. swap_ranges_impl(first1, last1, first2, last2,
  51. BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator1>::type(),
  52. BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator2>::type());
  53. }
  54. } // namespace range_detail
  55. namespace range
  56. {
  57. /// \brief template function swap_ranges
  58. ///
  59. /// range-based version of the swap_ranges std algorithm
  60. ///
  61. /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
  62. /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
  63. template< class SinglePassRange1, class SinglePassRange2 >
  64. inline SinglePassRange2&
  65. swap_ranges(SinglePassRange1& range1, SinglePassRange2& range2)
  66. {
  67. BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange1>));
  68. BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange2>));
  69. boost::range_detail::swap_ranges_impl(
  70. boost::begin(range1), boost::end(range1),
  71. boost::begin(range2), boost::end(range2));
  72. return range2;
  73. }
  74. /// \overload
  75. template< class SinglePassRange1, class SinglePassRange2 >
  76. inline SinglePassRange2&
  77. swap_ranges(const SinglePassRange1& range1, SinglePassRange2& range2)
  78. {
  79. BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange1>));
  80. BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange2>));
  81. boost::range_detail::swap_ranges_impl(
  82. boost::begin(range1), boost::end(range1),
  83. boost::begin(range2), boost::end(range2));
  84. return range2;
  85. }
  86. /// \overload
  87. template< class SinglePassRange1, class SinglePassRange2 >
  88. inline const SinglePassRange2&
  89. swap_ranges(SinglePassRange1& range1, const SinglePassRange2& range2)
  90. {
  91. BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange1>));
  92. BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange2>));
  93. boost::range_detail::swap_ranges_impl(
  94. boost::begin(range1), boost::end(range1),
  95. boost::begin(range2), boost::end(range2));
  96. return range2;
  97. }
  98. /// \overload
  99. template< class SinglePassRange1, class SinglePassRange2 >
  100. inline const SinglePassRange2&
  101. swap_ranges(const SinglePassRange1& range1, const SinglePassRange2& range2)
  102. {
  103. BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange1>));
  104. BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const SinglePassRange2>));
  105. boost::range_detail::swap_ranges_impl(
  106. boost::begin(range1), boost::end(range1),
  107. boost::begin(range2), boost::end(range2));
  108. return range2;
  109. }
  110. } // namespace range
  111. using range::swap_ranges;
  112. } // namespace boost
  113. #endif // include guard