reverse.hpp 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Eric Niebler 2013-present
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. //
  13. #ifndef RANGES_V3_ALGORITHM_REVERSE_HPP
  14. #define RANGES_V3_ALGORITHM_REVERSE_HPP
  15. #include <range/v3/range_fwd.hpp>
  16. #include <range/v3/iterator/concepts.hpp>
  17. #include <range/v3/iterator/operations.hpp>
  18. #include <range/v3/iterator/traits.hpp>
  19. #include <range/v3/range/access.hpp>
  20. #include <range/v3/range/concepts.hpp>
  21. #include <range/v3/range/dangling.hpp>
  22. #include <range/v3/range/traits.hpp>
  23. #include <range/v3/utility/static_const.hpp>
  24. #include <range/v3/utility/swap.hpp>
  25. #include <range/v3/detail/prologue.hpp>
  26. namespace ranges
  27. {
  28. /// \addtogroup group-algorithms
  29. /// @{
  30. /// \cond
  31. namespace detail
  32. {
  33. template<typename I>
  34. constexpr void reverse_impl(I first, I last, std::bidirectional_iterator_tag)
  35. {
  36. while(first != last)
  37. {
  38. if(first == --last)
  39. break;
  40. ranges::iter_swap(first, last);
  41. ++first;
  42. }
  43. }
  44. template<typename I>
  45. constexpr void reverse_impl(I first, I last, std::random_access_iterator_tag)
  46. {
  47. if(first != last)
  48. for(; first < --last; ++first)
  49. ranges::iter_swap(first, last);
  50. }
  51. } // namespace detail
  52. /// \endcond
  53. RANGES_FUNC_BEGIN(reverse)
  54. /// \brief function template \c reverse
  55. template(typename I, typename S)(
  56. requires bidirectional_iterator<I> AND sentinel_for<S, I> AND permutable<I>)
  57. constexpr I RANGES_FUNC(reverse)(I first, S end_)
  58. {
  59. I last = ranges::next(first, end_);
  60. detail::reverse_impl(first, last, iterator_tag_of<I>{});
  61. return last;
  62. }
  63. /// \overload
  64. template(typename Rng, typename I = iterator_t<Rng>)(
  65. requires bidirectional_range<Rng> AND permutable<I>)
  66. constexpr borrowed_iterator_t<Rng> RANGES_FUNC(reverse)(Rng && rng) //
  67. {
  68. return (*this)(begin(rng), end(rng));
  69. }
  70. RANGES_FUNC_END(reverse)
  71. namespace cpp20
  72. {
  73. using ranges::reverse;
  74. }
  75. /// @}
  76. } // namespace ranges
  77. #include <range/v3/detail/epilogue.hpp>
  78. #endif