You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
4.5KB

  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Eric Niebler 2014-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. // Copyright (c) 2009 Alexander Stepanov and Paul McJones
  14. //
  15. // Permission to use, copy, modify, distribute and sell this software
  16. // and its documentation for any purpose is hereby granted without
  17. // fee, provided that the above copyright notice appear in all copies
  18. // and that both that copyright notice and this permission notice
  19. // appear in supporting documentation. The authors make no
  20. // representations about the suitability of this software for any
  21. // purpose. It is provided "as is" without express or implied
  22. // warranty.
  23. //
  24. // Algorithms from
  25. // Elements of Programming
  26. // by Alexander Stepanov and Paul McJones
  27. // Addison-Wesley Professional, 2009
  28. #ifndef RANGES_V3_ALGORITHM_MERGE_HPP
  29. #define RANGES_V3_ALGORITHM_MERGE_HPP
  30. #include <tuple>
  31. #include <range/v3/range_fwd.hpp>
  32. #include <range/v3/algorithm/copy.hpp>
  33. #include <range/v3/algorithm/result_types.hpp>
  34. #include <range/v3/functional/comparisons.hpp>
  35. #include <range/v3/functional/identity.hpp>
  36. #include <range/v3/functional/invoke.hpp>
  37. #include <range/v3/iterator/traits.hpp>
  38. #include <range/v3/range/access.hpp>
  39. #include <range/v3/range/concepts.hpp>
  40. #include <range/v3/range/dangling.hpp>
  41. #include <range/v3/range/traits.hpp>
  42. #include <range/v3/utility/static_const.hpp>
  43. namespace ranges
  44. {
  45. /// \addtogroup group-algorithms
  46. /// @{
  47. template<typename I0, typename I1, typename O>
  48. using merge_result = detail::in1_in2_out_result<I0, I1, O>;
  49. RANGES_BEGIN_NIEBLOID(merge)
  50. /// \brief function template \c merge
  51. template<typename I0,
  52. typename S0,
  53. typename I1,
  54. typename S1,
  55. typename O,
  56. typename C = less,
  57. typename P0 = identity,
  58. typename P1 = identity>
  59. auto RANGES_FUN_NIEBLOID(merge)(I0 begin0,
  60. S0 end0,
  61. I1 begin1,
  62. S1 end1,
  63. O out,
  64. C pred = C{},
  65. P0 proj0 = P0{},
  66. P1 proj1 = P1{}) //
  67. ->CPP_ret(merge_result<I0, I1, O>)( //
  68. requires sentinel_for<S0, I0> && sentinel_for<S1, I1> &&
  69. mergeable<I0, I1, O, C, P0, P1>)
  70. {
  71. for(; begin0 != end0 && begin1 != end1; ++out)
  72. {
  73. if(invoke(pred, invoke(proj1, *begin1), invoke(proj0, *begin0)))
  74. {
  75. *out = *begin1;
  76. ++begin1;
  77. }
  78. else
  79. {
  80. *out = *begin0;
  81. ++begin0;
  82. }
  83. }
  84. auto t0 = ranges::copy(begin0, end0, out);
  85. auto t1 = ranges::copy(begin1, end1, t0.out);
  86. return {t0.in, t1.in, t1.out};
  87. }
  88. /// \overload
  89. template<typename Rng0,
  90. typename Rng1,
  91. typename O,
  92. typename C = less,
  93. typename P0 = identity,
  94. typename P1 = identity>
  95. auto RANGES_FUN_NIEBLOID(merge)(Rng0 && rng0,
  96. Rng1 && rng1,
  97. O out,
  98. C pred = C{},
  99. P0 proj0 = P0{},
  100. P1 proj1 = P1{})
  101. ->CPP_ret(merge_result<safe_iterator_t<Rng0>, safe_iterator_t<Rng1>, O>)( //
  102. requires range<Rng0> && range<Rng1> &&
  103. mergeable<iterator_t<Rng0>, iterator_t<Rng1>, O, C, P0, P1>)
  104. {
  105. return (*this)(begin(rng0),
  106. end(rng0),
  107. begin(rng1),
  108. end(rng1),
  109. std::move(out),
  110. std::move(pred),
  111. std::move(proj0),
  112. std::move(proj1));
  113. }
  114. RANGES_END_NIEBLOID(merge)
  115. namespace cpp20
  116. {
  117. using ranges::merge;
  118. using ranges::merge_result;
  119. } // namespace cpp20
  120. /// @}
  121. } // namespace ranges
  122. #endif // include guard