OpenKalman
wrap.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 
16 #ifndef OPENKALMAN_COORDINATES_WRAP_HPP
17 #define OPENKALMAN_COORDINATES_WRAP_HPP
18 
19 #include <type_traits>
20 #include <functional>
22 #include "coordinates/interfaces/coordinate_descriptor_traits.hpp"
29 
31 {
32 #ifndef __cpp_concepts
33  namespace detail
34  {
35  template<typename Traits, typename = void>
36  struct wrap_trait_defined_for : std::false_type {};
37 
38  template<typename Traits>
39  struct wrap_trait_defined_for<Traits, std::void_t<decltype(Traits::wrap)>>
40  : std::true_type {};
41  }
42 #endif
43 
44 
52 #ifdef __cpp_concepts
53  template<descriptor T, collections::collection R>
54  constexpr collections::collection decltype(auto)
55 #else
56  template<typename T, typename R, std::enable_if_t<descriptor<T> and collections::collection<R>, int> = 0>
57  constexpr decltype(auto)
58 #endif
59  wrap(const T& t, R&& data_view)
60  {
61  if constexpr (dimension_of_v<T> != stdex::dynamic_extent and collections::size_of_v<R> != stdex::dynamic_extent)
62  static_assert(dimension_of_v<T> == collections::size_of_v<R>);
63 
64  if constexpr (euclidean_pattern<T>)
65  {
66  return std::forward<R>(data_view);
67  }
68  else
69  {
70  using U = std::decay_t<stdex::unwrap_ref_decay_t<T>>;
72 #ifdef __cpp_concepts
73  if constexpr (requires { Traits::wrap; })
74 #else
76 #endif
77  {
78  if constexpr (std::is_same_v<U, T>)
79  return stdex::invoke(Traits::wrap, t, std::forward<R>(data_view));
80  else
81  return stdex::invoke(Traits::wrap, t.get(), std::forward<R>(data_view));
82  }
83  else
84  {
85  return from_stat_space(t, to_stat_space(t, std::forward<R>(data_view)));
86  }
87  }
88  }
89 
90 
91  namespace detail
92  {
93  template<std::size_t t_i = 0, std::size_t data_view_i = 0, typename T, typename R, typename...Out>
94  static constexpr auto
95  wrap_tuple(const T& t, const R& data_view, Out...out)
96  {
97  if constexpr (t_i < collections::size_of_v<T>)
98  {
99  decltype(auto) t_elem = collections::get<t_i>(t);
100  auto dim = get_dimension(t_elem);
101  auto data_view_sub = collections::views::slice(data_view, std::integral_constant<std::size_t, data_view_i>{}, dim);
102  auto o = wrap(t_elem, std::move(data_view_sub));
103  return wrap_tuple<t_i + 1, data_view_i + values::fixed_value_of_v<decltype(dim)>>(t, data_view, std::move(out)..., std::move(o));
104  }
105  else
106  {
107  return collections::views::concat(std::move(out)...);
108  }
109  }
110 
111  }
112 
113 
122 #ifdef __cpp_concepts
123  template<descriptor_collection T, collections::collection R>
124  constexpr collections::collection decltype(auto)
125 #else
126  template<typename T, typename R, std::enable_if_t<descriptor_collection<T> and collections::collection<R>, int> = 0>
127  constexpr decltype(auto)
128 #endif
129  wrap(const T& t, R&& data_view)
130  {
131  if constexpr (dimension_of_v<T> != stdex::dynamic_extent and collections::size_of_v<R> != stdex::dynamic_extent)
132  static_assert(dimension_of_v<T> == collections::size_of_v<R>);
133 
134  if constexpr (dimension_of_v<T> == stdex::dynamic_extent)
135  {
136  std::vector<collections::common_collection_type_t<R>> data;
137  data.reserve(get_dimension(t));
138  std::size_t i = 0;
139  for (auto& d : t)
140  {
141  auto dim = get_dimension(d);
142 #if __cpp_lib_containers_ranges >= 202002L
143  data.append_range(wrap(d, collections::views::slice(data_view, i, dim)));
144 #else
145  auto sd = wrap(d, collections::views::slice(data_view, i, dim));
146  data.insert(data.end(), sd.cbegin(), sd.cend());
147 #endif
148  i += values::to_value_type(dim);
149  }
150  return data;
151  }
152  else //if constexpr (fixed_pattern<T>)
153  {
154  return detail::wrap_tuple(t, data_view);
155  }
156  }
157 
158 }
159 
160 
161 #endif
Definition for coordinates::euclidean_pattern.
constexpr bool collection
An object describing a collection of objects.
Definition: collection.hpp:32
constexpr detail::concat_adaptor concat
a std::ranges::range_adaptor_closure for a set of concatenated collection objects.
Definition: concat.hpp:196
decltype(auto) constexpr to_stat_space(const T &t, R &&data_view)
Maps a range reflecting vector-space data to a corresponding range in a vector space for directional ...
Definition: to_stat_space.hpp:44
decltype(auto) constexpr wrap(const T &t, R &&data_view)
wraps a range reflecting vector-space data to its primary range.
Definition: wrap.hpp:59
decltype(auto) constexpr to_value_type(Arg &&arg)
Convert, if necessary, a fixed or dynamic value to its underlying base type.
Definition: to_value_type.hpp:28
Definition for coordinates::to_stat_space.
Definition for collections::from_stat_space.
constexpr auto get_dimension(const Arg &arg)
Get the vector dimension of coordinates::pattern Arg.
Definition: get_dimension.hpp:54
Definition for coordinates::descriptor.
The namespace for features relating to coordinates::pattern object.
Definition: compares_with.hpp:25
Inclusion file for collections.
constexpr detail::slice_adapter slice
a RangeAdapterObject associated with slice_view.
Definition: slice.hpp:364
Traits for coordinates::pattern objects.
Definition: coordinate_descriptor_traits.hpp:36
decltype(auto) constexpr from_stat_space(const T &t, R &&stat_data_view)
Maps a range in a vector space for directional-statistics back to a range reflecting vector-space dat...
Definition: from_stat_space.hpp:44
Definition for coordinates::descriptor_collection.
Definition for coordinates::dimension_of.