File indexing completed on 2025-01-18 10:09:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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
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 }
0050
0051
0052
0053
0054
0055
0056
0057
0058
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
0066
0067
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
0077
0078 template<typename T>
0079 CPP_concept container =
0080 semi_container<T> &&
0081 CPP_concept_ref(ranges::container_, T);
0082
0083
0084
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
0099
0100 template<typename C>
0101 CPP_concept reservable =
0102 container<C> && sized_range<C> && CPP_requires_ref(ranges::reservable_, C);
0103
0104
0105
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
0113
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
0121
0122 template<typename C>
0123 CPP_concept random_access_reservable =
0124 reservable<C> && random_access_range<C>;
0125
0126
0127
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 }
0164
0165
0166
0167
0168
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
0174
0175 template<typename T>
0176 CPP_concept lvalue_container_like =
0177 forward_range<T> &&
0178 CPP_concept_ref(ranges::lvalue_container_like_, T);
0179
0180
0181 }
0182
0183 #include <range/v3/detail/epilogue.hpp>
0184
0185 #endif