Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2014-present
0005 //  Copyright Casey Carter 2017
0006 //
0007 //  Use, modification and distribution is subject to the
0008 //  Boost Software License, Version 1.0. (See accompanying
0009 //  file LICENSE_1_0.txt or copy at
0010 //  http://www.boost.org/LICENSE_1_0.txt)
0011 //
0012 // Project home: https://github.com/ericniebler/range-v3
0013 //
0014 
0015 #ifndef RANGES_V3_VIEW_ANY_VIEW_HPP
0016 #define RANGES_V3_VIEW_ANY_VIEW_HPP
0017 
0018 #include <type_traits>
0019 #include <typeinfo>
0020 #include <utility>
0021 
0022 #include <range/v3/range_fwd.hpp>
0023 
0024 #include <range/v3/iterator/default_sentinel.hpp>
0025 #include <range/v3/range/access.hpp>
0026 #include <range/v3/range/concepts.hpp>
0027 #include <range/v3/range/traits.hpp>
0028 #include <range/v3/utility/addressof.hpp>
0029 #include <range/v3/utility/memory.hpp>
0030 #include <range/v3/view/all.hpp>
0031 #include <range/v3/view/facade.hpp>
0032 
0033 #include <range/v3/detail/prologue.hpp>
0034 
0035 RANGES_DIAGNOSTIC_PUSH
0036 RANGES_DIAGNOSTIC_IGNORE_INCONSISTENT_OVERRIDE
0037 RANGES_DIAGNOSTIC_SUGGEST_OVERRIDE
0038 
0039 namespace ranges
0040 {
0041     /// \brief An enum that denotes the supported subset of range concepts supported by a
0042     /// range.
0043     enum class category
0044     {
0045         none = 0,             ///<\brief No concepts met.
0046         input = 1,            ///<\brief satisfies ranges::concepts::input_range
0047         forward = 3,          ///<\brief satisfies ranges::concepts::forward_range
0048         bidirectional = 7,    ///<\brief satisfies ranges::concepts::bidirectional_range
0049         random_access = 15,   ///<\brief satisfies ranges::concepts::random_access_range
0050         mask = random_access, ///<\brief Mask away any properties other than iterator
0051                               ///< category
0052         sized = 16,           ///<\brief satisfies ranges::concepts::sized_range
0053     };
0054 
0055     /** \name Binary operators for ranges::category
0056      *  \relates ranges::category
0057      *  \{
0058      */
0059     constexpr category operator&(category lhs, category rhs) noexcept
0060     {
0061         return static_cast<category>(
0062             static_cast<meta::_t<std::underlying_type<category>>>(lhs) &
0063             static_cast<meta::_t<std::underlying_type<category>>>(rhs));
0064     }
0065 
0066     constexpr category operator|(category lhs, category rhs) noexcept
0067     {
0068         return static_cast<category>(
0069             static_cast<meta::_t<std::underlying_type<category>>>(lhs) |
0070             static_cast<meta::_t<std::underlying_type<category>>>(rhs));
0071     }
0072 
0073     constexpr category operator^(category lhs, category rhs) noexcept
0074     {
0075         return static_cast<category>(
0076             static_cast<meta::_t<std::underlying_type<category>>>(lhs) ^
0077             static_cast<meta::_t<std::underlying_type<category>>>(rhs));
0078     }
0079 
0080     constexpr category operator~(category lhs) noexcept
0081     {
0082         return static_cast<category>(
0083             ~static_cast<meta::_t<std::underlying_type<category>>>(lhs));
0084     }
0085 
0086     constexpr category & operator&=(category & lhs, category rhs) noexcept
0087     {
0088         return (lhs = lhs & rhs);
0089     }
0090 
0091     constexpr category & operator|=(category & lhs, category rhs) noexcept
0092     {
0093         return (lhs = lhs | rhs);
0094     }
0095 
0096     constexpr category & operator^=(category & lhs, category rhs) noexcept
0097     {
0098         return (lhs = lhs ^ rhs);
0099     }
0100     //!\}
0101 
0102     /// \brief For a given range, return a ranges::category enum with the satisfied
0103     /// concepts.
0104     template<typename Rng>
0105     constexpr category get_categories() noexcept
0106     {
0107         return (input_range<Rng> ? category::input : category::none) |
0108                (forward_range<Rng> ? category::forward : category::none) |
0109                (bidirectional_range<Rng> ? category::bidirectional : category::none) |
0110                (random_access_range<Rng> ? category::random_access : category::none) |
0111                (sized_range<Rng> ? category::sized : category::none);
0112     }
0113 
0114     /// \cond
0115     namespace detail
0116     {
0117         // workaround the fact that typeid ignores cv-qualifiers
0118         template<typename>
0119         struct rtti_tag
0120         {};
0121 
0122         struct any_ref
0123         {
0124             any_ref() = default;
0125             template<typename T>
0126             constexpr any_ref(T & obj) noexcept
0127               : obj_(detail::addressof(obj))
0128 #ifndef NDEBUG
0129               , info_(&typeid(rtti_tag<T>))
0130 #endif
0131             {}
0132             template<typename T>
0133             T & get() const noexcept
0134             {
0135                 RANGES_ASSERT(obj_ && info_ && *info_ == typeid(rtti_tag<T>));
0136                 return *const_cast<T *>(static_cast<T const volatile *>(obj_));
0137             }
0138 
0139         private:
0140             void const volatile * obj_ = nullptr;
0141 #ifndef NDEBUG
0142             std::type_info const * info_ = nullptr;
0143 #endif
0144         };
0145 
0146         template<typename Base>
0147         struct cloneable : Base
0148         {
0149             using Base::Base;
0150             virtual ~cloneable() override = default;
0151             cloneable() = default;
0152             cloneable(cloneable const &) = delete;
0153             cloneable & operator=(cloneable const &) = delete;
0154             virtual std::unique_ptr<cloneable> clone() const = 0;
0155         };
0156 
0157         // clang-format off
0158         /// \concept any_compatible_range_
0159         /// \brief The \c any_compatible_range_ concept
0160         template(typename Rng, typename Ref)(
0161         concept (any_compatible_range_)(Rng, Ref),
0162             convertible_to<range_reference_t<Rng>, Ref>
0163         );
0164         /// \concept any_compatible_range
0165         /// \brief The \c any_compatible_range concept
0166         template<typename Rng, typename Ref>
0167         CPP_concept any_compatible_range =
0168             CPP_concept_ref(detail::any_compatible_range_, Rng, Ref);
0169         // clang-format on
0170 
0171         template<typename Rng, typename = void>
0172         struct any_view_sentinel_impl
0173           : private box<sentinel_t<Rng>, any_view_sentinel_impl<Rng>>
0174         {
0175         private:
0176             using box_t = typename any_view_sentinel_impl::box;
0177 
0178         public:
0179             any_view_sentinel_impl() = default;
0180             any_view_sentinel_impl(Rng & rng)
0181               : box_t(ranges::end(rng))
0182             {}
0183             void init(Rng & rng) noexcept
0184             {
0185                 box_t::get() = ranges::end(rng);
0186             }
0187             sentinel_t<Rng> const & get(Rng &) const noexcept
0188             {
0189                 return box_t::get();
0190             }
0191         };
0192 
0193         template<typename Rng>
0194         struct any_view_sentinel_impl<
0195             Rng, meta::void_<decltype(ranges::end(std::declval<Rng const &>()))>>
0196         {
0197             any_view_sentinel_impl() = default;
0198             any_view_sentinel_impl(Rng &) noexcept
0199             {}
0200             void init(Rng &) noexcept
0201             {}
0202             sentinel_t<Rng> get(Rng & rng) const noexcept
0203             {
0204                 return ranges::end(rng);
0205             }
0206         };
0207 
0208         template<typename Ref, bool Sized = false>
0209         struct any_input_view_interface
0210         {
0211             virtual ~any_input_view_interface() = default;
0212             virtual void init() = 0;
0213             virtual bool done() = 0;
0214             virtual Ref read() const = 0;
0215             virtual void next() = 0;
0216         };
0217         template<typename Ref>
0218         struct any_input_view_interface<Ref, true> : any_input_view_interface<Ref, false>
0219         {
0220             virtual std::size_t size() = 0;
0221         };
0222 
0223         template<typename Ref>
0224         struct any_input_cursor
0225         {
0226             using single_pass = std::true_type;
0227 
0228             any_input_cursor() = default;
0229             constexpr any_input_cursor(any_input_view_interface<Ref> & view) noexcept
0230               : view_{detail::addressof(view)}
0231             {}
0232             Ref read() const
0233             {
0234                 return view_->read();
0235             }
0236             void next()
0237             {
0238                 view_->next();
0239             }
0240             bool equal(any_input_cursor const &) const noexcept
0241             {
0242                 return true;
0243             }
0244             bool equal(default_sentinel_t) const
0245             {
0246                 return !view_ || view_->done();
0247             }
0248 
0249         private:
0250             any_input_view_interface<Ref> * view_ = nullptr;
0251         };
0252 
0253         template<typename Rng, typename Ref, bool Sized = false>
0254         struct RANGES_EMPTY_BASES any_input_view_impl
0255           : any_input_view_interface<Ref, Sized>
0256           , private any_view_sentinel_impl<Rng>
0257         {
0258             CPP_assert(any_compatible_range<Rng, Ref>);
0259             CPP_assert(!Sized || (bool)sized_range<Rng>);
0260 
0261             explicit any_input_view_impl(Rng rng)
0262               : rng_{std::move(rng)}
0263             {}
0264             any_input_view_impl(any_input_view_impl const &) = delete;
0265             any_input_view_impl & operator=(any_input_view_impl const &) = delete;
0266 
0267         private:
0268             using sentinel_box_t = any_view_sentinel_impl<Rng>;
0269 
0270             virtual void init() override
0271             {
0272                 sentinel_box_t::init(rng_);
0273                 current_ = ranges::begin(rng_);
0274             }
0275             virtual bool done() override
0276             {
0277                 return current_ == sentinel_box_t::get(rng_);
0278             }
0279             virtual Ref read() const override
0280             {
0281                 return *current_;
0282             }
0283             virtual void next() override
0284             {
0285                 ++current_;
0286             }
0287             std::size_t size() // override-ish
0288             {
0289                 return static_cast<std::size_t>(ranges::size(rng_));
0290             }
0291 
0292             RANGES_NO_UNIQUE_ADDRESS Rng rng_;
0293             RANGES_NO_UNIQUE_ADDRESS iterator_t<Rng> current_{};
0294         };
0295 
0296         template<typename Ref, category Cat = category::forward, typename enable = void>
0297         struct any_cursor_interface;
0298 
0299         template<typename Ref, category Cat>
0300         struct any_cursor_interface<
0301             Ref, Cat, meta::if_c<(Cat & category::mask) == category::forward>>
0302         {
0303             virtual ~any_cursor_interface() = default;
0304             virtual any_ref iter()
0305                 const = 0; // returns a const ref to the cursor's wrapped iterator
0306             virtual Ref read() const = 0;
0307             virtual bool equal(any_cursor_interface const &) const = 0;
0308             virtual void next() = 0;
0309         };
0310 
0311         template<typename Ref, category Cat>
0312         struct any_cursor_interface<
0313             Ref, Cat, meta::if_c<(Cat & category::mask) == category::bidirectional>>
0314           : any_cursor_interface<Ref, (Cat & ~category::mask) | category::forward>
0315         {
0316             virtual void prev() = 0;
0317         };
0318 
0319         template<typename Ref, category Cat>
0320         struct any_cursor_interface<
0321             Ref, Cat, meta::if_c<(Cat & category::mask) == category::random_access>>
0322           : any_cursor_interface<Ref, (Cat & ~category::mask) | category::bidirectional>
0323         {
0324             virtual void advance(std::ptrdiff_t) = 0;
0325             virtual std::ptrdiff_t distance_to(any_cursor_interface const &) const = 0;
0326         };
0327 
0328         template<typename Ref, category Cat>
0329         using any_cloneable_cursor_interface = cloneable<any_cursor_interface<Ref, Cat>>;
0330 
0331         template<typename I, typename Ref, category Cat>
0332         struct any_cursor_impl : any_cloneable_cursor_interface<Ref, Cat>
0333         {
0334             CPP_assert(convertible_to<iter_reference_t<I>, Ref>);
0335             CPP_assert((Cat & category::forward) == category::forward);
0336 
0337             any_cursor_impl() = default;
0338             any_cursor_impl(I it)
0339               : it_{std::move(it)}
0340             {}
0341 
0342         private:
0343             using Forward =
0344                 any_cursor_interface<Ref, (Cat & ~category::mask) | category::forward>;
0345 
0346             I it_;
0347 
0348             any_ref iter() const override
0349             {
0350                 return it_;
0351             }
0352             Ref read() const override
0353             {
0354                 return *it_;
0355             }
0356             bool equal(Forward const & that_) const override
0357             {
0358                 auto & that = polymorphic_downcast<any_cursor_impl const &>(that_);
0359                 return that.it_ == it_;
0360             }
0361             void next() override
0362             {
0363                 ++it_;
0364             }
0365             std::unique_ptr<any_cloneable_cursor_interface<Ref, Cat>> clone()
0366                 const override
0367             {
0368                 return detail::make_unique<any_cursor_impl>(it_);
0369             }
0370             void prev() // override (sometimes; it's complicated)
0371             {
0372                 --it_;
0373             }
0374             void advance(std::ptrdiff_t n) // override-ish
0375             {
0376                 it_ += n;
0377             }
0378             std::ptrdiff_t distance_to(
0379                 any_cursor_interface<Ref, Cat> const & that_) const // override-ish
0380             {
0381                 auto & that = polymorphic_downcast<any_cursor_impl const &>(that_);
0382                 return static_cast<std::ptrdiff_t>(that.it_ - it_);
0383             }
0384         };
0385 
0386         struct fully_erased_view
0387         {
0388             virtual bool at_end(
0389                 any_ref) = 0; // any_ref is a const ref to a wrapped iterator
0390                               // to be compared to the erased view's last sentinel
0391         protected:
0392             ~fully_erased_view() = default;
0393         };
0394 
0395         struct any_sentinel
0396         {
0397             any_sentinel() = default;
0398             constexpr explicit any_sentinel(fully_erased_view & view) noexcept
0399               : view_{&view}
0400             {}
0401 
0402         private:
0403             template<typename, category>
0404             friend struct any_cursor;
0405 
0406             fully_erased_view * view_ = nullptr;
0407         };
0408 
0409         template<typename Ref, category Cat>
0410         struct any_cursor
0411         {
0412         private:
0413             CPP_assert((Cat & category::forward) == category::forward);
0414 
0415             std::unique_ptr<any_cloneable_cursor_interface<Ref, Cat>> ptr_;
0416 
0417             template<typename Rng>
0418             using impl_t = any_cursor_impl<iterator_t<Rng>, Ref, Cat>;
0419 
0420         public:
0421             any_cursor() = default;
0422             template(typename Rng)(
0423                 requires (!same_as<detail::decay_t<Rng>, any_cursor>) AND
0424                     forward_range<Rng> AND
0425                     any_compatible_range<Rng, Ref>)
0426             explicit any_cursor(Rng && rng)
0427               : ptr_{detail::make_unique<impl_t<Rng>>(begin(rng))}
0428             {}
0429             any_cursor(any_cursor &&) = default;
0430             any_cursor(any_cursor const & that)
0431               : ptr_{that.ptr_ ? that.ptr_->clone() : nullptr}
0432             {}
0433             any_cursor & operator=(any_cursor &&) = default;
0434             any_cursor & operator=(any_cursor const & that)
0435             {
0436                 ptr_ = (that.ptr_ ? that.ptr_->clone() : nullptr);
0437                 return *this;
0438             }
0439             Ref read() const
0440             {
0441                 RANGES_EXPECT(ptr_);
0442                 return ptr_->read();
0443             }
0444             bool equal(any_cursor const & that) const
0445             {
0446                 RANGES_EXPECT(!ptr_ == !that.ptr_);
0447                 return !ptr_ || ptr_->equal(*that.ptr_);
0448             }
0449             bool equal(any_sentinel const & that) const
0450             {
0451                 RANGES_EXPECT(!ptr_ == !that.view_);
0452                 return !ptr_ || that.view_->at_end(ptr_->iter());
0453             }
0454             void next()
0455             {
0456                 RANGES_EXPECT(ptr_);
0457                 ptr_->next();
0458             }
0459             CPP_member
0460             auto prev() //
0461                 -> CPP_ret(void)(
0462                     requires (category::bidirectional == (Cat & category::bidirectional)))
0463             {
0464                 RANGES_EXPECT(ptr_);
0465                 ptr_->prev();
0466             }
0467             CPP_member
0468             auto advance(std::ptrdiff_t n) //
0469                 -> CPP_ret(void)(
0470                     requires (category::random_access == (Cat & category::random_access)))
0471             {
0472                 RANGES_EXPECT(ptr_);
0473                 ptr_->advance(n);
0474             }
0475             CPP_member
0476             auto distance_to(any_cursor const & that) const //
0477                 -> CPP_ret(std::ptrdiff_t)(
0478                     requires (category::random_access == (Cat & category::random_access)))
0479             {
0480                 RANGES_EXPECT(!ptr_ == !that.ptr_);
0481                 return !ptr_ ? 0 : ptr_->distance_to(*that.ptr_);
0482             }
0483         };
0484 
0485         template<typename Ref, category Cat,
0486                  bool = (Cat & category::sized) == category::sized>
0487         struct any_view_interface : fully_erased_view
0488         {
0489             CPP_assert((Cat & category::forward) == category::forward);
0490 
0491             virtual ~any_view_interface() = default;
0492             virtual any_cursor<Ref, Cat> begin_cursor() = 0;
0493         };
0494         template<typename Ref, category Cat>
0495         struct any_view_interface<Ref, Cat, true> : any_view_interface<Ref, Cat, false>
0496         {
0497             virtual std::size_t size() = 0;
0498         };
0499 
0500         template<typename Ref, category Cat>
0501         using any_cloneable_view_interface = cloneable<any_view_interface<Ref, Cat>>;
0502 
0503         template<typename Rng, typename Ref, category Cat>
0504         struct RANGES_EMPTY_BASES any_view_impl
0505           : any_cloneable_view_interface<Ref, Cat>
0506           , private box<Rng, any_view_impl<Rng, Ref, Cat>>
0507           , private any_view_sentinel_impl<Rng>
0508         {
0509             CPP_assert((Cat & category::forward) == category::forward);
0510             CPP_assert(any_compatible_range<Rng, Ref>);
0511             CPP_assert((Cat & category::sized) == category::none ||
0512                        (bool)sized_range<Rng>);
0513 
0514             any_view_impl() = default;
0515             any_view_impl(Rng rng)
0516               : range_box_t{std::move(rng)}
0517               , sentinel_box_t{range_box_t::get()}
0518             // NB: initialization order dependence
0519             {}
0520 
0521         private:
0522             using range_box_t = box<Rng, any_view_impl>;
0523             using sentinel_box_t = any_view_sentinel_impl<Rng>;
0524 
0525             any_cursor<Ref, Cat> begin_cursor() override
0526             {
0527                 return any_cursor<Ref, Cat>{range_box_t::get()};
0528             }
0529             bool at_end(any_ref it_) override
0530             {
0531                 auto & it = it_.get<iterator_t<Rng> const>();
0532                 return it == sentinel_box_t::get(range_box_t::get());
0533             }
0534             std::unique_ptr<any_cloneable_view_interface<Ref, Cat>> clone() const override
0535             {
0536                 return detail::make_unique<any_view_impl>(range_box_t::get());
0537             }
0538             std::size_t size() // override-ish
0539             {
0540                 return static_cast<std::size_t>(ranges::size(range_box_t::get()));
0541             }
0542         };
0543     } // namespace detail
0544     /// \endcond
0545 
0546     /// \brief A type-erased view
0547     /// \ingroup group-views
0548     template<typename Ref, category Cat = category::input, typename enable = void>
0549     struct any_view
0550       : view_facade<any_view<Ref, Cat>,
0551                     (Cat & category::sized) == category::sized ? finite : unknown>
0552     {
0553         friend range_access;
0554         CPP_assert((Cat & category::forward) == category::forward);
0555 
0556         any_view() = default;
0557         template(typename Rng)(
0558             requires //
0559                 (!same_as<detail::decay_t<Rng>, any_view>) AND
0560                 input_range<Rng> AND
0561                 detail::any_compatible_range<Rng, Ref>)
0562         any_view(Rng && rng)
0563           : any_view(static_cast<Rng &&>(rng),
0564                      meta::bool_<(get_categories<Rng>() & Cat) == Cat>{})
0565         {}
0566         any_view(any_view &&) = default;
0567         any_view(any_view const & that)
0568           : ptr_{that.ptr_ ? that.ptr_->clone() : nullptr}
0569         {}
0570         any_view & operator=(any_view &&) = default;
0571         any_view & operator=(any_view const & that)
0572         {
0573             ptr_ = (that.ptr_ ? that.ptr_->clone() : nullptr);
0574             return *this;
0575         }
0576 
0577         CPP_member
0578         auto size() //
0579             -> CPP_ret(std::size_t)(
0580                 requires (category::sized == (Cat & category::sized)))
0581         {
0582             return ptr_ ? ptr_->size() : 0;
0583         }
0584 
0585     private:
0586         template<typename Rng>
0587         using impl_t = detail::any_view_impl<views::all_t<Rng>, Ref, Cat>;
0588         template<typename Rng>
0589         any_view(Rng && rng, std::true_type)
0590           : ptr_{detail::make_unique<impl_t<Rng>>(views::all(static_cast<Rng &&>(rng)))}
0591         {}
0592         template<typename Rng>
0593         any_view(Rng &&, std::false_type)
0594         {
0595             static_assert(
0596                 (get_categories<Rng>() & Cat) == Cat,
0597                 "The range passed to any_view() does not model the requested category");
0598         }
0599 
0600         detail::any_cursor<Ref, Cat> begin_cursor()
0601         {
0602             return ptr_ ? ptr_->begin_cursor() : detail::value_init{};
0603         }
0604         detail::any_sentinel end_cursor() noexcept
0605         {
0606             return detail::any_sentinel{*ptr_};
0607         }
0608 
0609         std::unique_ptr<detail::any_cloneable_view_interface<Ref, Cat>> ptr_;
0610     };
0611 
0612     // input and not forward
0613     template<typename Ref, category Cat>
0614     struct any_view<Ref, Cat, meta::if_c<(Cat & category::forward) == category::input>>
0615       : view_facade<any_view<Ref, Cat, void>,
0616                     (Cat & category::sized) == category::sized ? finite : unknown>
0617     {
0618         friend range_access;
0619 
0620         any_view() = default;
0621         template(typename Rng)(
0622             requires //
0623                 (!same_as<detail::decay_t<Rng>, any_view>) AND
0624                 input_range<Rng> AND
0625                 detail::any_compatible_range<Rng, Ref>)
0626         any_view(Rng && rng)
0627           : ptr_{std::make_shared<impl_t<Rng>>(views::all(static_cast<Rng &&>(rng)))}
0628         {}
0629 
0630         CPP_member
0631         auto size() //
0632             -> CPP_ret(std::size_t)(
0633                 requires (category::sized == (Cat & category::sized)))
0634         {
0635             return ptr_ ? ptr_->size() : 0;
0636         }
0637 
0638     private:
0639         template<typename Rng>
0640         using impl_t =
0641             detail::any_input_view_impl<views::all_t<Rng>, Ref,
0642                                         (Cat & category::sized) == category::sized>;
0643 
0644         detail::any_input_cursor<Ref> begin_cursor()
0645         {
0646             if(!ptr_)
0647                 return {};
0648 
0649             ptr_->init();
0650             return detail::any_input_cursor<Ref>{*ptr_};
0651         }
0652 
0653         std::shared_ptr<detail::any_input_view_interface<Ref, (Cat & category::sized) ==
0654                                                                   category::sized>>
0655             ptr_;
0656     };
0657 
0658 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0659     template(typename Rng)(
0660         requires view_<Rng>)
0661         any_view(Rng &&)
0662             ->any_view<range_reference_t<Rng>, get_categories<Rng>()>;
0663 #endif
0664 
0665     template<typename Ref>
0666     using any_input_view RANGES_DEPRECATED(
0667         "Use any_view<Ref, category::input> instead.") = any_view<Ref, category::input>;
0668 
0669     template<typename Ref>
0670     using any_forward_view RANGES_DEPRECATED(
0671         "Use any_view<Ref, category::forward> instead.") =
0672         any_view<Ref, category::forward>;
0673 
0674     template<typename Ref>
0675     using any_bidirectional_view RANGES_DEPRECATED(
0676         "Use any_view<Ref, category::bidirectional> instead.") =
0677         any_view<Ref, category::bidirectional>;
0678 
0679     template<typename Ref>
0680     using any_random_access_view RANGES_DEPRECATED(
0681         "Use any_view<Ref, category::random_access> instead.") =
0682         any_view<Ref, category::random_access>;
0683 } // namespace ranges
0684 
0685 #include <range/v3/detail/satisfy_boost_range.hpp>
0686 RANGES_SATISFY_BOOST_RANGE(::ranges::any_view)
0687 
0688 RANGES_DIAGNOSTIC_POP
0689 
0690 #include <range/v3/detail/epilogue.hpp>
0691 
0692 #endif