OpenKalman
square_shaped.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) 2019-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_SQUARE_SHAPED_HPP
17 #define OPENKALMAN_SQUARE_SHAPED_HPP
18 
19 #include "coordinates/coordinates.hpp"
20 #include "../interfaces/object_traits.hpp"
23 
24 namespace OpenKalman
25 {
26  namespace detail
27  {
28 #ifndef __cpp_concepts
29  template<typename T, applicability b, typename = void>
30  struct is_explicitly_square : std::false_type {};
31 
32  template<typename T, applicability b>
33  struct is_explicitly_square<T, b, std::enable_if_t<interface::object_traits<stdex::remove_cvref_t<T>>::template is_square<b>>>
34  : std::true_type {};
35 #endif
36 
37  template<typename T, std::size_t i>
38  constexpr std::size_t
39  best_square_index()
40  {
41  if constexpr (i == 0) return i;
42  else if constexpr (coordinates::fixed_pattern<decltype(get_index_pattern<i - 1>(std::declval<T>()))>) return i - 1;
43  else return best_square_index<T, i - 1>();
44  }
45 
46 
47  template<typename T, applicability b, std::size_t...is>
48  constexpr auto
49  square_shaped_fixed_index_count(std::index_sequence<is...>)
50  {
51  constexpr std::size_t best = best_square_index<T, sizeof...(is)>();
52  using best_patt = decltype(get_index_pattern<best>(std::declval<T>()));
53  return (... and (is == best or
54  coordinates::compares_with<decltype(get_index_pattern<is>(std::declval<T>())), best_patt, stdex::is_eq, b>));
55  }
56 
57 
58  template<typename T, applicability b>
59  constexpr auto
60  square_shaped_impl()
61  {
62  if constexpr (not indexible<T>) // Only needed for c++17 mode
63  return false;
64  else if constexpr (index_count_v<T> == 1)
65  return index_dimension_of_v<T, 0> == 1;
66  else
67  return detail::square_shaped_fixed_index_count<T, b>(std::make_index_sequence<index_count_v<T>>{});
68  }
69 
70  }
71 
72 
81  template<typename T, applicability b = applicability::guaranteed>
82 #ifdef __cpp_concepts
83  concept square_shaped =
84  indexible<T> and
85  (not interface::is_square_defined_for<T, b> or
86  interface::object_traits<stdex::remove_cvref_t<T>>::template is_square<b>) and
87  (interface::is_square_defined_for<T, b> or
88  detail::square_shaped_impl<T, b>());
89 #else
90  constexpr bool square_shaped =
91  indexible<T> and
92  (interface::is_square_defined_for<T, b> ?
94  detail::square_shaped_impl<T, b>());
95 #endif
96 
97 
98 }
99 
100 #endif
applicability
The applicability of a concept, trait, or restraint.
Definition: constants.hpp:35
The root namespace for OpenKalman.
Definition: basics.hpp:34
Definition: object_traits.hpp:38
constexpr bool fixed_pattern
A coordinates::pattern for which the dimension is fixed at compile time.
Definition: fixed_pattern.hpp:46
Definition: square_shaped.hpp:30
Definition for index_count.
Definition of get_index_pattern function.
Definition: trait_backports.hpp:64
constexpr bool compares_with
Compares two coordinates::pattern objects.
Definition: compares_with.hpp:475
constexpr bool square_shaped
Specifies that an object is square (i.e., has equivalent coordinates::pattern along each dimension)...
Definition: square_shaped.hpp:90