1#ifndef HALCHECK_LIB_ITERATOR_RANGES_HPP
2#define HALCHECK_LIB_ITERATOR_RANGES_HPP
6#include <halcheck/lib/iterator/base.hpp>
7#include <halcheck/lib/iterator/type_traits.hpp>
8#include <halcheck/lib/pp.hpp>
9#include <halcheck/lib/type_traits.hpp>
13namespace halcheck {
namespace lib {
23inline namespace begin_cpo {
40 using member = lib::iterator<decltype(std::declval<T &>().begin())>;
43 using free = lib::iterator<decltype(begin(std::declval<T &>()))>;
46 template<
typename T, std::
size_t N>
47 constexpr T *operator()(T (&value)[N])
const {
51 template<
typename T, std::
size_t N>
52 constexpr const T *operator()(
const T (&value)[N])
const {
56 template<
typename T, std::
size_t N>
57 constexpr T *operator()(T *value)
const {
61 template<
typename T, std::
size_t N>
62 constexpr const T *operator()(
const T *value)
const {
70 constexpr auto operator()(T &&value)
const ->
decltype(value.begin()) {
79 constexpr auto operator()(T &&value)
const ->
decltype(
begin(value)) {
94inline namespace end_cpo {
111 using member = lib::iterator<decltype(std::declval<T &&>().end())>;
114 using free = lib::iterator<decltype(end(std::declval<T &&>()))>;
117 template<
typename T, std::
size_t N>
118 constexpr T *operator()(T (&value)[N])
const {
122 template<
typename T, std::
size_t N>
123 constexpr const T *operator()(
const T (&value)[N])
const {
131 constexpr auto operator()(T &&value)
const ->
decltype(value.end()) {
140 constexpr auto operator()(T &&value)
const ->
decltype(
end(value)) {
149using range = lib::same<lib::iterator_t<T>,
decltype(lib::end(
std::declval<T &>()))>;
169struct is_view : lib::is_detected<lib::view, T> {};
253 constexpr void operator()(T *)
const =
delete;
255 template<
typename T, std::
size_t N>
256 constexpr std::size_t operator()(T (&)[N])
const noexcept {
260 template<
typename T, std::
size_t N>
261 constexpr std::size_t operator()(
const T (&)[N])
const noexcept {
269 constexpr auto operator()(T &&value)
const noexcept(
noexcept(value.size())) ->
decltype(value.size()) {
279 constexpr auto operator()(T &&value)
const noexcept(
noexcept(
size(value))) ->
decltype(
size(value)) {
292 constexpr auto operator()(T &&value)
const noexcept(
noexcept(lib::end(value) - lib::begin(value)))
293 ->
decltype(lib::end(value) - lib::begin(value)) {
294 return lib::end(value) - lib::begin(value);
315template<typename R, HALCHECK_REQUIRE(lib::is_sized_range<R>())>
323template<typename R, HALCHECK_REQUIRE(lib::is_range<R>())>
331template<typename R, HALCHECK_REQUIRE(lib::is_range<R>())>
339template<typename R, HALCHECK_REQUIRE(lib::is_range<R>())>
360 template<typename T, HALCHECK_REQUIRE(lib::is_detected<member, T>())>
361 constexpr bool operator()(T &&value)
const noexcept(
noexcept(
bool(value.empty()))) {
362 return bool(value.empty());
366 constexpr auto operator()(T &&value)
const noexcept(
noexcept(
lib::size(value) == 0))
376 constexpr bool operator()(T &&value)
const noexcept(
noexcept(bool(lib::end(value) == lib::begin(value)))) {
377 return bool(lib::end(value) == lib::begin(value));
lib::iter_value_t< lib::iterator_t< R > > range_value_t
The type of element contained in a range.
Definition range.hpp:332
decltype(lib::size(std::declval< R & >())) range_size_t
The type of value returned by lib::size.
Definition range.hpp:316
decltype(lib::begin(std::declval< T & >())) iterator_t
Obtains the iterator type of a range type.
Definition range.hpp:92
HALCHECK_INLINE_CONSTEXPR struct halcheck::lib::@26 empty
Determines if a range is empty.
typename std::iterator_traits< I >::value_type iter_value_t
The type of value pointed to by an iterator.
Definition base.hpp:16
typename std::iterator_traits< I >::difference_type iter_difference_t
The return type of operator- for an iterator.
Definition base.hpp:32
typename std::iterator_traits< I >::reference iter_reference_t
The return type of operator* for an iterator.
Definition base.hpp:24
HALCHECK_INLINE_CONSTEXPR struct halcheck::lib::@25 size
Obtains the size of a range.
lib::iter_reference_t< lib::iterator_t< R > > range_reference_t
The type returned by operator* for a range type's iterators.
Definition range.hpp:340
HALCHECK_INLINE_CONSTEXPR struct halcheck::lib::end_cpo::@28 end
Gets an iterator to past the end of a range.
HALCHECK_INLINE_CONSTEXPR struct halcheck::lib::begin_cpo::@27 begin
Gets an iterator to the first element of a range.
lib::iter_difference_t< lib::iterator_t< R > > range_difference_t
The type of value returned by operator- for a range type's iterators.
Definition range.hpp:324
#define HALCHECK_INLINE_CONSTEXPR
A backwards-compatible substitute for inline constexpr.
Definition pp.hpp:70
typename std::remove_cv< typename std::remove_reference< T >::type >::type remove_cvref_t
An implementation of std::remove_cvref_t.
Definition type_traits.hpp:141
typename std::enable_if< Cond, T >::type enable_if_t
An implementation of std::enable_if_t.
Definition type_traits.hpp:93
typename std::make_unsigned< T >::type make_unsigned_t
An implementation of std::make_unsigned_t.
Definition type_traits.hpp:125
void void_t
An implementation of std::void_t.
Definition type_traits.hpp:43
#define HALCHECK_REQUIRE(...)
Expands to a template argument that is only valid if the given argument evaluates to true.
Definition type_traits.hpp:24
Indicates whether lib::size should be disabled for a type.
Definition range.hpp:229
An implementation of std::ranges::enable_borrowed_range.
Definition range.hpp:21
Determines whether a type is a range whose iterators satisfy lib::is_bidirectional_iterator.
Definition range.hpp:207
An implementation of std::experimental::is_detected.
Definition type_traits.hpp:247
Determines whether a type is a range whose iterators satisfy lib::is_forward_iterator.
Definition range.hpp:195
Determines whether a range is insertable.
Definition range.hpp:401
Determines whether a type is a range whose iterators satisfy lib::is_random_access_iterator.
Definition range.hpp:219
Determines whether the given type is a range.
Definition range.hpp:158
Determines whether a range type supports the lib::size operation.
Definition range.hpp:308