push_front.hpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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_ACTION_PUSH_FRONT_HPP
  14. #define RANGES_V3_ACTION_PUSH_FRONT_HPP
  15. #include <utility>
  16. #include <meta/meta.hpp>
  17. #include <range/v3/range_fwd.hpp>
  18. #include <range/v3/action/action.hpp>
  19. #include <range/v3/action/insert.hpp>
  20. #include <range/v3/detail/with_braced_init_args.hpp>
  21. #include <range/v3/functional/bind_back.hpp>
  22. #include <range/v3/utility/static_const.hpp>
  23. #include <range/v3/detail/prologue.hpp>
  24. namespace ranges
  25. {
  26. /// \addtogroup group-actions
  27. /// @{
  28. /// \cond
  29. namespace adl_push_front_detail
  30. {
  31. /// \endcond
  32. template<typename Cont, typename T>
  33. using push_front_t = decltype(static_cast<void>(
  34. unwrap_reference(std::declval<Cont &>()).push_front(std::declval<T>())));
  35. template<typename Cont, typename Rng>
  36. using insert_t = decltype(static_cast<void>(
  37. ranges::insert(std::declval<Cont &>(), std::declval<iterator_t<Cont>>(),
  38. std::declval<Rng>())));
  39. template(typename Cont, typename T)(
  40. requires lvalue_container_like<Cont> AND
  41. (!range<T>) AND constructible_from<range_value_t<Cont>, T>)
  42. push_front_t<Cont, T> push_front(Cont && cont, T && t)
  43. {
  44. unwrap_reference(cont).push_front(static_cast<T &&>(t));
  45. }
  46. template(typename Cont, typename Rng)(
  47. requires lvalue_container_like<Cont> AND range<Rng>)
  48. insert_t<Cont, Rng> push_front(Cont && cont, Rng && rng)
  49. {
  50. ranges::insert(cont, begin(cont), static_cast<Rng &&>(rng));
  51. }
  52. /// \cond
  53. // clang-format off
  54. /// \concept can_push_front_frag_
  55. /// \brief The \c can_push_front_frag_ concept
  56. template<typename Rng, typename T>
  57. CPP_requires(can_push_front_frag_,
  58. requires(Rng && rng, T && t) //
  59. (
  60. push_front(rng, (T &&) t)
  61. ));
  62. /// \concept can_push_front_
  63. /// \brief The \c can_push_front_ concept
  64. template<typename Rng, typename T>
  65. CPP_concept can_push_front_ =
  66. CPP_requires_ref(adl_push_front_detail::can_push_front_frag_, Rng, T);
  67. // clang-format on
  68. /// \endcond
  69. struct push_front_fn
  70. {
  71. template<typename T>
  72. constexpr auto operator()(T && val) const
  73. {
  74. return make_action_closure(
  75. bind_back(push_front_fn{}, static_cast<T &&>(val)));
  76. }
  77. template<typename T>
  78. constexpr auto operator()(std::initializer_list<T> val) const
  79. {
  80. return make_action_closure(bind_back(push_front_fn{}, val));
  81. }
  82. template(typename T)(
  83. requires range<T &>)
  84. constexpr auto operator()(T & t) const
  85. {
  86. return make_action_closure(
  87. bind_back(push_front_fn{}, detail::reference_wrapper_<T>(t)));
  88. }
  89. template(typename Rng, typename T)(
  90. requires input_range<Rng> AND can_push_front_<Rng, T> AND
  91. (range<T> || constructible_from<range_value_t<Rng>, T>)) //
  92. Rng operator()(Rng && rng, T && t) const //
  93. {
  94. push_front(rng, static_cast<T &&>(t));
  95. return static_cast<Rng &&>(rng);
  96. }
  97. template(typename Rng, typename T)(
  98. requires input_range<Rng> AND
  99. can_push_front_<Rng, std::initializer_list<T>> AND
  100. constructible_from<range_value_t<Rng>, T const &>)
  101. Rng operator()(Rng && rng, std::initializer_list<T> t) const //
  102. {
  103. push_front(rng, t);
  104. return static_cast<Rng &&>(rng);
  105. }
  106. /// \cond
  107. template<typename Rng, typename T>
  108. invoke_result_t<push_front_fn, Rng, T &> //
  109. operator()(Rng && rng, detail::reference_wrapper_<T> r) const
  110. {
  111. return (*this)(static_cast<Rng &&>(rng), r.get());
  112. }
  113. /// \endcond
  114. };
  115. /// \cond
  116. } // namespace adl_push_front_detail
  117. /// \endcond
  118. namespace actions
  119. {
  120. RANGES_INLINE_VARIABLE(adl_push_front_detail::push_front_fn, push_front)
  121. } // namespace actions
  122. using actions::push_front;
  123. /// @}
  124. } // namespace ranges
  125. #include <range/v3/detail/epilogue.hpp>
  126. #endif