Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/parser/detail/stl_interfaces/view_interface.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // Copyright (C) 2019 T. Zachary Laine
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See
0004 // accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 #ifndef BOOST_PARSER_DETAIL_STL_INTERFACES_VIEW_INTERFACE_HPP
0007 #define BOOST_PARSER_DETAIL_STL_INTERFACES_VIEW_INTERFACE_HPP
0008 
0009 #include <boost/parser/detail/stl_interfaces/fwd.hpp>
0010 
0011 
0012 namespace boost::parser::detail { namespace stl_interfaces { BOOST_PARSER_DETAIL_STL_INTERFACES_NAMESPACE_V1 {
0013 
0014     /** A CRTP template that one may derive from to make it easier to define
0015         `std::ranges::view`-like types with a container-like interface.  This
0016         is a pre-C++20 version of C++20's `view_interface` (see
0017         [view.interface] in the C++ standard).
0018 
0019         The template parameter `D` for `view_interface` may be an incomplete
0020         type.  Before any member of the resulting specialization of
0021         `view_interface` other than special member functions is referenced,
0022         `D` shall be complete, and model both
0023         `std::derived_from<view_interface<D>>` and `std::view`. */
0024     template<
0025         typename Derived,
0026         element_layout Contiguity = element_layout::discontiguous
0027 #ifndef BOOST_STL_INTERFACES_DOXYGEN
0028         ,
0029         typename E = std::enable_if_t<
0030             std::is_class<Derived>::value &&
0031             std::is_same<Derived, std::remove_cv_t<Derived>>::value>
0032 #endif
0033         >
0034     struct view_interface;
0035 
0036     namespace v1_dtl {
0037         template<typename D, element_layout Contiguity>
0038         void derived_view(view_interface<D, Contiguity> const &);
0039     }
0040 
0041     template<
0042         typename Derived,
0043         element_layout Contiguity
0044 #ifndef BOOST_STL_INTERFACES_DOXYGEN
0045         ,
0046         typename E
0047 #endif
0048         >
0049     struct view_interface
0050     {
0051 #ifndef BOOST_STL_INTERFACES_DOXYGEN
0052     private:
0053         constexpr Derived & derived() noexcept
0054         {
0055             return static_cast<Derived &>(*this);
0056         }
0057         constexpr const Derived & derived() const noexcept
0058         {
0059             return static_cast<Derived const &>(*this);
0060         }
0061 #endif
0062 
0063     public:
0064         template<typename D = Derived>
0065         constexpr auto empty() noexcept(
0066             noexcept(std::declval<D &>().begin() == std::declval<D &>().end()))
0067             -> decltype(
0068                 std::declval<D &>().begin() == std::declval<D &>().end())
0069         {
0070             return derived().begin() == derived().end();
0071         }
0072         template<typename D = Derived>
0073         constexpr auto empty() const noexcept(noexcept(
0074             std::declval<D const &>().begin() ==
0075             std::declval<D const &>().end()))
0076             -> decltype(
0077                 std::declval<D const &>().begin() ==
0078                 std::declval<D const &>().end())
0079         {
0080             return derived().begin() == derived().end();
0081         }
0082 
0083         template<
0084             typename D = Derived,
0085             typename R = decltype(std::declval<D &>().empty())>
0086         constexpr explicit
0087         operator bool() noexcept(noexcept(std::declval<D &>().empty()))
0088         {
0089             return !derived().empty();
0090         }
0091         template<
0092             typename D = Derived,
0093             typename R = decltype(std::declval<D const &>().empty())>
0094         constexpr explicit operator bool() const
0095             noexcept(noexcept(std::declval<D const &>().empty()))
0096         {
0097             return !derived().empty();
0098         }
0099 
0100         template<
0101             typename D = Derived,
0102             element_layout C = Contiguity,
0103             typename Enable = std::enable_if_t<C == element_layout::contiguous>>
0104         constexpr auto data() noexcept(noexcept(std::declval<D &>().begin()))
0105             -> decltype(std::addressof(*std::declval<D &>().begin()))
0106         {
0107             return std::addressof(*derived().begin());
0108         }
0109         template<
0110             typename D = Derived,
0111             element_layout C = Contiguity,
0112             typename Enable = std::enable_if_t<C == element_layout::contiguous>>
0113         constexpr auto data() const
0114             noexcept(noexcept(std::declval<D const &>().begin()))
0115                 -> decltype(std::addressof(*std::declval<D const &>().begin()))
0116         {
0117             return std::addressof(*derived().begin());
0118         }
0119 
0120         template<typename D = Derived>
0121         constexpr auto size() noexcept(
0122             noexcept(std::declval<D &>().end() - std::declval<D &>().begin()))
0123             -> decltype(std::declval<D &>().end() - std::declval<D &>().begin())
0124         {
0125             return derived().end() - derived().begin();
0126         }
0127         template<typename D = Derived>
0128         constexpr auto size() const noexcept(noexcept(
0129             std::declval<D const &>().end() -
0130             std::declval<D const &>().begin()))
0131             -> decltype(
0132                 std::declval<D const &>().end() -
0133                 std::declval<D const &>().begin())
0134         {
0135             return derived().end() - derived().begin();
0136         }
0137 
0138         template<typename D = Derived>
0139         constexpr auto front() noexcept(noexcept(*std::declval<D &>().begin()))
0140             -> decltype(*std::declval<D &>().begin())
0141         {
0142             return *derived().begin();
0143         }
0144         template<typename D = Derived>
0145         constexpr auto front() const
0146             noexcept(noexcept(*std::declval<D const &>().begin()))
0147                 -> decltype(*std::declval<D const &>().begin())
0148         {
0149             return *derived().begin();
0150         }
0151 
0152         template<
0153             typename D = Derived,
0154             typename Enable = std::enable_if_t<
0155                 v1_dtl::decrementable_sentinel<D>::value &&
0156                 v1_dtl::common_range<D>::value>>
0157         constexpr auto
0158         back() noexcept(noexcept(*std::prev(std::declval<D &>().end())))
0159             -> decltype(*std::prev(std::declval<D &>().end()))
0160         {
0161             return *std::prev(derived().end());
0162         }
0163         template<
0164             typename D = Derived,
0165             typename Enable = std::enable_if_t<
0166                 v1_dtl::decrementable_sentinel<D>::value &&
0167                 v1_dtl::common_range<D>::value>>
0168         constexpr auto back() const
0169             noexcept(noexcept(*std::prev(std::declval<D const &>().end())))
0170                 -> decltype(*std::prev(std::declval<D const &>().end()))
0171         {
0172             return *std::prev(derived().end());
0173         }
0174 
0175         template<typename D = Derived>
0176         constexpr auto operator[](v1_dtl::range_difference_t<D> n) noexcept(
0177             noexcept(std::declval<D &>().begin()[n]))
0178             -> decltype(std::declval<D &>().begin()[n])
0179         {
0180             return derived().begin()[n];
0181         }
0182         template<typename D = Derived>
0183         constexpr auto operator[](v1_dtl::range_difference_t<D> n) const
0184             noexcept(noexcept(std::declval<D const &>().begin()[n]))
0185                 -> decltype(std::declval<D const &>().begin()[n])
0186         {
0187             return derived().begin()[n];
0188         }
0189     };
0190 
0191     /** Implementation of `operator!=()` for all views derived from
0192         `view_interface`. */
0193     template<typename ViewInterface>
0194     constexpr auto operator!=(ViewInterface lhs, ViewInterface rhs) noexcept(
0195         noexcept(lhs == rhs))
0196         -> decltype(v1_dtl::derived_view(lhs), !(lhs == rhs))
0197     {
0198         return !(lhs == rhs);
0199     }
0200 
0201 }}}
0202 
0203 
0204 #if defined(BOOST_STL_INTERFACES_DOXYGEN) || BOOST_PARSER_DETAIL_STL_INTERFACES_USE_CONCEPTS
0205 
0206 namespace boost::parser::detail { namespace stl_interfaces { BOOST_PARSER_DETAIL_STL_INTERFACES_NAMESPACE_V2 {
0207 
0208     /** A template alias for `std::ranges::view_interface`.  This only exists
0209         to make migration from Boost.STLInterfaces to C++20 easier; switch to
0210         the one in `std` as soon as you can. */
0211     template<typename D, element_layout = element_layout::discontiguous>
0212     using view_interface = std::ranges::view_interface<D>;
0213 
0214 }}}
0215 
0216 namespace boost::parser::detail { namespace stl_interfaces { BOOST_PARSER_DETAIL_STL_INTERFACES_NAMESPACE_V3 {
0217 
0218     /** A template alias for `std::ranges::view_interface`.  This only exists
0219         to make migration from Boost.STLInterfaces to C++20 easier; switch to
0220         the one in `std` as soon as you can. */
0221     template<typename D, element_layout = element_layout::discontiguous>
0222     using view_interface = std::ranges::view_interface<D>;
0223 
0224 }}}
0225 
0226 #endif
0227 
0228 #endif