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_INSERT_HPP
0015 #define RANGES_V3_ACTION_INSERT_HPP
0016 
0017 #include <initializer_list>
0018 #include <utility>
0019 
0020 #include <range/v3/range_fwd.hpp>
0021 
0022 #include <range/v3/action/concepts.hpp>
0023 #include <range/v3/algorithm/max.hpp>
0024 #include <range/v3/iterator/common_iterator.hpp>
0025 #include <range/v3/range/traits.hpp>
0026 #include <range/v3/utility/static_const.hpp>
0027 
0028 #include <range/v3/detail/prologue.hpp>
0029 
0030 namespace ranges
0031 {
0032     /// \cond
0033     namespace adl_insert_detail
0034     {
0035         template<typename Cont, typename... Args>
0036         using insert_result_t = decltype(
0037             unwrap_reference(std::declval<Cont>()).insert(std::declval<Args>()...));
0038 
0039         template(typename Cont, typename T)(
0040             requires lvalue_container_like<Cont> AND
0041             (!range<T> && constructible_from<range_value_t<Cont>, T>)) //
0042         insert_result_t<Cont &, T> insert(Cont && cont, T && t)
0043         {
0044             return unwrap_reference(cont).insert(static_cast<T &&>(t));
0045         }
0046 
0047         template(typename Cont, typename I, typename S)(
0048             requires lvalue_container_like<Cont> AND sentinel_for<S, I> AND (!range<S>))
0049         insert_result_t<Cont &, detail::cpp17_iterator_t<I, S>,
0050                                 detail::cpp17_iterator_t<I, S>>
0051         insert(Cont && cont, I i, S j)
0052         {
0053             return unwrap_reference(cont).insert(detail::cpp17_iterator_t<I, S>{i},
0054                                                  detail::cpp17_iterator_t<I, S>{j});
0055         }
0056 
0057         template(typename Cont, typename Rng)(
0058             requires lvalue_container_like<Cont> AND range<Rng>)
0059         insert_result_t<Cont &, detail::range_cpp17_iterator_t<Rng>,
0060                                 detail::range_cpp17_iterator_t<Rng>>
0061         insert(Cont && cont, Rng && rng)
0062         {
0063             return unwrap_reference(cont).insert(
0064                 detail::range_cpp17_iterator_t<Rng>{ranges::begin(rng)},
0065                 detail::range_cpp17_iterator_t<Rng>{ranges::end(rng)});
0066         }
0067 
0068         template(typename Cont, typename I, typename T)(
0069             requires lvalue_container_like<Cont> AND input_iterator<I> AND
0070             (!range<T> && constructible_from<range_value_t<Cont>, T>)) //
0071         insert_result_t<Cont &, I, T> insert(Cont && cont, I p, T && t)
0072         {
0073             return unwrap_reference(cont).insert(p, static_cast<T &&>(t));
0074         }
0075 
0076         template(typename Cont, typename I, typename N, typename T)(
0077             requires lvalue_container_like<Cont> AND input_iterator<I> AND
0078                 integral<N> AND constructible_from<range_value_t<Cont>, T>)
0079         insert_result_t<Cont &, I, N, T> insert(Cont && cont, I p, N n, T && t)
0080         {
0081             return unwrap_reference(cont).insert(p, n, static_cast<T &&>(t));
0082         }
0083 
0084         /// \cond
0085         namespace detail
0086         {
0087             using ranges::detail::cpp17_iterator_t;
0088             using ranges::detail::range_cpp17_iterator_t;
0089 
0090             template(typename Cont, typename P)(
0091                 requires container<Cont> AND input_iterator<P> AND
0092                         random_access_reservable<Cont>)
0093             iterator_t<Cont> insert_reserve_helper(
0094                 Cont & cont, P const p, range_size_t<Cont> const delta)
0095             {
0096                 auto const old_size = ranges::size(cont);
0097                 auto const max_size = cont.max_size();
0098                 RANGES_EXPECT(delta <= max_size - old_size);
0099                 auto const new_size = old_size + delta;
0100                 auto const old_capacity = cont.capacity();
0101                 auto const index = p - ranges::begin(cont);
0102                 if(old_capacity < new_size)
0103                 {
0104                     auto const new_capacity =
0105                         (old_capacity <= max_size / 3 * 2)
0106                             ? ranges::max(old_capacity + old_capacity / 2, new_size)
0107                             : max_size;
0108                     cont.reserve(new_capacity);
0109                 }
0110                 return ranges::begin(cont) + index;
0111             }
0112 
0113             template(typename Cont, typename P, typename I, typename S)(
0114                 requires sentinel_for<S, I> AND (!range<S>)) //
0115             auto insert_impl(Cont && cont, P p, I i, S j, std::false_type)
0116                 -> decltype(unwrap_reference(cont).insert(
0117                     p, cpp17_iterator_t<I, S>{i}, cpp17_iterator_t<I, S>{j}))
0118             {
0119                 using C = cpp17_iterator_t<I, S>;
0120                 return unwrap_reference(cont).insert(p, C{i}, C{j});
0121             }
0122 
0123             template(typename Cont, typename P, typename I, typename S)(
0124                 requires sized_sentinel_for<S, I> AND random_access_reservable<Cont> AND
0125                     (!range<S>)) //
0126             auto insert_impl(Cont && cont_, P p, I i, S j, std::true_type)
0127                 -> decltype(unwrap_reference(cont_).insert(
0128                     ranges::begin(unwrap_reference(cont_)), cpp17_iterator_t<I, S>{i},
0129                     cpp17_iterator_t<I, S>{j}))
0130             {
0131                 using C = cpp17_iterator_t<I, S>;
0132                 auto && cont = unwrap_reference(cont_);
0133                 auto const delta = static_cast<range_size_t<Cont>>(j - i);
0134                 auto pos = insert_reserve_helper(cont, std::move(p), delta);
0135                 return cont.insert(pos, C{std::move(i)}, C{std::move(j)});
0136             }
0137 
0138             template(typename Cont, typename I, typename Rng)(
0139                 requires range<Rng>)
0140             auto insert_impl(Cont && cont, I p, Rng && rng, std::false_type)
0141                 -> decltype(unwrap_reference(cont).insert(
0142                     p, range_cpp17_iterator_t<Rng>{ranges::begin(rng)},
0143                     range_cpp17_iterator_t<Rng>{ranges::end(rng)}))
0144             {
0145                 using C = range_cpp17_iterator_t<Rng>;
0146                 return unwrap_reference(cont).insert(
0147                     p, C{ranges::begin(rng)}, C{ranges::end(rng)});
0148             }
0149 
0150             template(typename Cont, typename I, typename Rng)(
0151                 requires random_access_reservable<Cont> AND sized_range<Rng>)
0152             auto insert_impl(Cont && cont_, I p, Rng && rng, std::true_type)
0153                 -> decltype(unwrap_reference(cont_).insert(
0154                     begin(unwrap_reference(cont_)),
0155                     range_cpp17_iterator_t<Rng>{ranges::begin(rng)},
0156                     range_cpp17_iterator_t<Rng>{ranges::end(rng)}))
0157             {
0158                 using C = range_cpp17_iterator_t<Rng>;
0159                 auto && cont = unwrap_reference(cont_);
0160                 auto const delta = static_cast<range_size_t<Cont>>(ranges::size(rng));
0161                 auto pos = insert_reserve_helper(cont, std::move(p), delta);
0162                 return cont.insert(pos, C{ranges::begin(rng)}, C{ranges::end(rng)});
0163             }
0164         } // namespace detail
0165         /// \endcond
0166 
0167         template(typename Cont, typename P, typename I, typename S)(
0168             requires lvalue_container_like<Cont> AND input_iterator<P> AND
0169                 sentinel_for<S, I> AND
0170             (!range<S>)) //
0171         auto insert(Cont && cont, P p, I i, S j) //
0172             -> decltype(detail::insert_impl(
0173                 static_cast<Cont &&>(cont),
0174                 static_cast<P &&>(p),
0175                 static_cast<I &&>(i),
0176                 static_cast<S &&>(j),
0177                 meta::bool_<random_access_reservable<Cont> && //
0178                             sized_sentinel_for<S, I>>{}))
0179         {
0180             return detail::insert_impl(static_cast<Cont &&>(cont),
0181                                        static_cast<P &&>(p),
0182                                        static_cast<I &&>(i),
0183                                        static_cast<S &&>(j),
0184                                        meta::bool_<random_access_reservable<Cont> &&
0185                                                    sized_sentinel_for<S, I>>{});
0186         }
0187 
0188         template(typename Cont, typename I, typename Rng)(
0189             requires lvalue_container_like<Cont> AND input_iterator<I> AND range<Rng>)
0190         auto insert(Cont && cont, I p, Rng && rng)
0191             -> decltype(detail::insert_impl(
0192                 static_cast<Cont &&>(cont), std::move(p), static_cast<Rng &&>(rng),
0193                 meta::bool_<random_access_reservable<Cont> && sized_range<Rng>>{}))
0194         {
0195             return detail::insert_impl(static_cast<Cont &&>(cont),
0196                                        std::move(p),
0197                                        static_cast<Rng &&>(rng),
0198                                        meta::bool_<random_access_reservable<Cont> &&
0199                                                    sized_range<Rng>>{});
0200         }
0201 
0202         struct insert_fn
0203         {
0204             template<typename Rng, typename... Args>
0205             using insert_result_t =
0206                 decltype(insert(std::declval<Rng>(), std::declval<Args>()...));
0207 
0208             template(typename Rng, typename T)(
0209                 requires range<Rng> AND
0210                     (!range<T>) AND constructible_from<range_value_t<Rng>, T>)
0211             insert_result_t<Rng, T> operator()(Rng && rng, T && t) const
0212             {
0213                 return insert(static_cast<Rng &&>(rng), static_cast<T &&>(t));
0214             }
0215 
0216             template(typename Rng, typename Rng2)(
0217                 requires range<Rng> AND range<Rng2>)
0218             insert_result_t<Rng, Rng2> operator()(Rng && rng, Rng2 && rng2) const
0219             {
0220                 static_assert(!is_infinite<Rng>::value,
0221                               "Attempting to insert an infinite range into a container");
0222                 return insert(static_cast<Rng &&>(rng), static_cast<Rng2 &&>(rng2));
0223             }
0224 
0225             template(typename Rng, typename T)(
0226                 requires range<Rng>)
0227             insert_result_t<Rng, std::initializer_list<T> &> //
0228             operator()(Rng && rng, std::initializer_list<T> rng2) const
0229             {
0230                 return insert(static_cast<Rng &&>(rng), rng2);
0231             }
0232 
0233             template(typename Rng, typename I, typename S)(
0234                 requires range<Rng> AND sentinel_for<S, I> AND (!range<S>)) //
0235             insert_result_t<Rng, I, S> operator()(Rng && rng, I i, S j) const
0236             {
0237                 return insert(static_cast<Rng &&>(rng), std::move(i), std::move(j));
0238             }
0239 
0240             template(typename Rng, typename I, typename T)(
0241                 requires range<Rng> AND input_iterator<I> AND
0242                     (!range<T>) AND constructible_from<range_value_t<Rng>, T>)
0243             insert_result_t<Rng, I, T> operator()(Rng && rng, I p, T && t) const
0244             {
0245                 return insert(
0246                     static_cast<Rng &&>(rng), std::move(p), static_cast<T &&>(t));
0247             }
0248 
0249             template(typename Rng, typename I, typename Rng2)(
0250                 requires range<Rng> AND input_iterator<I> AND range<Rng2>)
0251             insert_result_t<Rng, I, Rng2> operator()(Rng && rng, I p, Rng2 && rng2) const
0252             {
0253                 static_assert(!is_infinite<Rng>::value,
0254                               "Attempting to insert an infinite range into a container");
0255                 return insert(
0256                     static_cast<Rng &&>(rng), std::move(p), static_cast<Rng2 &&>(rng2));
0257             }
0258 
0259             template(typename Rng, typename I, typename T)(
0260                 requires range<Rng> AND input_iterator<I>)
0261             insert_result_t<Rng, I, std::initializer_list<T> &> //
0262             operator()(Rng && rng, I p, std::initializer_list<T> rng2) const
0263             {
0264                 return insert(static_cast<Rng &&>(rng), std::move(p), rng2);
0265             }
0266 
0267             template(typename Rng, typename I, typename N, typename T)(
0268                 requires range<Rng> AND input_iterator<I> AND integral<N> AND
0269                     (!range<T>) AND constructible_from<range_value_t<Rng>, T>)
0270             insert_result_t<Rng, I, N, T> operator()(Rng && rng, I p, N n, T && t) const
0271             {
0272                 return insert(
0273                     static_cast<Rng &&>(rng), std::move(p), n, static_cast<T &&>(t));
0274             }
0275 
0276             template(typename Rng, typename P, typename I, typename S)(
0277                 requires range<Rng> AND input_iterator<P> AND sentinel_for<S, I> AND
0278                 (!range<S>)) //
0279             insert_result_t<Rng, P, I, S> operator()(Rng && rng, P p, I i, S j) const
0280             {
0281                 return insert(
0282                     static_cast<Rng &&>(rng), std::move(p), std::move(i), std::move(j));
0283             }
0284         };
0285     } // namespace adl_insert_detail
0286     /// \endcond
0287 
0288     /// \ingroup group-actions
0289     RANGES_INLINE_VARIABLE(adl_insert_detail::insert_fn, insert)
0290 
0291     namespace actions
0292     {
0293         using ranges::insert;
0294     }
0295 } // namespace ranges
0296 
0297 #include <range/v3/detail/epilogue.hpp>
0298 
0299 #endif