VCCC  2024.05
VisualCamp Common C++ library
take_while_view.hpp
Go to the documentation of this file.
1 //
2 // Created by YongGyu Lee on 3/27/24.
3 //
4 
5 #ifndef VCCC_RANGES_VIEWS_TAKE_WHILE_VIEW_HPP_
6 #define VCCC_RANGES_VIEWS_TAKE_WHILE_VIEW_HPP_
7 
8 #include <memory>
9 #include <type_traits>
10 #include <utility>
11 
17 #include "vccc/__ranges/begin.hpp"
21 #include "vccc/__ranges/range.hpp"
24 #include "vccc/__ranges/view.hpp"
33 
34 namespace vccc {
35 namespace ranges {
36 
39 
40 template<typename V, typename Pred>
42  public:
43  static_assert(ranges::view<V>::value, "Constraints not satisfied");
44  static_assert(ranges::input_range<V>::value, "Constraints not satisfied");
45  static_assert(std::is_object<Pred>::value, "Constraints not satisfied");
46  static_assert(indirect_unary_predicate<const Pred, iterator_t<V>>::value, "Constraints not satisfied");
47 
48  template<bool Const>
49  class sentinel {
50  using Base = maybe_const<Const, V>;
51  friend class sentinel<!Const>;
52 
53  public:
54  sentinel() = default;
55 
56  constexpr explicit sentinel(sentinel_t<Base> end, const Pred* pred)
57  : end_(std::move(end)), pred_(pred) {}
58 
59  template<bool AntiConst, std::enable_if_t<conjunction<
60  bool_constant<((Const != AntiConst) && Const)>,
62  >::value, int> = 0>
63  constexpr sentinel(sentinel<AntiConst> that)
64  : end_(std::move(that.end_)), pred_(that.pred_) {}
65 
66  constexpr sentinel_t<Base> base() const {
67  return end_;
68  }
69 
70  friend constexpr bool operator==(const iterator_t<Base>& x, const sentinel& y) {
71  using namespace vccc::rel_ops;
72  return x == y.end_ || !vccc::invoke(*y.pred_, *x);
73  }
74 
75  friend constexpr bool operator!=(const iterator_t<Base>& x, const sentinel& y) {
76  return !(x == y);
77  }
78 
79  friend constexpr bool operator==(const sentinel& y, const iterator_t<Base>& x) {
80  return x == y;
81  }
82 
83  friend constexpr bool operator!=(const sentinel& y, const iterator_t<Base>& x) {
84  return !(x == y);
85  }
86 
87  private:
88  sentinel_t<Base> end_;
89  const Pred* pred_;
90  };
91 
92  take_while_view() = default;
93 
94  constexpr explicit take_while_view(V base, Pred pred)
95  : base_(std::move(base)), pred_(std::move(pred)) {}
96 
97  template<typename Dummy = void, std::enable_if_t<vccc::conjunction<std::is_void<Dummy>,
98  copy_constructible<V>
99  >::value, int> = 0>
100  constexpr V base() const& {
101  return base_;
102  }
103 
104  constexpr V base() && {
105  return std::move(base_);
106  }
107 
108  constexpr const Pred& pred() const {
109  return *pred_;
110  }
111 
112  template<typename Dummy = void, std::enable_if_t<vccc::conjunction<std::is_void<Dummy>,
113  negation<simple_view<V>>
114  >::value, int> = 0>
115  constexpr auto begin() {
116  return ranges::begin(base_);
117  }
118 
119  template<typename Dummy = void, std::enable_if_t<vccc::conjunction<std::is_void<Dummy>,
120  range<const V>,
121  indirect_unary_predicate<const Pred, iterator_t<const V>>
122  >::value, int> = 0>
123  constexpr auto begin() const {
124  return ranges::begin(base_);
125  }
126 
127  template<typename Dummy = void, std::enable_if_t<vccc::conjunction<std::is_void<Dummy>,
128  negation<simple_view<V>>
129  >::value, int> = 0>
131  return sentinel<false>{ranges::end(base_), pred_.operator->()};
132  }
133 
134  template<typename Dummy = void, std::enable_if_t<vccc::conjunction<std::is_void<Dummy>,
135  range<const V>,
136  indirect_unary_predicate<const Pred, iterator_t<const V>>
137  >::value, int> = 0>
139  return sentinel<true>{ranges::end(base_), pred_.operator->()};
140  }
141 
142  private:
143  V base_{};
145 };
146 
147 #if __cplusplus >= 201703L
148 
149 template<typename R, typename Pred>
151 
152 #endif
153 
155 
156 } // namespace ranges
157 } // namespace vccc
158 
159 #endif // VCCC_RANGES_VIEWS_TAKE_WHILE_VIEW_HPP_
Definition: take_while_view.hpp:49
constexpr friend bool operator==(const sentinel &y, const iterator_t< Base > &x)
Definition: take_while_view.hpp:79
constexpr sentinel_t< Base > base() const
Definition: take_while_view.hpp:66
constexpr sentinel(sentinel_t< Base > end, const Pred *pred)
Definition: take_while_view.hpp:56
constexpr sentinel(sentinel< AntiConst > that)
Definition: take_while_view.hpp:63
constexpr friend bool operator!=(const sentinel &y, const iterator_t< Base > &x)
Definition: take_while_view.hpp:83
constexpr friend bool operator==(const iterator_t< Base > &x, const sentinel &y)
Definition: take_while_view.hpp:70
constexpr friend bool operator!=(const iterator_t< Base > &x, const sentinel &y)
Definition: take_while_view.hpp:75
Definition: take_while_view.hpp:41
constexpr V base() const &
Definition: take_while_view.hpp:100
VCCC_CONSTEXPR_AFTER_CXX17 auto end() const
Definition: take_while_view.hpp:138
constexpr take_while_view(V base, Pred pred)
Definition: take_while_view.hpp:94
constexpr const Pred & pred() const
Definition: take_while_view.hpp:108
constexpr V base() &&
Definition: take_while_view.hpp:104
VCCC_CONSTEXPR_AFTER_CXX17 auto end()
Definition: take_while_view.hpp:130
constexpr auto begin() const
Definition: take_while_view.hpp:123
constexpr auto begin()
Definition: take_while_view.hpp:115
#define VCCC_CONSTEXPR_AFTER_CXX17
Definition: constexpr.hpp:20
constexpr invoke_result_t< F, Args... > invoke(F &&f, Args &&... args) noexcept(is_nothrow_invocable< F, Args... >::value)
Definition: invoke.hpp:38
typename sentinel< R >::type sentinel_t
Definition: sentinel_t.hpp:29
typename ranges::iterator< T >::type iterator_t
Definition: iterator_t.hpp:32
constexpr VCCC_INLINE_OR_STATIC detail::begin_niebloid begin
returns an iterator to the beginning of a range
Definition: begin.hpp:116
constexpr VCCC_INLINE_OR_STATIC detail::end_niebloid end
returns a sentinel indicating the end of a range
Definition: end.hpp:120
std::integral_constant< bool, v > bool_constant
Definition: bool_constant.hpp:19
std::conditional_t< Const, const V, V > maybe_const
Definition: maybe_const.hpp:16
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
Definition: conjunction.hpp:22
Models std::convertible_to
Definition: convertible_to.hpp:38
specifies that a callable type, when invoked with the result of dereferencing an indirectly_readable ...
Definition: indirect_unary_predicate.hpp:49
specifies a range whose iterator type satisfies input_iterator
Definition: input_range.hpp:46
specifies that a range is a view, that is, it has constant time copy/move/assignment
Definition: view.hpp:31