halcheck 1.0
Loading...
Searching...
No Matches
ref.hpp
1#ifndef HALCHECK_LIB_ITERATOR_REF_HPP
2#define HALCHECK_LIB_ITERATOR_REF_HPP
3
4// IWYU pragma: private, include <halcheck/lib/iterator.hpp>
5
6#include <halcheck/lib/iterator/interface.hpp>
7#include <halcheck/lib/iterator/range.hpp>
8#include <halcheck/lib/pp.hpp>
9#include <halcheck/lib/type_traits.hpp>
10
11#include <memory>
12
13namespace halcheck { namespace lib {
14
15// See https://en.cppreference.com/w/cpp/ranges/ref_view
16
17template<typename R>
18class ref_view : public lib::view_interface<ref_view<R>> {
19private:
20 static_assert(std::is_object<R>(), "R must be an object type");
21 static_assert(lib::is_range<R>(), "R must be a range type");
22
23 template<typename>
24 friend class ref_view;
25
26 static std::true_type FUN(R &);
27 static std::false_type FUN(R &&);
28
29public:
30 template<
31 typename T,
34 HALCHECK_REQUIRE(decltype(FUN(std::declval<T>()))())>
35 constexpr ref_view(T &&base) // NOLINT
36 : _base(std::addressof(static_cast<R &>(std::forward<T>(base)))) {}
37
38 template<typename T, HALCHECK_REQUIRE(std::is_convertible<T *, R *>())>
39 constexpr ref_view(const ref_view<T> &other) // NOLINT
40 : _base(other._base) {}
41
42 constexpr R &base() const { return *_base; }
43
44 constexpr lib::iterator_t<R> begin() const { return lib::begin(*_base); }
45
46 constexpr lib::iterator_t<R> end() const { return lib::end(*_base); }
47
48 template<typename T = R, typename = decltype(lib::empty(std::declval<const T &>()))>
49 constexpr bool empty() const {
50 return lib::empty(*_base);
51 }
52
53 template<typename T = R, HALCHECK_REQUIRE(lib::is_sized_range<T>())>
54 constexpr bool size() const {
55 return lib::size(*_base);
56 }
57
58private:
59 R *_base;
60};
61
62template<typename R>
63struct enable_borrowed_range<lib::ref_view<R>> : std::true_type {};
64
66 template<typename R>
67 constexpr lib::ref_view<R> operator()(R &range) const {
68 return lib::ref_view<R>(range);
69 }
70} ref;
71
72}} // namespace halcheck::lib
73
74#endif
T addressof(T... args)
T declval(T... args)
T forward(T... args)
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.
HALCHECK_INLINE_CONSTEXPR struct halcheck::lib::@25 size
Obtains the size of a range.
#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
#define HALCHECK_REQUIRE(...)
Expands to a template argument that is only valid if the given argument evaluates to true.
Definition type_traits.hpp:24
STL namespace.