5 #ifndef VCCC_RANGES_SUBRANGE_HPP 
    6 #define VCCC_RANGES_SUBRANGE_HPP 
   10 #include <type_traits> 
   49 template<
typename From, 
typename To>
 
   50 struct convertible_to_non_slicing
 
   52           convertible_to<From, To>,
 
   55                   negation< std::is_pointer<From> >,
 
   56                   negation< std::is_pointer<To>   >
 
   58               std::is_convertible<std::remove_pointer_t<From>(*)[], std::remove_pointer_t<To>(*)[]>
 
   62 template<
typename T, 
typename U>
 
   63 struct different_from : negation<same_as<std::decay_t<T>, std::decay_t<U>>> {};
 
   66 struct make_unsigned_like {};
 
   68 struct make_unsigned_like<T, true> {
 
   69   using type = std::make_unsigned_t<T>;
 
   72 using make_unsigned_like_t = 
typename make_unsigned_like<T>::type;
 
   75 struct pair_like_convertible_from
 
   78           negation< std::is_reference<T> >,
 
   79           constructible_from<T, U, V>,
 
   80           convertible_to_non_slicing<U, std::tuple_element_t<0, T>>,
 
   81           convertible_to<V, std::tuple_element_t<1, T>>
 
   84 template<
typename T, 
typename U, 
typename V>
 
   85 struct pair_like_convertible_from<T, U, V, false> : std::false_type {};
 
   88 struct borrowed_range_difference {
 
   89   using type = range_difference_t<R>;
 
   92 struct borrowed_range_difference<R, false> {};
 
   94 using borrowed_range_difference_t = 
typename borrowed_range_difference<R>::type;
 
  101 struct is_subrange_constructible
 
  103           input_or_output_iterator<I>,
 
  106             bool_constant<(K == subrange_kind::sized)>,
 
  107             negation< sized_sentinel_for<S, I> >
 
  111 template<
typename I, 
typename S, 
bool Store >
 
  112 struct subrange_size {
 
  113   constexpr subrange_size() = 
default;
 
  115   constexpr subrange_size(in_place_t, U) noexcept {}
 
  118 template<
typename I, 
typename S>
 
  119 struct subrange_size<I, S, true> {
 
  120   constexpr subrange_size() = 
default;
 
  122   constexpr subrange_size(in_place_t, U n) : size_(n) {}
 
  124   std::make_unsigned_t<iter_difference_t<I>> size_ = 0;
 
  128 struct subrange_ctor_range
 
  130           convertible_to_non_slicing<iterator_t<R>, I>,
 
  131           convertible_to<sentinel_t<R>, S>
 
  134 template<
typename I, 
typename S, 
typename R>
 
  135 struct subrange_ctor_range<I, S, R, false> : std::false_type {};
 
  150     , detail::subrange_size<I, S, (K == subrange_kind::sized && sized_sentinel_for<S, I>::value == false)>
 
  153   using size_base = detail::subrange_size<I, S, store_size::value>;
 
  161   template<
typename I2, std::enable_if_t<
conjunction<
 
  162       detail::convertible_to_non_slicing<I2, I>,
 
  166       : iterator_(
std::move(i)), sentinel_(
std::move(s)) {}
 
  168   template<
typename I2, std::enable_if_t<
conjunction<
 
  169       detail::convertible_to_non_slicing<I2, I>,
 
  173       : size_base(
in_place, n), iterator_(
std::move(i)), sentinel_(
std::move(s)) {}
 
  176       detail::different_from<subrange, R>,
 
  177       detail::subrange_ctor_range<I, S, R>,
 
  187       detail::subrange_ctor_range<I, S, R>,
 
  194   template<
typename PairLike, std::enable_if_t<
conjunction<
 
  196       detail::pair_like_convertible_from<PairLike, const I&, const S&>
 
  198   constexpr 
operator PairLike()
 const {
 
  199     return PairLike(iterator_, sentinel_);
 
  210     return std::move(iterator_);
 
  219     return iterator_ == sentinel_;
 
  226   constexpr detail::make_unsigned_like_t<iter_difference_t<I>> 
size()
 const {
 
  227     return static_cast<detail::make_unsigned_like_t<iter_difference_t<I>
>>(sentinel_ - iterator_);
 
  234   constexpr detail::make_unsigned_like_t<iter_difference_t<I>> 
size()
 const {
 
  235     return size_base::size_;
 
  260     return std::move(*
this);
 
  270 template<
typename I, 
typename S, std::enable_if_t<
conjunction<
 
  274 constexpr subrange<I, S>
 
  279 template<
typename I, 
typename S, std::enable_if_t<
conjunction<
 
  283 constexpr subrange<I, S, subrange_kind::sized>
 
  289 constexpr subrange<iterator_t<R>, sentinel_t<R>,
 
  294   return {std::forward<R>(r)};
 
  300   return {std::forward<R>(r), n};
 
  304 #if __cplusplus >= 201703L 
  315 template<
typename I, 
typename S>
 
  317     subrange<I, S, ranges::subrange_kind::sized>;
 
  331 struct is_size_storing_subrange;
 
  333 template<
typename I, 
typename S, subrange_kind K>
 
  334 struct is_size_storing_subrange<
subrange<I, S, K>>
 
  335     : 
bool_constant<(K == subrange_kind::sized && sized_sentinel_for<S, I>::value == false)> {};
 
  337 template<std::
size_t N>
 
  340 template<> 
struct get_subrange<0> {
 
  341   template<
typename I, 
typename S, subrange_kind K>
 
  342   static constexpr 
auto get(
const subrange<I, S, K>& r) {
 
  345   template<
typename I, 
typename S, subrange_kind K>
 
  346   static constexpr 
auto get(subrange<I, S, K>&& r) {
 
  347     return std::move(r.begin());
 
  351 template<> 
struct get_subrange<1> {
 
  352   template<
typename I, 
typename S, subrange_kind K>
 
  353   auto get(
const subrange<I, S, K>& r) {
 
  356   template<
typename I, 
typename S, subrange_kind K>
 
  357   auto get(subrange<I, S, K>&& r) {
 
  358     return std::move(r.end());
 
  363 struct is_subrange : std::false_type {};
 
  364 template<
typename I, 
typename S, subrange_kind K>
 
  365 struct is_subrange<
subrange<I, S, K>> : std::true_type {};
 
  369 template<std::size_t N, 
typename I, 
typename S, 
subrange_kind K,
 
  375 template<std::size_t N, 
typename I, 
typename S, 
subrange_kind K,
 
  376     std::enable_if_t<(N < 2), int> = 0>
 
  381 template<
typename I, 
typename S, subrange_kind K>
 
  390 template<
typename I, 
typename S, ranges::subrange_kind K>
 
  391 struct tuple_like_uncvref<ranges::subrange<I, S, K>> : std::true_type {};
 
  397 template<
typename I, 
typename S, vccc::ranges::subrange_kind K>
 
  398 struct std::tuple_size<
vccc::ranges::subrange<I, S, K>> : std::integral_constant<std::size_t, 2> {};
 
  404 template<
typename I, 
typename S, vccc::ranges::subrange_kind K>
 
  405 struct tuple_element<0, 
vccc::ranges::subrange<I, S, K>> { 
using type = I; };
 
  406 template<
typename I, 
typename S, vccc::ranges::subrange_kind K>
 
  407 struct tuple_element<0, const 
vccc::ranges::subrange<I, S, K>> { 
using type = I; };
 
  408 template<
typename I, 
typename S, vccc::ranges::subrange_kind K>
 
  409 struct tuple_element<1, 
vccc::ranges::subrange<I, S, K>> { 
using type = S; };
 
  410 template<
typename I, 
typename S, vccc::ranges::subrange_kind K>
 
  411 struct tuple_element<1, const 
vccc::ranges::subrange<I, S, K>> { 
using type = S; };
 
Definition: subrange.hpp:151
 
constexpr VCCC_NODISCARD subrange_kind next(iter_difference_t< I > n=1) const &
Definition: subrange.hpp:251
 
constexpr subrange(R &&r)
Definition: subrange.hpp:183
 
constexpr S end() const
Definition: subrange.hpp:213
 
constexpr VCCC_NODISCARD subrange_kind prev(iter_difference_t< I > n=1) const
Definition: subrange.hpp:244
 
constexpr subrange(R &&r, detail::make_unsigned_like_t< iter_difference_t< I >> n)
Definition: subrange.hpp:190
 
constexpr subrange(I2 i, S s, detail::make_unsigned_like_t< iter_difference_t< I >> n)
Definition: subrange.hpp:172
 
constexpr VCCC_NODISCARD I begin()
Definition: subrange.hpp:209
 
constexpr I begin() const
Definition: subrange.hpp:204
 
constexpr subrange & advance(iter_difference_t< I > n)
Definition: subrange.hpp:238
 
constexpr detail::make_unsigned_like_t< iter_difference_t< I > > size() const
Definition: subrange.hpp:226
 
constexpr bool empty() const
Definition: subrange.hpp:217
 
constexpr VCCC_NODISCARD subrange_kind next(iter_difference_t< I > n=1) &&
Definition: subrange.hpp:258
 
constexpr subrange(I2 i, S s)
Definition: subrange.hpp:165
 
helper class template for defining a view, using the curiously recurring template pattern
Definition: view_interface.hpp:78
 
constexpr VCCC_INLINE_OR_STATIC detail::advance_niebloid advance
Definition: advance.hpp:158
 
typename iter_difference< T >::type iter_difference_t
Computes the difference type of T
Definition: iter_difference_t.hpp:49
 
constexpr auto get(subrange< I, S, K > &&r)
Definition: subrange.hpp:377
 
constexpr auto get(const subrange< I, S, K > &r)
Definition: subrange.hpp:371
 
subrange_kind
Definition: subrange_kind.hpp:18
 
typename sentinel< R >::type sentinel_t
Definition: sentinel_t.hpp:29
 
typename ranges::iterator< T >::type iterator_t
Definition: iterator_t.hpp:32
 
constexpr subrange< I, S > make_subrange(I i, S s)
Definition: subrange.hpp:275
 
typename range_difference< R >::type range_difference_t
Used to obtain the difference type of the iterator type of range type R.
Definition: range_difference_t.hpp:41
 
std::integral_constant< bool, v > bool_constant
Definition: bool_constant.hpp:19
 
constexpr VCCC_INLINE_OR_STATIC in_place_t in_place
Definition: in_place.hpp:47
 
Definition: matrix.hpp:495
 
Definition: cxx20_rel_ops.hpp:17
 
Definition: directory.h:12
 
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
 
#define VCCC_NODISCARD
Definition: nodiscard.hpp:14
 
I type
Definition: subrange.hpp:407
 
I type
Definition: subrange.hpp:405
 
S type
Definition: subrange.hpp:411
 
S type
Definition: subrange.hpp:409
 
Definition: conjunction.hpp:22
 
Definition: disjunction.hpp:22
 
Definition: negation.hpp:23
 
Definition: enable_borrowed_range.hpp:17
 
specifies that a range knows its size in constant time
Definition: sized_range.hpp:38
 
Definition: sentinel_for.hpp:24
 
specifies that the - operator can be applied to an iterator and a sentinel to calculate their differe...
Definition: sized_sentinel_for.hpp:75