Back to home page

EIC code displayed by LXR

 
 

    


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

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_CONCEPTS_HPP
0015 #define RANGES_V3_ACTION_CONCEPTS_HPP
0016 
0017 #include <utility>
0018 
0019 #include <meta/meta.hpp>
0020 
0021 #include <range/v3/range_fwd.hpp>
0022 
0023 #include <range/v3/range/concepts.hpp>
0024 #include <range/v3/range/traits.hpp>
0025 
0026 #include <range/v3/detail/prologue.hpp>
0027 
0028 namespace ranges
0029 {
0030     /// \cond
0031     namespace detail
0032     {
0033         template<typename T>
0034         struct movable_input_iterator
0035         {
0036             using iterator_category = std::input_iterator_tag;
0037             using value_type = T;
0038             using difference_type = std::ptrdiff_t;
0039             using pointer = T *;
0040             using reference = T &&;
0041 
0042             movable_input_iterator() = default;
0043             movable_input_iterator & operator++();
0044             movable_input_iterator operator++(int);
0045             bool operator==(movable_input_iterator const &) const;
0046             bool operator!=(movable_input_iterator const &) const;
0047             T && operator*() const;
0048         };
0049     } // namespace detail
0050       /// \endcond
0051 
0052     /// \addtogroup group-range
0053     /// @{
0054 
0055     // clang-format off
0056     /// \concept semi_container
0057     /// \brief The \c semi_container concept
0058     /// \c std::array is a \c semi_container, native arrays are not.
0059     template<typename T>
0060     CPP_concept semi_container =
0061         forward_range<T> && default_constructible<uncvref_t<T>> &&
0062         movable<uncvref_t<T>> &&
0063         !view_<T>;
0064 
0065     /// \concept container_
0066     /// \brief The \c container_ concept
0067     /// \c std::vector is a container, \c std::array is not
0068     template(typename T)(
0069     concept (container_)(T),
0070         constructible_from<
0071             uncvref_t<T>,
0072             detail::movable_input_iterator<range_value_t<T>>,
0073             detail::movable_input_iterator<range_value_t<T>>>
0074     );
0075 
0076     /// \concept container
0077     /// \brief The \c container concept
0078     template<typename T>
0079     CPP_concept container =
0080         semi_container<T> &&
0081         CPP_concept_ref(ranges::container_, T);
0082 
0083     /// \concept reservable_
0084     /// \brief The \c reservable_ concept
0085     template<typename C>
0086     CPP_requires(reservable_,
0087         requires(C & c, C const & cc) //
0088         (
0089             c.reserve(ranges::size(c)),
0090             cc.capacity(),
0091             cc.max_size(),
0092             concepts::requires_<same_as<decltype(cc.capacity()),
0093                                         decltype(ranges::size(c))>>,
0094             concepts::requires_<same_as<decltype(cc.max_size()),
0095                                         decltype(ranges::size(c))>>
0096         ));
0097 
0098     /// \concept reservable
0099     /// \brief The \c reservable concept
0100     template<typename C>
0101     CPP_concept reservable =
0102         container<C> && sized_range<C> && CPP_requires_ref(ranges::reservable_, C);
0103 
0104     /// \concept reservable_with_assign_
0105     /// \brief The \c reservable_with_assign_ concept
0106     template<typename C, typename I>
0107     CPP_requires(reservable_with_assign_,
0108         requires(C & c, I i) //
0109         (
0110             c.assign(i, i)
0111         ));
0112     /// \concept reservable_with_assign
0113     /// \brief The \c reservable_with_assign concept
0114     template<typename C, typename I>
0115     CPP_concept reservable_with_assign =
0116         reservable<C> && //
0117         input_iterator<I> && //
0118         CPP_requires_ref(ranges::reservable_with_assign_, C, I);
0119 
0120     /// \concept random_access_reservable
0121     /// \brief The \c random_access_reservable concept
0122     template<typename C>
0123     CPP_concept random_access_reservable =
0124         reservable<C> && random_access_range<C>;
0125     // clang-format on
0126 
0127     /// \cond
0128     namespace detail
0129     {
0130         template(typename T)(
0131             requires container<T>)
0132         std::true_type is_lvalue_container_like(T &) noexcept
0133         {
0134             return {};
0135         }
0136 
0137         template(typename T)(
0138             requires container<T>)
0139         meta::not_<std::is_rvalue_reference<T>> //
0140         is_lvalue_container_like(reference_wrapper<T>) noexcept
0141         {
0142             return {};
0143         }
0144 
0145         template(typename T)(
0146             requires container<T>)
0147         std::true_type is_lvalue_container_like(std::reference_wrapper<T>) noexcept
0148         {
0149             return {};
0150         }
0151 
0152         template(typename T)(
0153             requires container<T>)
0154         std::true_type is_lvalue_container_like(ref_view<T>) noexcept
0155         {
0156             return {};
0157         }
0158 
0159         template<typename T>
0160         using is_lvalue_container_like_t =
0161             decltype(detail::is_lvalue_container_like(std::declval<T>()));
0162 
0163     } // namespace detail
0164       /// \endcond
0165 
0166     // clang-format off
0167     /// \concept lvalue_container_like_
0168     /// \brief The \c lvalue_container_like_ concept
0169     template(typename T)(
0170     concept (lvalue_container_like_)(T),
0171         implicitly_convertible_to<detail::is_lvalue_container_like_t<T>, std::true_type>
0172     );
0173     /// \concept lvalue_container_like
0174     /// \brief The \c lvalue_container_like concept
0175     template<typename T>
0176     CPP_concept lvalue_container_like =
0177         forward_range<T> &&
0178         CPP_concept_ref(ranges::lvalue_container_like_, T);
0179     // clang-format on
0180     /// @}
0181 } // namespace ranges
0182 
0183 #include <range/v3/detail/epilogue.hpp>
0184 
0185 #endif