OpenKalman
uniform_pattern.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_UNIFORM_PATTERN_HPP
17 #define OPENKALMAN_UNIFORM_PATTERN_HPP
18 
22 
24 {
25  namespace detail
26  {
27  template<typename T, typename C = void, std::size_t i = 0>
28  constexpr auto
29  heterogeneous_pattern_impl()
30  {
31  if constexpr (i < collections::size_of_v<T>)
32  {
33  using A = common_descriptor_type_t<collections::collection_element_t<i, T>>;
34  if constexpr (i == 0)
35  {
36  return heterogeneous_pattern_impl<T, A, i + 1>();
37  }
38  else
39  {
40  constexpr auto dA = dimension_of_v<A>;
41  if constexpr ((dA != stdex::dynamic_extent and dA != 1) or not compares_with<C, A, &stdex::is_eq, applicability::permitted>)
42  return std::true_type {};
43  else if constexpr (dA != stdex::dynamic_extent and dimension_of_v<C> == stdex::dynamic_extent)
44  return heterogeneous_pattern_impl<T, A, i + 1>();
45  else
46  return heterogeneous_pattern_impl<T, C, i + 1>();
47  }
48  }
49  else
50  {
51  return std::false_type{};
52  }
53  }
54 
55 
56 #ifdef __cpp_concepts
57  template<typename T>
58 #else
59  template<typename T, typename = void>
60 #endif
61  struct heterogeneous_pattern : std::false_type {};
62 
63 
64 #ifdef __cpp_concepts
65  template<descriptor T>
66  struct heterogeneous_pattern<T>
67 #else
68  template<typename T>
69  struct heterogeneous_pattern<T, std::enable_if_t<descriptor<T>>>
70 #endif
71  : std::bool_constant<
72  (not euclidean_pattern<T>) and
73  (dimension_of_v<T> != stdex::dynamic_extent) and
74  (dimension_of_v<T> != 1)
75  > {};
76 
77 
78 #ifdef __cpp_concepts
79  template<descriptor_collection T> requires
80  collections::sized<T> and
81  (collections::size_of_v<T> != stdex::dynamic_extent) and
82  (collections::size_of_v<T> > 1) and
83  collections::uniformly_gettable<T>
84  struct heterogeneous_pattern<T>
85 #else
86  template<typename T>
87  struct heterogeneous_pattern<T, std::enable_if_t<
88  descriptor_collection<T> and
89  values::fixed_value_compares_with<collections::size_of<T>, stdex::dynamic_extent, &stdex::is_neq> and
90  values::fixed_value_compares_with<collections::size_of<T>, 1, &stdex::is_gt> and
91  collections::uniformly_gettable<T>
92  >>
93 #endif
94  : std::bool_constant<heterogeneous_pattern_impl<T>()> {};
95 
96 
97 #ifdef __cpp_concepts
98  template<descriptor_collection T> requires
99  (not collections::uniformly_gettable<T>) and
100  (dimension_of_v<common_descriptor_type_t<T>> != stdex::dynamic_extent) and
102  struct heterogeneous_pattern<T>
103 #else
104  template<typename T>
105  struct heterogeneous_pattern<T, std::enable_if_t<
106  descriptor_collection<T> and
107  (not collections::uniformly_gettable<T>) and
108  values::fixed_value_compares_with<dimension_of<common_descriptor_type_t<T>>, stdex::dynamic_extent, &stdex::is_neq> and
109  values::fixed_value_compares_with<dimension_of<common_descriptor_type_t<T>>, 1, &stdex::is_neq>
110  >>
111 #endif
112  : std::true_type {};
113 
114 
115 #ifndef __cpp_concepts
116  template<typename T, typename = void>
117  struct is_uniform_pattern_impl : std::false_type {};
118 
119  template<typename T>
120  struct is_uniform_pattern_impl<T, std::void_t<typename uniform_pattern_type<T>::type>>
121  : std::true_type {};
122 #endif
123 
124  }
125 
126 
131  template<typename T, applicability a = applicability::guaranteed>
132 #ifdef __cpp_concepts
133  concept uniform_pattern =
134  (a == applicability::guaranteed and requires { typename uniform_pattern_type<T>::type; }) or
136 #else
137  constexpr bool uniform_pattern =
139  (a == applicability::permitted and not detail::heterogeneous_pattern<T>::value);
140 #endif
141 
142 
143 }
144 
145 #endif
typename common_descriptor_type< T >::type common_descriptor_type_t
Helper template for common_descriptor_type.
Definition: common_descriptor_type.hpp:126
Definition for compares_with.
If T is a uniform_pattern, type is an alias for the uniform component.
Definition: uniform_pattern_type.hpp:37
The concept, trait, or restraint represents a compile-time guarantee.
The concept, trait, or restraint is permitted, but whether it applies is not necessarily known at com...
constexpr auto dimension_of_v
Helper template for coordinates::dimension_of.
Definition: dimension_of.hpp:56
Definition for uniform_pattern_type.
The namespace for features relating to coordinates::pattern object.
Definition: compares_with.hpp:25
Inclusion file for collections.
constexpr bool uniform_pattern
T is a coordinates::pattern that is either empty or can be decomposed into a uniform set of 1D coordi...
Definition: uniform_pattern.hpp:137