OpenKalman
iota.hpp
Go to the documentation of this file.
1 /* This file is part of OpenKalman, a header-only C++ library for
2  * Kalman filters and other recursive filters.
3  *
4  * Copyright (c) 2025 Christopher Lee Ogden <ogden@gatech.edu>
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
9  */
10 
17 #ifndef OPENKALMAN_COLLECTIONS_VIEWS_IOTA_HPP
18 #define OPENKALMAN_COLLECTIONS_VIEWS_IOTA_HPP
19 
20 #include <type_traits>
21 #ifdef __cpp_lib_ranges
22 #include <ranges>
23 #else
25 #endif
27 #include "values/concepts/size.hpp"
32 #include "generate.hpp"
33 
35 {
36  namespace detail
37  {
38  template<typename Start = std::integral_constant<std::size_t, 0>>
40  {
41  constexpr iota_generator() = default;
42 
43  explicit constexpr iota_generator(Start start) : start_ {std::move(start)} {};
44 
45 #ifdef __cpp_concepts
46  template<values::index I>
47 #else
48  template<typename I, std::enable_if_t<values::index<I>, int> = 0>
49 #endif
50  constexpr auto
51  operator() (I i) const
52  {
53  return values::operation {std::plus<std::size_t>{}, start_, std::move(i)};
54  }
55 
56  private:
57 
58  Start start_;
59  };
60 
61  }
62 
63 
73 #ifdef __cpp_concepts
74  template<values::integral Start = std::integral_constant<std::size_t, 0>, values::size Size = std::unreachable_sentinel_t>
75  requires (not values::index<Size> or std::convertible_to<values::number_type_of_t<Size>, values::number_type_of_t<Start>>) and
76  std::same_as<Start, std::remove_reference_t<Start>> and
77  std::same_as<Size, std::remove_reference_t<Size>>
78 #else
79  template<typename Start = std::integral_constant<std::size_t, 0>, typename Size = unreachable_sentinel_t>
80 #endif
81  struct iota_view : generate_view<detail::iota_generator<Start>, Size>
82  {
83  private:
84 
85  using Size_ = std::conditional_t<values::index<Size>, Size, std::monostate>;
87 
88  public:
89 
93 #ifdef __cpp_concepts
94  constexpr
95  iota_view(Start start, Size_ size) requires values::index<Size>
96 #else
97  template<bool Enable = true, std::enable_if_t<Enable and values::index<Size>, int> = 0>
98  constexpr iota_view(Start start, Size_ size)
99 #endif
100  : view_base {detail::iota_generator{start}, std::move(size)} {}
101 
102 
106 #ifdef __cpp_concepts
107  explicit constexpr
108  iota_view(Size_ size) requires values::fixed<Start> and values::index<Size>
109 #else
110  template<bool Enable = true, std::enable_if_t<Enable and values::fixed<Start> and values::index<Size>, int> = 0>
111  explicit constexpr iota_view(Size_ size)
112 #endif
113  : view_base {std::move(size)} {}
114 
115 
119  constexpr
120  iota_view() noexcept = default;
121 
122  };
123 
124 
128  template<typename Start, typename Size>
129  iota_view(const Start&, const Size&) -> iota_view<Start, Size>;
130 
134  template<typename Size>
136 
137 } // OpenKalman::values
138 
139 
140 #ifdef __cpp_lib_ranges
141 namespace std::ranges
142 #else
143 namespace OpenKalman::ranges
144 #endif
145 {
146  template<typename Start, typename Size>
147  constexpr bool enable_borrowed_range<OpenKalman::collections::iota_view<Start, Size>> = true;
148 }
149 
150 
151 namespace std
152 {
153 #ifdef __cpp_concepts
154  template<typename Start, OpenKalman::values::fixed Size>
155  struct tuple_size<OpenKalman::collections::iota_view<Start, Size>>
156  : std::integral_constant<size_t, OpenKalman::values::fixed_number_of_v<Size>> {};
157 #else
158  template<typename Start, typename Size>
159  struct tuple_size<OpenKalman::collections::iota_view<Start, Size>>
160  : tuple_size<OpenKalman::collections::generate_view<OpenKalman::collections::detail::iota_generator<Start>, Size>> {};
161 #endif
162 
163 
164 #ifdef __cpp_concepts
165  template<std::size_t i, OpenKalman::values::fixed Start, typename Size>
166  struct tuple_element<i, OpenKalman::collections::iota_view<Start, Size>>
167  {
168  static_assert(not OpenKalman::values::fixed<Size> or requires { requires i < OpenKalman::values::fixed_number_of<Size>::value; });
169  using type = OpenKalman::values::operation<std::plus<>, Start, std::integral_constant<std::size_t, i>>;
170  };
171 #else
172  template<std::size_t i, typename Start, typename Size>
173  struct tuple_element<i, OpenKalman::collections::iota_view<Start, Size>>
174  : tuple_element<i, OpenKalman::collections::generate_view<OpenKalman::collections::detail::iota_generator<Start>, Size>> {};
175 #endif
176 
177 } // namespace std
178 
179 
181 {
182  namespace detail
183  {
185  {
189 #ifdef __cpp_concepts
190  template<values::index Start, values::index Size> requires
191  std::convertible_to<values::number_type_of_t<Size>, values::number_type_of_t<Start>>
192 #else
193  template<typename Start, typename Size, std::enable_if_t<values::index<Start> and values::index<Size> and
194  std::is_convertible_v<values::number_type_of_t<Size>, values::number_type_of_t<Start>>, int> = 0>
195 #endif
196  constexpr auto
197  operator() (Start start, Size size) const
198  {
199  return iota_view<std::decay_t<Start>, std::decay_t<Size>>(std::move(start), std::move(size));
200  }
201 
202 
206 #ifdef __cpp_concepts
207  template<values::index Size>
208 #else
209  template<typename Size, std::enable_if_t<values::index<Size>, int> = 0>
210 #endif
211  constexpr auto
212  operator() (Size size) const
213  {
214  return iota_view<std::integral_constant<std::size_t, 0>, std::decay_t<Size>>(std::move(size));
215  }
216 
217 
221  constexpr auto
222  operator() () const
223  {
224  return iota_view<> {};
225  }
226 
227  };
228  }
229 
230 
237  inline constexpr detail::iota_adapter iota;
238 
239 }
240 
241 
242 #endif //OPENKALMAN_COLLECTIONS_VIEWS_IOTA_HPP
Definition for values::index.
constexpr detail::iota_adapter iota
a RangeAdapterObject associated with iota_view.
Definition: iota.hpp:237
Namespace for collections.
Definition: collections.hpp:27
Definition for values::fixed_number_of.
Definition for values::size.
An operation involving some number of values.
Definition: operation.hpp:69
Definition: tuple_reverse.hpp:103
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
An iota collection that is a std::range and may also be tuple_like.
Definition: iota.hpp:81
Definition for collections::generate_view and collections::views::generate.
Definition for value:number_type_of_t.
A collection_view created by lazily generating elements based on an index.
Definition: generate.hpp:44
constexpr iota_view(Start start, Size_ size)
Construct from an initial value and size.
Definition: iota.hpp:98
constexpr bool size
T is either an index representing a size, or void which represents that there is no size...
Definition: size.hpp:32
Namespace for generalized views.
Definition: collections.hpp:33
iota_view(const Start &, const Size &) -> iota_view< Start, Size >
Deduction guide.
constexpr iota_view(Size_ size)
Construct from a size, default-initializing Start.
Definition: iota.hpp:111
Definitions implementing features of the c++ ranges library for compatibility.
std::decay_t< decltype(values::to_number(std::declval< T >()))> number_type_of_t
Obtain the values::number type associated with avalues::value.
Definition: number_type_of_t.hpp:34
Definition for ::fixed.