17 #ifndef OPENKALMAN_COMPATIBILITY_VIEWS_CONCAT_HPP 18 #define OPENKALMAN_COMPATIBILITY_VIEWS_CONCAT_HPP 27 #if __cpp_lib_ranges_concat >= 202403L 28 using std::ranges::concat_view;
39 #ifdef __cpp_lib_ranges 40 template<std::ranges::random_access_range...Views> requires (... and std::ranges::view<Views>) and (
sizeof...(Views) > 0)
42 template<
typename...Views>
48 template<
typename...Rs>
using concat_reference_t = common_reference_t<range_reference_t<Rs>...>;
49 template<
typename...Rs>
using concat_value_t = std::common_type_t<range_value_t<Rs>...>;
50 template<
typename...Rs>
using concat_rvalue_reference_t = common_reference_t<range_rvalue_reference_t<Rs>...>;
52 template<
bool Const,
typename Rs>
53 using maybe_const = std::conditional_t<Const, const Rs, Rs>;
55 using ViewsTup = std::tuple<Views...>;
58 class concat_index_table
60 template<std::size_t...cs>
61 #ifdef __cpp_lib_constexpr_vector 68 std::vector<std::size_t> table;
69 auto it = std::back_inserter(table);
76 make_index_table(
const ViewsTup& tup)
78 return make_index_table_range(tup, std::index_sequence_for<Views...>{});
83 explicit constexpr concat_index_table(
const ViewsTup& rs_tup) :
value {make_index_table(rs_tup)} {}
85 decltype(make_index_table(std::declval<const ViewsTup&>()))
value;
90 class concat_start_table
92 template<std::size_t i = 0,
typename...Locs>
94 make_start_table(
const ViewsTup& tup, std::size_t currloc = 0_uz, Locs...locs)
96 if constexpr (i <
sizeof...(Views))
99 return make_start_table<i + 1>(tup, next_loc, locs..., currloc);
103 return std::array {locs...};
109 explicit constexpr concat_start_table(
const ViewsTup& rs_tup) :
value {make_start_table(rs_tup)} {}
111 decltype(make_start_table(std::declval<const ViewsTup&>()))
value;
116 using IndexTable = decltype(concat_index_table(std::declval<ViewsTup>()).
value);
118 using StartTable = decltype(concat_start_table(std::declval<ViewsTup>()).
value);
125 using iterator_concept = std::random_access_iterator_tag;
126 using iterator_category = iterator_concept;
127 using value_type = concat_value_t<maybe_const<Const, Views>...>;
128 using difference_type = std::common_type_t<range_difference_t<maybe_const<Const, Views>>...>;
129 using pointer = void;
130 using reference = concat_reference_t<maybe_const<Const, Views>...>;
134 using Tup = maybe_const<Const, ViewsTup>;
136 template<
typename = std::index_sequence_for<Views...>>
137 struct tuple_concat_iterator_call_table;
139 template<std::size_t...ix>
140 struct tuple_concat_iterator_call_table<std::index_sequence<ix...>>
142 template<std::
size_t i>
143 static constexpr value_type
144 call_table_get(Tup& tup, std::size_t local_i) noexcept
146 return std::get<i>(tup)[local_i];
149 static constexpr std::array
value {call_table_get<ix>...};
152 using table = tuple_concat_iterator_call_table<>;
156 #ifdef __cpp_concepts 160 (... and std::convertible_to<stdex::ranges::iterator_t<Views>, stdex::ranges::iterator_t<const Views>>)
161 : parent(it.parent), current(it.current) {}
163 constexpr
iterator() : parent{
nullptr} {};
165 template<
bool C = Const, std::enable_if_t<C and
166 (... and stdex::convertible_to<iterator_t<Views>, iterator_t<const Views>>),
int> = 0>
167 constexpr iterator(
iterator<not C> it) : parent(it.parent), current(it.current) {}
171 constexpr
explicit iterator(maybe_const<Const, concat_view>* parent, difference_type p)
173 : parent(parent), current(p) {}
175 constexpr iterator(
const iterator& other) =
default;
176 constexpr iterator(iterator&& other) noexcept =
default;
177 constexpr iterator& operator=(
const iterator& other) =
default;
178 constexpr iterator& operator=(iterator&& other) noexcept =
default;
179 explicit constexpr
operator std::size_t()
const noexcept {
return static_cast<std::size_t
>(current); }
181 constexpr decltype(
auto) operator*() noexcept
183 std::size_t c = (parent->index_table)[static_cast<std::size_t>(current)];
184 std::size_t local_i = current - parent->start_table[c];
187 constexpr decltype(
auto) operator*()
const noexcept
189 std::size_t c = (parent->index_table)[static_cast<std::size_t>(current)];
190 std::size_t local_i = current - parent->start_table[c];
193 constexpr decltype(
auto) operator[](difference_type offset) noexcept
195 auto i =
static_cast<std::size_t
>(current + offset);
196 std::size_t c = parent->index_table[i];
197 std::size_t local_i = i - parent->start_table[c];
200 constexpr decltype(
auto) operator[](difference_type offset)
const noexcept
202 auto i =
static_cast<std::size_t
>(current + offset);
203 std::size_t c = parent->index_table[i];
204 std::size_t local_i = i - parent->start_table[c];
207 constexpr
auto& operator++() noexcept { ++current;
return *
this; }
208 constexpr
auto operator++(
int) noexcept {
auto temp = *
this; ++*
this;
return temp; }
209 constexpr
auto& operator--() noexcept { --current;
return *
this; }
210 constexpr
auto operator--(
int) noexcept {
auto temp = *
this; --*
this;
return temp; }
211 constexpr
auto& operator+=(
const difference_type diff) noexcept { current += diff;
return *
this; }
212 constexpr
auto& operator-=(
const difference_type diff) noexcept { current -= diff;
return *
this; }
214 friend constexpr
auto operator+(
const iterator& it,
const difference_type diff) noexcept
216 return iterator {it.parent, it.current + diff};
218 friend constexpr
auto operator+(
const difference_type diff,
const iterator& it) noexcept
220 return iterator {it.parent, diff + it.current};
222 friend constexpr
auto operator-(
const iterator& it,
const difference_type diff) noexcept
224 return iterator {it.parent, it.current - diff};
226 friend constexpr difference_type operator-(
const iterator& it,
const iterator& other) noexcept
228 return it.current - other.current;
230 friend constexpr
bool operator==(
const iterator& it,
const iterator& other) noexcept
232 return it.current == other.current;
234 #ifdef __cpp_impl_three_way_comparison 235 constexpr
auto operator<=>(
const iterator& other)
const noexcept {
return current <=> other.current; }
237 constexpr
bool operator!=(
const iterator& other)
const noexcept {
return current != other.current; }
238 constexpr
bool operator<(
const iterator& other)
const noexcept {
return current < other.current; }
239 constexpr
bool operator>(
const iterator& other)
const noexcept {
return current > other.current; }
240 constexpr
bool operator<=(
const iterator& other)
const noexcept {
return current <= other.current; }
241 constexpr
bool operator>=(
const iterator& other)
const noexcept {
return current >= other.current; }
246 maybe_const<Const, concat_view>* parent;
247 difference_type current;
252 #ifdef __cpp_concepts 255 template<
bool Enable =
true, std::enable_if_t<Enable and (... and stdex::default_initializable<Views>),
int> = 0>
260 explicit constexpr
concat_view(Views...vs) : views_tup {std::move(vs)...} {}
271 begin()
const noexcept
292 template<
typename F,
typename Tuple>
293 static constexpr
auto tuple_transform(F&& f, Tuple&& tuple)
297 return std::tuple<std::invoke_result_t<F&, decltype(args)>...>(stdex::invoke(f, std::forward<decltype(args)>(args))...);
298 }, std::forward<Tuple>(tuple));
304 #ifdef __cpp_concepts 305 constexpr
auto size()
const requires (... and std::ranges::sized_range<Views>)
307 template<
bool enable =
true, std::enable_if_t<enable and (... and sized_range<Views>),
int> = 0>
308 constexpr
auto size()
const 311 return std::apply([](
auto...sizes) {
return (... + static_cast<std::size_t>(sizes)); },
319 IndexTable index_table = concat_index_table(views_tup).value;
321 StartTable start_table = concat_start_table(views_tup).value;
326 template<
typename...Rs>
336 #ifdef __cpp_lib_ranges 337 template<std::ranges::viewable_range...Rs> requires (... and std::ranges::random_access_range<Rs>)
339 template<
typename...Rs, std::enable_if_t<(... and (viewable_range<Rs> and random_access_range<Rs>)),
int> = 0>
342 operator() (Rs&&...rs)
const 344 if constexpr (
sizeof...(Rs) == 1 and (... and input_range<Rs>))
345 return all(std::forward<Rs>(rs)...);
Definition: concat.hpp:123
constexpr detail::all_closure all
Equivalent to std::ranges::views::all.
Definition: all.hpp:64
Definition: concat.hpp:44
constexpr bool value
T is a fixed or dynamic value that is reducible to a number.
Definition: value.hpp:45
decltype(auto) constexpr apply(F &&f, T &&t)
A generalization of std::apply.
Definition: apply.hpp:49
Definition: view_interface.hpp:32
constexpr detail::concat_adaptor concat
a std::ranges::range_adaptor_closure for a set of concatenated pattern objects.
Definition: concat.hpp:56
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: concat.hpp:334
Definition: trait_backports.hpp:64
Definitions relating to a compatible replacement for std::invoke.