Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/range/v3/iterator/move_iterators.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2014-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 #ifndef RANGES_V3_ITERATOR_MOVE_ITERATORS_HPP
0014 #define RANGES_V3_ITERATOR_MOVE_ITERATORS_HPP
0015 
0016 #include <cstddef>
0017 #include <utility>
0018 
0019 #include <range/v3/range_fwd.hpp>
0020 
0021 #include <range/v3/iterator/basic_iterator.hpp>
0022 #include <range/v3/iterator/concepts.hpp>
0023 #include <range/v3/iterator/traits.hpp>
0024 
0025 #include <range/v3/detail/prologue.hpp>
0026 
0027 namespace ranges
0028 {
0029     /// \addtogroup group-iterator
0030     /// @{
0031     template<typename I>
0032     struct move_iterator
0033     {
0034     private:
0035         CPP_assert(input_iterator<I>);
0036         I current_ = I{};
0037 
0038     public:
0039         using iterator_type = I;
0040         using difference_type = iter_difference_t<I>;
0041         using value_type = iter_value_t<I>;
0042         using iterator_category = std::input_iterator_tag;
0043         using reference = iter_rvalue_reference_t<I>;
0044 
0045         constexpr move_iterator() = default;
0046         explicit move_iterator(I i)
0047           : current_(i)
0048         {}
0049         template(typename O)(
0050             requires convertible_to<O, I>)
0051         move_iterator(move_iterator<O> const & i)
0052           : current_(i.base())
0053         {}
0054         template(typename O)(
0055             requires convertible_to<O, I>)
0056         move_iterator & operator=(move_iterator<O> const & i)
0057         {
0058             current_ = i.base();
0059             return *this;
0060         }
0061         I base() const
0062         {
0063             return current_;
0064         }
0065         // clang-format off
0066         auto CPP_auto_fun(operator*)()(const)
0067         (
0068             return iter_move(current_)
0069         )
0070             // clang-format on
0071             move_iterator &
0072             operator++()
0073         {
0074             ++current_;
0075             return *this;
0076         }
0077         CPP_member
0078         auto operator++(int) //
0079             -> CPP_ret(void)(
0080                 requires (!forward_iterator<I>))
0081         {
0082             ++current_;
0083         }
0084         CPP_member
0085         auto operator++(int) //
0086             -> CPP_ret(move_iterator)(
0087                 requires forward_iterator<I>)
0088         {
0089             return move_iterator(current_++);
0090         }
0091         CPP_member
0092         auto operator--() //
0093             -> CPP_ret(move_iterator &)(
0094                 requires forward_iterator<I>)
0095         {
0096             --current_;
0097             return *this;
0098         }
0099         CPP_member
0100         auto operator--(int) //
0101             -> CPP_ret(move_iterator)(
0102                 requires bidirectional_iterator<I>)
0103         {
0104             return move_iterator(current_--);
0105         }
0106         CPP_member
0107         auto operator+(difference_type n) const //
0108             -> CPP_ret(move_iterator)(
0109                 requires random_access_iterator<I>)
0110         {
0111             return move_iterator(current_ + n);
0112         }
0113         CPP_member
0114         auto operator+=(difference_type n)
0115             -> CPP_ret(move_iterator &)(
0116                 requires random_access_iterator<I>)
0117         {
0118             current_ += n;
0119             return *this;
0120         }
0121         CPP_member
0122         auto operator-(difference_type n) const //
0123             -> CPP_ret(move_iterator)(
0124                 requires random_access_iterator<I>)
0125         {
0126             return move_iterator(current_ - n);
0127         }
0128         CPP_member
0129         auto operator-=(difference_type n) //
0130             -> CPP_ret(move_iterator &)(
0131                 requires random_access_iterator<I>)
0132         {
0133             current_ -= n;
0134             return *this;
0135         }
0136         CPP_member
0137         auto operator[](difference_type n) const //
0138             -> CPP_ret(reference)(
0139                 requires random_access_iterator<I>)
0140         {
0141             return iter_move(current_ + n);
0142         }
0143 
0144         template<typename I2>
0145         friend auto operator==(move_iterator const & x, move_iterator<I2> const & y)
0146             -> CPP_broken_friend_ret(bool)(
0147                 requires equality_comparable_with<I, I2>)
0148         {
0149             return x.base() == y.base();
0150         }
0151         template<typename I2>
0152         friend auto operator!=(move_iterator const & x, move_iterator<I2> const & y)
0153             -> CPP_broken_friend_ret(bool)(
0154                 requires equality_comparable_with<I, I2>)
0155         {
0156             return !(x == y);
0157         }
0158         template<typename I2>
0159         friend auto operator<(move_iterator const & x, move_iterator<I2> const & y)
0160             -> CPP_broken_friend_ret(bool)(
0161                 requires totally_ordered_with<I, I2>)
0162         {
0163             return x.base() < y.base();
0164         }
0165         template<typename I2>
0166         friend auto operator<=(move_iterator const & x, move_iterator<I2> const & y)
0167             -> CPP_broken_friend_ret(bool)(
0168                 requires totally_ordered_with<I, I2>)
0169         {
0170             return !(y < x);
0171         }
0172         template<typename I2>
0173         friend auto operator>(move_iterator const & x, move_iterator<I2> const & y)
0174             -> CPP_broken_friend_ret(bool)(
0175                 requires totally_ordered_with<I, I2>)
0176         {
0177             return y < x;
0178         }
0179         template<typename I2>
0180         friend auto operator>=(move_iterator const & x, move_iterator<I2> const & y)
0181             -> CPP_broken_friend_ret(bool)(
0182                 requires totally_ordered_with<I, I2>)
0183         {
0184             return !(x < y);
0185         }
0186 
0187         template<typename I2>
0188         friend auto operator-(move_iterator const & x, move_iterator<I2> const & y)
0189             -> CPP_broken_friend_ret(iter_difference_t<I2>)(
0190                 requires sized_sentinel_for<I, I2>)
0191         {
0192             return x.base() - y.base();
0193         }
0194         CPP_broken_friend_member
0195         friend auto operator+(iter_difference_t<I> n,
0196                               move_iterator const & x)
0197             -> CPP_broken_friend_ret(move_iterator)(
0198                 requires random_access_iterator<I>)
0199         {
0200             return x + n;
0201         }
0202     };
0203 
0204     struct make_move_iterator_fn
0205     {
0206         template(typename I)(
0207             requires input_iterator<I>)
0208         constexpr move_iterator<I> operator()(I it) const
0209         {
0210             return move_iterator<I>{detail::move(it)};
0211         }
0212     };
0213 
0214     RANGES_INLINE_VARIABLE(make_move_iterator_fn, make_move_iterator)
0215 
0216     template<typename S>
0217     struct move_sentinel
0218     {
0219     private:
0220         S sent_;
0221 
0222     public:
0223         constexpr move_sentinel()
0224           : sent_{}
0225         {}
0226         constexpr explicit move_sentinel(S s)
0227           : sent_(detail::move(s))
0228         {}
0229         template(typename OS)(
0230             requires convertible_to<OS, S>)
0231         constexpr explicit move_sentinel(move_sentinel<OS> const & that)
0232           : sent_(that.base())
0233         {}
0234         template(typename OS)(
0235             requires convertible_to<OS, S>)
0236         move_sentinel & operator=(move_sentinel<OS> const & that)
0237         {
0238             sent_ = that.base();
0239             return *this;
0240         }
0241         S base() const
0242         {
0243             return sent_;
0244         }
0245 
0246         template<typename I>
0247         friend auto operator==(move_iterator<I> const & i, move_sentinel const & s)
0248             -> CPP_broken_friend_ret(bool)(
0249                 requires sentinel_for<S, I>)
0250         {
0251             return i.base() == s.base();
0252         }
0253         template<typename I>
0254         friend auto operator==(move_sentinel const & s, move_iterator<I> const & i)
0255             -> CPP_broken_friend_ret(bool)(
0256                 requires sentinel_for<S, I>)
0257         {
0258             return s.base() == i.base();
0259         }
0260         template<typename I>
0261         friend auto operator!=(move_iterator<I> const & i, move_sentinel const & s)
0262             -> CPP_broken_friend_ret(bool)(
0263                 requires sentinel_for<S, I>)
0264         {
0265             return i.base() != s.base();
0266         }
0267         template<typename I>
0268         friend auto operator!=(move_sentinel const & s, move_iterator<I> const & i)
0269             -> CPP_broken_friend_ret(bool)(
0270                 requires sentinel_for<S, I>)
0271         {
0272             return s.base() != i.base();
0273         }
0274     };
0275 
0276     struct make_move_sentinel_fn
0277     {
0278         template(typename I)(
0279             requires input_iterator<I>)
0280         constexpr move_iterator<I> operator()(I i) const
0281         {
0282             return move_iterator<I>{detail::move(i)};
0283         }
0284 
0285         template(typename S)(
0286             requires semiregular<S> AND (!input_iterator<S>)) //
0287         constexpr move_sentinel<S> operator()(S s) const
0288         {
0289             return move_sentinel<S>{detail::move(s)};
0290         }
0291     };
0292 
0293     RANGES_INLINE_VARIABLE(make_move_sentinel_fn, make_move_sentinel)
0294 
0295     /// \cond
0296     namespace detail
0297     {
0298         template<typename I, bool IsReadable>
0299         struct move_into_cursor_types_
0300         {};
0301 
0302         template<typename I>
0303         struct move_into_cursor_types_<I, true>
0304         {
0305             using value_type = iter_value_t<I>;
0306             using single_pass = meta::bool_<(bool)single_pass_iterator_<I>>;
0307         };
0308 
0309         template<typename I>
0310         using move_into_cursor_types =
0311             move_into_cursor_types_<I, (bool)indirectly_readable<I>>;
0312 
0313         template<typename I>
0314         struct move_into_cursor : move_into_cursor_types<I>
0315         {
0316         private:
0317             friend range_access;
0318             struct mixin : basic_mixin<move_into_cursor>
0319             {
0320                 mixin() = default;
0321                 #ifndef _MSC_VER
0322                 using basic_mixin<move_into_cursor>::basic_mixin;
0323                 #else
0324                 constexpr explicit mixin(move_into_cursor && cur)
0325                   : basic_mixin<move_into_cursor>(static_cast<move_into_cursor &&>(cur))
0326                 {}
0327                 constexpr explicit mixin(move_into_cursor const & cur)
0328                   : basic_mixin<move_into_cursor>(cur)
0329                 {}
0330                 #endif
0331                 explicit mixin(I it)
0332                   : mixin{move_into_cursor{std::move(it)}}
0333                 {}
0334                 I base() const
0335                 {
0336                     return this->get().it_;
0337                 }
0338             };
0339 
0340             I it_ = I();
0341 
0342             explicit move_into_cursor(I it)
0343               : it_(std::move(it))
0344             {}
0345             void next()
0346             {
0347                 ++it_;
0348             }
0349             template(typename T)(
0350                 requires indirectly_writable<I, aux::move_t<T>>)
0351             void write(T && t) noexcept(noexcept(*it_ = std::move(t)))
0352             {
0353                 *it_ = std::move(t);
0354             }
0355             template(typename T)(
0356                 requires indirectly_writable<I, aux::move_t<T>>)
0357             void write(T && t) const noexcept(noexcept(*it_ = std::move(t)))
0358             {
0359                 *it_ = std::move(t);
0360             }
0361             CPP_member
0362             auto read() const noexcept(noexcept(*std::declval<I const &>()))
0363                 -> CPP_ret(iter_reference_t<I>)(
0364                     requires indirectly_readable<I>)
0365             {
0366                 return *it_;
0367             }
0368             CPP_member
0369             auto equal(move_into_cursor const & that) const //
0370                 -> CPP_ret(bool)(
0371                     requires input_iterator<I>)
0372             {
0373                 return it_ == that.it_;
0374             }
0375             CPP_member
0376             auto prev() //
0377                 -> CPP_ret(void)(
0378                     requires bidirectional_iterator<I>)
0379             {
0380                 --it_;
0381             }
0382             CPP_member
0383             auto advance(iter_difference_t<I> n) //
0384                 -> CPP_ret(void)(
0385                     requires random_access_iterator<I>)
0386             {
0387                 it_ += n;
0388             }
0389             CPP_member
0390             auto distance_to(move_into_cursor const & that) const //
0391                 -> CPP_ret(iter_difference_t<I>)(
0392                     requires sized_sentinel_for<I, I>)
0393             {
0394                 return that.it_ - it_;
0395             }
0396             template(typename II = I const)(
0397                 requires same_as<I const, II> AND indirectly_readable<II>)
0398             constexpr iter_rvalue_reference_t<II> move() const //
0399                 noexcept(has_nothrow_iter_move_v<II>)
0400             {
0401                 return iter_move(it_);
0402             }
0403 
0404         public:
0405             constexpr move_into_cursor() = default;
0406         };
0407     } // namespace detail
0408     /// \endcond
0409 
0410     struct move_into_fn
0411     {
0412         template<typename I>
0413         constexpr move_into_iterator<I> operator()(I it) const
0414         {
0415             return move_into_iterator<I>{std::move(it)};
0416         }
0417     };
0418 
0419     /// \sa `move_into_fn`
0420     RANGES_INLINE_VARIABLE(move_into_fn, move_into)
0421 
0422     namespace cpp20
0423     {
0424         using ranges::make_move_iterator;
0425         using ranges::move_iterator;
0426         using ranges::move_sentinel;
0427     } // namespace cpp20
0428     /// @}
0429 } // namespace ranges
0430 
0431 /// \cond
0432 RANGES_DIAGNOSTIC_PUSH
0433 RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
0434 
0435 namespace std
0436 {
0437     template<typename I>
0438     struct iterator_traits<::ranges::move_iterator<I>>
0439     {
0440         using iterator_category = std::input_iterator_tag;
0441         using difference_type = typename ::ranges::move_iterator<I>::difference_type;
0442         using value_type = typename ::ranges::move_iterator<I>::value_type;
0443         using reference = typename ::ranges::move_iterator<I>::reference;
0444         using pointer = meta::_t<std::add_pointer<reference>>;
0445     };
0446 } // namespace std
0447 
0448 RANGES_DIAGNOSTIC_POP
0449 /// \endcond
0450 
0451 #include <range/v3/detail/epilogue.hpp>
0452 
0453 #endif // RANGES_V3_ITERATOR_MOVE_ITERATORS_HPP