Back to home page

EIC code displayed by LXR

 
 

    


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

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_VIEW_FACADE_HPP
0014 #define RANGES_V3_VIEW_FACADE_HPP
0015 
0016 #include <type_traits>
0017 #include <utility>
0018 
0019 #include <meta/meta.hpp>
0020 
0021 #include <concepts/concepts.hpp>
0022 
0023 #include <range/v3/range_fwd.hpp>
0024 
0025 #include <range/v3/iterator/basic_iterator.hpp>
0026 #include <range/v3/iterator/default_sentinel.hpp>
0027 #include <range/v3/iterator/traits.hpp>
0028 #include <range/v3/view/interface.hpp>
0029 
0030 #include <range/v3/detail/prologue.hpp>
0031 
0032 namespace ranges
0033 {
0034     /// \cond
0035     namespace detail
0036     {
0037         template<typename Derived>
0038         using begin_cursor_t = detail::decay_t<decltype(
0039             range_access::begin_cursor(std::declval<Derived &>()))>;
0040 
0041         template<typename Derived>
0042         using end_cursor_t = detail::decay_t<decltype(
0043             range_access::end_cursor(std::declval<Derived &>()))>;
0044 
0045         template<typename Derived>
0046         using facade_iterator_t = basic_iterator<begin_cursor_t<Derived>>;
0047 
0048         template<typename Derived>
0049         using facade_sentinel_t =
0050             meta::if_c<same_as<begin_cursor_t<Derived>, end_cursor_t<Derived>>,
0051                        facade_iterator_t<Derived>, end_cursor_t<Derived>>;
0052     } // namespace detail
0053     /// \endcond
0054 
0055     /// \addtogroup group-views
0056     /// @{
0057 
0058     /// \brief A utility for constructing a view from a (derived) type that
0059     /// implements begin and end cursors.
0060     /// \tparam Derived A type that derives from `view_facade` and implements
0061     /// begin and end cursors. This type is permitted to be incomplete.
0062     /// \tparam Cardinality The cardinality of this view: `finite`, `infinite`,
0063     /// or `unknown`. See `ranges::cardinality`.
0064     template<typename Derived, cardinality Cardinality>
0065     struct view_facade : view_interface<Derived, Cardinality>
0066     {
0067     protected:
0068         friend range_access;
0069         struct view_as_cursor : Derived
0070         {
0071             view_as_cursor() = default;
0072             explicit view_as_cursor(Derived const * derived)
0073               : Derived(*derived)
0074             {}
0075             explicit operator bool() = delete;
0076             explicit operator bool() const = delete;
0077         };
0078         // Default implementations
0079         constexpr view_as_cursor begin_cursor() const
0080         {
0081             return view_as_cursor{static_cast<Derived const *>(this)};
0082         }
0083         constexpr default_sentinel_t end_cursor() const
0084         {
0085             return {};
0086         }
0087 
0088     public:
0089         /// Let `d` be `static_cast<Derived &>(*this)`. Let `b` be
0090         /// `std::as_const(d).begin_cursor()` if that expression is well-formed;
0091         /// otherwise, let `b` be `d.begin_cursor()`. Let `B` be the type of
0092         /// `b`.
0093         /// \return `ranges::basic_iterator<B>(b)`
0094         template(typename D = Derived)(
0095             requires same_as<D, Derived>)
0096         constexpr auto begin() -> detail::facade_iterator_t<D>
0097         {
0098             return detail::facade_iterator_t<D>{
0099                 range_access::begin_cursor(*static_cast<Derived *>(this))};
0100         }
0101         /// \overload
0102         template(typename D = Derived)(
0103             requires same_as<D, Derived>)
0104         constexpr auto begin() const -> detail::facade_iterator_t<D const>
0105         {
0106             return detail::facade_iterator_t<D const>{
0107                 range_access::begin_cursor(*static_cast<Derived const *>(this))};
0108         }
0109         /// Let `d` be `static_cast<Derived &>(*this)`. Let `e` be
0110         /// `std::as_const(d).end_cursor()` if that expression is well-formed;
0111         /// otherwise, let `e` be `d.end_cursor()`. Let `E` be the type of
0112         /// `e`.
0113         /// \return `ranges::basic_iterator<E>(e)` if `E` is the same
0114         /// as `B` computed above for `begin()`; otherwise, return `e`.
0115         template(typename D = Derived)(
0116             requires same_as<D, Derived>)
0117         constexpr auto end() -> detail::facade_sentinel_t<D>
0118         {
0119             return static_cast<detail::facade_sentinel_t<D>>(
0120                 range_access::end_cursor(*static_cast<Derived *>(this)));
0121         }
0122         /// \overload
0123         template(typename D = Derived)(
0124             requires same_as<D, Derived>)
0125         constexpr auto end() const -> detail::facade_sentinel_t<D const>
0126         {
0127             return static_cast<detail::facade_sentinel_t<D const>>(
0128                 range_access::end_cursor(*static_cast<Derived const *>(this)));
0129         }
0130     };
0131 
0132     /// @}
0133 } // namespace ranges
0134 
0135 #include <range/v3/detail/epilogue.hpp>
0136 
0137 #endif