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 
19 namespace OpenKalman
20 {
34 #ifdef __cpp_concepts
35  template<indexible T, Layout layout = Layout::none, values::number Scalar = scalar_type_of_t<T>, coordinates::pattern...Ds, std::convertible_to<const Scalar> ... Args>
36  requires (layout != Layout::stride) and
37  (((coordinates::dimension_of_v<Ds> == 0) or ...) ? sizeof...(Args) == 0 :
38  (sizeof...(Args) % ((dynamic_pattern<Ds> ? 1 : coordinates::dimension_of_v<Ds>) * ... * 1) == 0))
39  inline writable auto
40 #else
41  template<typename T, Layout layout = Layout::none, typename Scalar = scalar_type_of_t<T>, typename...Ds, typename...Args, std::enable_if_t<
42  indexible<T> and values::number<Scalar> and (coordinates::pattern<Ds> and ...) and
43  (std::is_convertible_v<Args, const Scalar> and ...) and (layout != Layout::stride) and
44  (((coordinates::dimension_of<Ds>::value == 0) or ...) ? sizeof...(Args) == 0 :
45  (sizeof...(Args) % ((dynamic_pattern<Ds> ? 1 : coordinates::dimension_of<Ds>::value) * ... * 1) == 0)), int> = 0>
46  inline auto
47 #endif
48  make_dense_object_from(const std::tuple<Ds...>& d_tup, Args...args)
49  {
50  auto m = make_dense_object<T, layout, Scalar>(d_tup);
51  if constexpr (sizeof...(Args) > 0)
52  {
53  constexpr Layout l = layout == Layout::none ? Layout::right : layout;
54  return fill_components<l>(m, static_cast<const Scalar>(args)...);
55  }
56  else return m;
57  }
58 
59 
60  namespace detail
61  {
62  template<typename T, std::size_t...Is>
63  constexpr bool zero_dimension_count_impl(std::index_sequence<Is...>)
64  {
65  return ((dimension_size_of_index_is<T, Is, 0> ? 1 : 0) + ... + 0);
66  }
67 
68 
69  template<typename T>
70  struct zero_dimension_count : std::integral_constant<std::size_t,
71  zero_dimension_count_impl<T>(std::make_index_sequence<index_count_v<T>>{})> {};
72 
73 
74  template<typename T, Layout layout, typename Scalar, std::size_t...I, typename...Args>
75  inline auto make_dense_object_from_impl(std::index_sequence<I...>, Args...args)
76  {
77  std::tuple d_tup {[]{
78  if constexpr (dynamic_dimension<T, I>) // There will be only one dynamic dimension, at most.
79  {
80  constexpr auto dims = ((dynamic_dimension<T, I> ? 1 : index_dimension_of_v<T, I>) * ... * 1);
81  if constexpr (dims == 0) return coordinates::Dimensions<0>{};
82  else return coordinates::Dimensions<sizeof...(Args) / dims>{};
83  }
85  }()...};
86  return make_dense_object_from<T, layout, Scalar>(d_tup, args...);
87  }
88 
89  } // namespace detail
90 
91 
103 #ifdef __cpp_concepts
104  template<indexible T, Layout layout = Layout::none, values::number Scalar = scalar_type_of_t<T>, std::convertible_to<const Scalar> ... Args>
105  requires (layout != Layout::stride) 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, Layout layout = Layout::none, typename Scalar = scalar_type_of_t<T>, typename ... Args, std::enable_if_t<
110  indexible<T> and values::number<Scalar> and (std::is_convertible_v<Args, const Scalar> and ...) and
111  (layout != Layout::stride) and internal::may_hold_components<T, Args...> and
112  (dynamic_index_count_v<T> + detail::zero_dimension_count<T>::value <= 1), int> = 0>
113  inline auto
114 #endif
115  make_dense_object_from(Args...args)
116  {
117  constexpr std::make_index_sequence<index_count_v<T>> seq;
118  return detail::make_dense_object_from_impl<T, layout, Scalar>(seq, args...);
119  }
120 
121 
122 } // namespace OpenKalman
123 
124 #endif //OPENKALMAN_MAKE_DENSE_OBJECT_FROM_HPP
Row-major storage (C or C++ style): contiguous storage in which the right-most index has a stride of ...
No storage layout (e.g., if the elements are calculated rather than stored).
The root namespace for OpenKalman.
Definition: basics.hpp:34
A generalization of the above: a custom stride is specified for each index.
typename vector_space_descriptor_of< T, N >::type vector_space_descriptor_of_t
helper template for vector_space_descriptor_of.
Definition: vector_space_descriptor_of.hpp:56
Layout
The layout format of a multidimensional array.
Definition: global-definitions.hpp:47
A structure representing the dimensions associated with of a particular index.
Definition: Dimensions.hpp:42
Definition: make_dense_object_from.hpp:70
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:48