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.

108 lines
3.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. #ifndef RANGES_V3_ALGORITHM_PARTITION_COPY_HPP
  14. #define RANGES_V3_ALGORITHM_PARTITION_COPY_HPP
  15. #include <tuple>
  16. #include <meta/meta.hpp>
  17. #include <range/v3/range_fwd.hpp>
  18. #include <range/v3/algorithm/result_types.hpp>
  19. #include <range/v3/functional/identity.hpp>
  20. #include <range/v3/functional/invoke.hpp>
  21. #include <range/v3/iterator/concepts.hpp>
  22. #include <range/v3/iterator/operations.hpp>
  23. #include <range/v3/iterator/traits.hpp>
  24. #include <range/v3/range/access.hpp>
  25. #include <range/v3/range/concepts.hpp>
  26. #include <range/v3/range/dangling.hpp>
  27. #include <range/v3/range/traits.hpp>
  28. #include <range/v3/utility/static_const.hpp>
  29. namespace ranges
  30. {
  31. /// \addtogroup group-algorithms
  32. /// @{
  33. template<typename I, typename O0, typename O1>
  34. using partition_copy_result = detail::in_out1_out2_result<I, O0, O1>;
  35. RANGES_BEGIN_NIEBLOID(partition_copy)
  36. /// \brief function template \c partition_copy
  37. template<typename I,
  38. typename S,
  39. typename O0,
  40. typename O1,
  41. typename C,
  42. typename P = identity>
  43. auto RANGES_FUN_NIEBLOID(partition_copy)(
  44. I first, S last, O0 o0, O1 o1, C pred, P proj = P{})
  45. ->CPP_ret(partition_copy_result<I, O0, O1>)( //
  46. requires input_iterator<I> && sentinel_for<S, I> &&
  47. weakly_incrementable<O0> && weakly_incrementable<O1> &&
  48. indirectly_copyable<I, O0> && indirectly_copyable<I, O1> &&
  49. indirect_unary_predicate<C, projected<I, P>>)
  50. {
  51. for(; first != last; ++first)
  52. {
  53. auto && x = *first;
  54. if(invoke(pred, invoke(proj, x)))
  55. {
  56. *o0 = (decltype(x) &&)x;
  57. ++o0;
  58. }
  59. else
  60. {
  61. *o1 = (decltype(x) &&)x;
  62. ++o1;
  63. }
  64. }
  65. return {first, o0, o1};
  66. }
  67. /// \overload
  68. template<typename Rng,
  69. typename O0,
  70. typename O1,
  71. typename C,
  72. typename P = identity>
  73. auto RANGES_FUN_NIEBLOID(partition_copy)(
  74. Rng && rng, O0 o0, O1 o1, C pred, P proj = P{}) //
  75. ->CPP_ret(partition_copy_result<safe_iterator_t<Rng>, O0, O1>)( //
  76. requires input_range<Rng> && weakly_incrementable<O0> &&
  77. weakly_incrementable<O1> && indirectly_copyable<iterator_t<Rng>, O0> &&
  78. indirectly_copyable<iterator_t<Rng>, O1> &&
  79. indirect_unary_predicate<C, projected<iterator_t<Rng>, P>>)
  80. {
  81. return (*this)(begin(rng),
  82. end(rng),
  83. std::move(o0),
  84. std::move(o1),
  85. std::move(pred),
  86. std::move(proj));
  87. }
  88. RANGES_END_NIEBLOID(partition_copy)
  89. namespace cpp20
  90. {
  91. using ranges::partition_copy;
  92. using ranges::partition_copy_result;
  93. } // namespace cpp20
  94. /// @}
  95. } // namespace ranges
  96. #endif // include guard