OpenKalman
make_fixed_size_adapter_like.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) 2022-2023 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_MAKE_FIXED_SIZE_ADAPTER_LIKE_HPP
18 #define OPENKALMAN_MAKE_FIXED_SIZE_ADAPTER_LIKE_HPP
19 
20 namespace OpenKalman::internal
21 {
22  namespace detail
23  {
24  template<std::size_t I, typename...Ts>
25  constexpr decltype(auto) best_desc_Ts_impl(const Ts&...ts)
26  {
27  return best_vector_space_descriptor(get_vector_space_descriptor<I>(ts)...);
28  }
29 
30 
31  template<typename...Ts, typename Arg, std::size_t...Ix>
32  constexpr decltype(auto) make_fixed_size_adapter_like_impl(Arg&& arg, std::index_sequence<Ix...>)
33  {
34  if constexpr (sizeof...(Ts) == 0) return std::forward<Arg>(arg);
35  else
36  {
37  using F = decltype(make_fixed_size_adapter<decltype(best_desc_Ts_impl<Ix>(std::declval<Ts>()...))...>(std::declval<Arg&&>()));
38  constexpr bool better = (... or (dynamic_dimension<Arg, Ix> and not dynamic_dimension<F, Ix>));
39  if constexpr (better) return F {std::forward<Arg>(arg)};
40  else return std::forward<Arg>(arg);
41  }
42  }
43  } // namespace detail
44 
45 
51 #ifdef __cpp_concepts
52  template<indexible...Ts, vector_space_descriptors_may_match_with<Ts...> Arg> requires (index_count_v<Arg> != dynamic_size)
53 #else
54  template<typename...Ts, typename Arg, std::enable_if_t<(... and indexible<Ts>) and
55  vector_space_descriptors_may_match_with<Arg, Ts...> and (index_count_v<Arg> != dynamic_size), int> = 0>
56 #endif
57  constexpr decltype(auto)
58  make_fixed_size_adapter_like(Arg&& arg)
59  {
60  constexpr auto min_count = std::min({index_count_v<Arg>,
61  (index_count_v<Ts> == dynamic_size ? index_count_v<Arg> : index_count_v<Ts>)...});
62  return detail::make_fixed_size_adapter_like_impl<Ts...>(std::forward<Arg>(arg), std::make_index_sequence<min_count>{});
63  }
64 
65 
66 } // namespace OpenKalman::internal
67 
68 #endif //OPENKALMAN_MAKE_FIXED_SIZE_ADAPTER_LIKE_HPP
decltype(auto) constexpr best_vector_space_descriptor(D &&d, Ds &&...ds)
Given one or more /ref coordinates::pattern objects, return the "best" one (i.e., the one that is sta...
Definition: best_vector_space_descriptor.hpp:32
constexpr bool indexible
T is a generalized tensor type.
Definition: indexible.hpp:32
Definition: tuple_reverse.hpp:103
constexpr bool vector_space_descriptors_may_match_with
Specifies that indexible objects Ts may have equivalent dimensions and vector-space types...
Definition: vector_space_descriptors_may_match_with.hpp:49
constexpr std::size_t dynamic_size
A constant indicating that a size or index is dynamic.
Definition: global-definitions.hpp:33
Definition: basics.hpp:48