17 #ifndef OPENKALMAN_COMPATIBILITY_VIEWS_REPEAT_HPP 18 #define OPENKALMAN_COMPATIBILITY_VIEWS_REPEAT_HPP 20 #include <type_traits> 27 #ifdef __cpp_lib_ranges_repeat 28 using std::ranges::repeat_view;
37 #ifdef __cpp_lib_ranges 38 template<std::move_constructible W, std::semiregular Bound = unreachable_sentinel_t> requires
39 std::is_object_v<W> and std::same_as<W, std::remove_cv_t<W>> and
40 (OpenKalman::internal::is_signed_integer_like<Bound> or
41 (OpenKalman::internal::is_integer_like<Bound> and weakly_incrementable<Bound> or
42 std::same_as<Bound, std::unreachable_sentinel_t>))
43 struct repeat_view : std::ranges::view_interface<repeat_view<W, Bound>>
45 template<typename W, typename Bound = unreachable_sentinel_t>
53 using index_type = std::conditional_t<std::is_same_v<Bound, unreachable_sentinel_t>, std::ptrdiff_t, Bound>;
56 using iota_diff_t = std::conditional_t<
57 not std::is_integral_v<I> or (
sizeof(iter_difference_t<I>) >
sizeof(I)), iter_difference_t<I>, std::ptrdiff_t>;
61 using iterator_concept = std::random_access_iterator_tag;
62 using iterator_category = std::random_access_iterator_tag;
64 using difference_type = std::conditional_t<OpenKalman::internal::is_signed_integer_like<index_type>,
65 index_type, iota_diff_t<index_type>>;
71 constexpr
explicit iterator(
const W*
value, index_type b = index_type{}) : value_ {value}, current_ {b} {}
73 constexpr
const W& operator*()
const noexcept {
return *value_; }
75 constexpr
const W& operator[](difference_type n)
const noexcept {
return *(*
this + n); }
77 constexpr
iterator& operator++() { ++current_;
return *
this; }
79 constexpr
auto operator++(
int) {
auto tmp = *
this; ++*
this;
return tmp; }
81 constexpr
iterator& operator--() { --current_;
return *
this; }
83 constexpr
auto operator--(
int) {
auto tmp = *
this; --*
this;
return tmp; }
85 constexpr
iterator& operator+=(difference_type n) { current_ += n;
return *
this; }
87 constexpr
iterator& operator-=(difference_type n) { current_ -= n;
return *
this; }
89 friend constexpr
bool operator==(
const iterator& x,
const iterator& y) {
return x.current_ == y.current_; }
91 #ifdef __cpp_impl_three_way_comparison 92 friend constexpr
auto operator<=>(
const iterator& x,
const iterator& y) {
return x.current_ <=> y.current_; }
94 friend constexpr
bool operator!=(
const iterator& x,
const iterator& y) {
return x.current_ != y.current_; }
95 friend constexpr
bool operator<(
const iterator& x,
const iterator& y) {
return x.current_ < y.current_; }
96 friend constexpr
bool operator>(
const iterator& x,
const iterator& y) {
return x.current_ > y.current_; }
97 friend constexpr
bool operator<=(
const iterator& x,
const iterator& y) {
return x.current_ <= y.current_; }
98 friend constexpr
bool operator>=(
const iterator& x,
const iterator& y) {
return x.current_ >= y.current_; }
101 friend constexpr
auto operator+(
iterator i, difference_type n) { i += n;
return i; }
103 friend constexpr
auto operator+(difference_type n,
iterator i) { i += n;
return i; }
105 friend constexpr
auto operator-(
iterator i, difference_type n) { i -= n;
return i; }
109 return static_cast<difference_type
>(x.current_) - static_cast<difference_type>(y.current_);
120 #ifdef __cpp_lib_concepts 121 repeat_view() requires std::default_initializable<W> =
default;
123 template<
bool Enable = true, std::enable_if_t<Enable and stdex::default_initializable<W>,
int> = 0>
129 repeat_view(
const W&
value, Bound bound = {}) : value_ {value}, bound_ {bound} {}
133 repeat_view(W&& value, Bound bound = {}) : value_ {std::move(value)}, bound_ {bound} {}
136 #ifdef __cpp_lib_concepts 137 template <
typename...WArgs,
typename...BoundArgs> requires
138 std::constructible_from<W, WArgs...> and std::constructible_from<Bound, BoundArgs...>
140 template<
typename...WArgs,
typename...BoundArgs, std::enable_if_t<
141 stdex::constructible_from<W, WArgs...> and stdex::constructible_from<Bound, BoundArgs...>,
int> = 0>
144 repeat_view(std::piecewise_construct_t, std::tuple<WArgs...> value_args, std::tuple<BoundArgs...> bound_args = std::tuple<>{})
145 : value_ {std::make_from_tuple<W>(std::move(value_args))}, bound_ {std::make_from_tuple<Bound>(std::move(bound_args))} {}
149 begin()
const {
return iterator {std::addressof(*value_)}; }
155 if constexpr (same_as<Bound, unreachable_sentinel_t>)
156 return unreachable_sentinel;
158 return iterator {std::addressof(*value_), bound_};
162 #ifdef __cpp_lib_concepts 164 size()
const requires (not same_as<Bound, unreachable_sentinel_t>)
166 template<
bool Enable = true, std::enable_if_t<Enable and not same_as<Bound, unreachable_sentinel_t>,
int> = 0>
167 constexpr
auto size()
const 170 if constexpr (std::is_integral_v<Bound>)
return static_cast<std::make_unsigned_t<Bound>
>(bound_);
171 else return static_cast<std::size_t
>(bound_);
183 template<
typename W,
typename Bound = unreachable_sentinel_t>
193 #ifdef __cpp_lib_concepts 194 template<std::move_constructible W, std::semiregular Bound = unreachable_sentinel_t> requires
195 (OpenKalman::internal::is_signed_integer_like<Bound> or
196 (OpenKalman::internal::is_integer_like<Bound> and weakly_incrementable<Bound> or
197 std::same_as<Bound, std::unreachable_sentinel_t>))
199 template<
typename W,
typename Bound = unreachable_sentinel_t>
202 operator() [[nodiscard]] (W&&
value, Bound&& bound = {})
const
constexpr detail::repeat_adaptor repeat
a std::ranges::range_adaptor_closure for a set of repeated collection objects.
Definition: repeat.hpp:148
constexpr bool value
T is a fixed or dynamic value that is reducible to a number.
Definition: value.hpp:45
Definition: view_interface.hpp:32
Definitions relating to the availability of c++ language features.
Definition: common.hpp:200
constexpr bool size
T is either an index representing a size, or unbounded_size_t, which indicates that the size is unbou...
Definition: size.hpp:65
Definition: repeat.hpp:191
Definition: repeat.hpp:49
Equivalent to std::ranges::repeat_view.
Definition: repeat.hpp:46