OpenKalman
make_dense_object_from.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 
16 #ifndef OPENKALMAN_MAKE_DENSE_OBJECT_FROM_HPP
17 #define OPENKALMAN_MAKE_DENSE_OBJECT_FROM_HPP
18 
20 
21 namespace OpenKalman
22 {
35 #ifdef __cpp_concepts
36  template<indexible T, internal::layout_mapping_policy layout = stdex::layout_right, values::number Scalar = element_type_of_t<T>, coordinates::pattern...Ds, std::convertible_to<const Scalar> ... Args>
37  requires (std::same_as<layout, stdex::layout_right> or std::same_as<layout, stdex::layout_left>) and
38  (((coordinates::dimension_of_v<Ds> == 0) or ...) ? sizeof...(Args) == 0 :
39  (sizeof...(Args) % ((dynamic_pattern<Ds> ? 1 : coordinates::dimension_of_v<Ds>) * ... * 1) == 0))
40  inline writable auto
41 #else
42  template<typename T, typename layout = stdex::layout_right, typename Scalar = element_type_of_t<T>, typename...Ds, typename...Args, std::enable_if_t<
43  indexible<T> and values::number<Scalar> and (coordinates::pattern<Ds> and ...) and
44  (stdex::convertible_to<Args, const Scalar> and ...) and
45  (stdex::same_as<layout, stdex::layout_right> or stdex::same_as<layout, stdex::layout_left>) and
46  (((coordinates::dimension_of<Ds>::value == 0) or ...) ? sizeof...(Args) == 0 :
47  (sizeof...(Args) % ((dynamic_pattern<Ds> ? 1 : coordinates::dimension_of<Ds>::value) * ... * 1) == 0)), int> = 0>
48  inline auto
49 #endif
50  make_dense_object_from(const std::tuple<Ds...>& d_tup, Args...args)
51  {
52  auto m = make_dense_object<T, layout, Scalar>(d_tup);
53  if constexpr (sizeof...(Args) > 0)
54  {
55  return fill_components<layout>(m, static_cast<const Scalar>(args)...);
56  }
57  else return m;
58  }
59 
60 
61  namespace detail
62  {
63  template<typename T, std::size_t...Is>
64  constexpr bool zero_dimension_count_impl(std::index_sequence<Is...>)
65  {
66  return ((dimension_size_of_index_is<T, Is, 0> ? 1 : 0) + ... + 0);
67  }
68 
69 
70  template<typename T>
71  struct zero_dimension_count : std::integral_constant<std::size_t,
72  zero_dimension_count_impl<T>(std::make_index_sequence<index_count_v<T>>{})> {};
73 
74 
75  template<typename T, typename layout, typename Scalar, std::size_t...I, typename...Args>
76  inline auto make_dense_object_from_impl(std::index_sequence<I...>, Args...args)
77  {
78  std::tuple d_tup {[]{
79  if constexpr (dynamic_dimension<T, I>) // There will be only one dynamic dimension, at most.
80  {
81  constexpr auto dims = ((dynamic_dimension<T, I> ? 1 : index_dimension_of_v<T, I>) * ... * 1);
82  if constexpr (dims == 0) return coordinates::Dimensions<0>{};
83  else return coordinates::Dimensions<sizeof...(Args) / dims>{};
84  }
85  else return std::decay_t<decltype(get_pattern_collection(std::declval<T>(), std::integral_constant<std::size_t, I>{}))> {};
86  }()...};
87  return make_dense_object_from<T, layout, Scalar>(d_tup, args...);
88  }
89 
90  }
91 
92 
103 #ifdef __cpp_concepts
104  template<indexible T, internal::layout_mapping_policy layout = stdex::layout_right, values::number Scalar = element_type_of_t<T>, std::convertible_to<const Scalar> ... Args>
105  requires (std::same_as<layout, stdex::layout_right> or std::same_as<layout, stdex::layout_left>) and internal::may_hold_components<T, Args...> and
106  (dynamic_index_count_v<T> + detail::zero_dimension_count<T>::value <= 1)
107  inline writable auto
108 #else
109  template<typename T, typename layout = std::compat::layout_right, typename Scalar = element_type_of_t<T>, typename ... Args, std::enable_if_t<
110  indexible<T> and values::number<Scalar> and (stdex::convertible_to<Args, const Scalar> and ...) and
111  (stdex::same_as<layout, stdex::layout_right> or stdex::same_as<layout, stdex::layout_left>) and
112  internal::may_hold_components<T, Args...> and
113  (dynamic_index_count_v<T> + detail::zero_dimension_count<T>::value <= 1), int> = 0>
114  inline auto
115 #endif
116  make_dense_object_from(Args...args)
117  {
118  constexpr std::make_index_sequence<index_count_v<T>> seq;
119  return detail::make_dense_object_from_impl<T, layout, Scalar>(seq, args...);
120  }
121 
122 
123 }
124 
125 #endif
Definition for layout_mapping_policy.
The root namespace for OpenKalman.
Definition: basics.hpp:34
A structure representing the dimensions associated with of a particular index.
Definition: Dimensions.hpp:42
Definition: trait_backports.hpp:64
Definition: make_dense_object_from.hpp:71
auto make_dense_object_from(const std::tuple< Ds... > &d_tup, Args...args)
Create a dense, writable matrix from the library of which dummy type T is a member, filled with a set of scalar components.
Definition: make_dense_object_from.hpp:50