Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:09:42

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2013-present
0005 //
0006 //  Use, modification and distribution is subject to the
0007 //  Boost Software License, Version 1.0. (See accompanying
0008 //  file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 // Project home: https://github.com/ericniebler/range-v3
0012 //
0013 
0014 #ifndef RANGES_V3_ACTION_PUSH_BACK_HPP
0015 #define RANGES_V3_ACTION_PUSH_BACK_HPP
0016 
0017 #include <utility>
0018 
0019 #include <meta/meta.hpp>
0020 
0021 #include <range/v3/range_fwd.hpp>
0022 
0023 #include <range/v3/action/action.hpp>
0024 #include <range/v3/action/insert.hpp>
0025 #include <range/v3/detail/with_braced_init_args.hpp>
0026 #include <range/v3/functional/bind_back.hpp>
0027 #include <range/v3/utility/static_const.hpp>
0028 
0029 #include <range/v3/detail/prologue.hpp>
0030 
0031 namespace ranges
0032 {
0033     /// \addtogroup group-actions
0034     /// @{
0035 
0036     /// \cond
0037     namespace adl_push_back_detail
0038     {
0039         /// \endcond
0040         template<typename Cont, typename T>
0041         using push_back_t = decltype(static_cast<void>(
0042             unwrap_reference(std::declval<Cont &>()).push_back(std::declval<T>())));
0043 
0044         template<typename Cont, typename Rng>
0045         using insert_t = decltype(static_cast<void>(
0046             ranges::insert(std::declval<Cont &>(), std::declval<sentinel_t<Cont>>(),
0047                            std::declval<Rng>())));
0048 
0049         template(typename Cont, typename T)(
0050             requires lvalue_container_like<Cont> AND
0051                 (!range<T>) AND constructible_from<range_value_t<Cont>, T>)
0052         push_back_t<Cont, T> push_back(Cont && cont, T && t)
0053         {
0054             unwrap_reference(cont).push_back(static_cast<T &&>(t));
0055         }
0056 
0057         template(typename Cont, typename Rng)(
0058             requires lvalue_container_like<Cont> AND range<Rng>)
0059         insert_t<Cont, Rng> push_back(Cont && cont, Rng && rng)
0060         {
0061             ranges::insert(cont, end(cont), static_cast<Rng &&>(rng));
0062         }
0063 
0064         /// \cond
0065         // clang-format off
0066         /// \concept can_push_back_frag_
0067         /// \brief The \c can_push_back_frag_ concept
0068         template<typename Rng, typename T>
0069         CPP_requires(can_push_back_frag_,
0070             requires(Rng && rng, T && t) //
0071             (
0072                 push_back(rng, (T &&) t)
0073             ));
0074         /// \concept can_push_back_
0075         /// \brief The \c can_push_back_ concept
0076         template<typename Rng, typename T>
0077         CPP_concept can_push_back_ =
0078             CPP_requires_ref(adl_push_back_detail::can_push_back_frag_, Rng, T);
0079         // clang-format on
0080         /// \endcond
0081 
0082         struct push_back_fn
0083         {
0084             template<typename T>
0085             constexpr auto operator()(T && val) const
0086             {
0087                 return make_action_closure(
0088                     bind_back(push_back_fn{}, static_cast<T &&>(val)));
0089             }
0090 
0091             template(typename T)(
0092                 requires range<T &>)
0093             constexpr auto operator()(T & t) const
0094             {
0095                 return make_action_closure(
0096                     bind_back(push_back_fn{}, detail::reference_wrapper_<T>(t)));
0097             }
0098 
0099             template<typename T>
0100             constexpr auto operator()(std::initializer_list<T> val) const
0101             {
0102                 return make_action_closure(bind_back(push_back_fn{}, val));
0103             }
0104 
0105             template(typename Rng, typename T)(
0106                 requires input_range<Rng> AND can_push_back_<Rng, T> AND
0107                 (range<T> || constructible_from<range_value_t<Rng>, T>)) //
0108             Rng operator()(Rng && rng, T && t) const //
0109             {
0110                 push_back(rng, static_cast<T &&>(t));
0111                 return static_cast<Rng &&>(rng);
0112             }
0113 
0114             template(typename Rng, typename T)(
0115                 requires input_range<Rng> AND
0116                         can_push_back_<Rng, std::initializer_list<T>> AND
0117                             constructible_from<range_value_t<Rng>, T const &>)
0118             Rng operator()(Rng && rng, std::initializer_list<T> t) const //
0119             {
0120                 push_back(rng, t);
0121                 return static_cast<Rng &&>(rng);
0122             }
0123 
0124             /// \cond
0125             template<typename Rng, typename T>
0126             invoke_result_t<push_back_fn, Rng, T &> //
0127             operator()(Rng && rng, detail::reference_wrapper_<T> r) const
0128             {
0129                 return (*this)(static_cast<Rng &&>(rng), r.get());
0130             }
0131             /// \endcond
0132         };
0133         /// \cond
0134     } // namespace adl_push_back_detail
0135     /// \endcond
0136 
0137     namespace actions
0138     {
0139         RANGES_INLINE_VARIABLE(adl_push_back_detail::push_back_fn, push_back)
0140     } // namespace actions
0141 
0142     using actions::push_back;
0143 
0144     /// @}
0145 } // namespace ranges
0146 
0147 #include <range/v3/detail/epilogue.hpp>
0148 
0149 #endif