OpenKalman
exposition.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_STD_EXPOSITION_FEATURES_HPP
17 #define OPENKALMAN_STD_EXPOSITION_FEATURES_HPP
18 
19 #include <type_traits>
20 #include <utility>
22 
23 namespace OpenKalman::internal
24 {
25  namespace detail
26  {
27  struct decay_copy_impl final
28  {
29  template<typename T>
30  constexpr std::decay_t<T> operator()(T&& t) const noexcept { return std::forward<T>(t); }
31  };
32  }
33 
34  inline constexpr detail::decay_copy_impl decay_copy;
35 
36 
37  namespace detail
38  {
39  template<typename T, typename = void>
40  struct is_integer_like_impl : std::false_type {};
41 
42  template<>
43  struct is_integer_like_impl<bool> : std::false_type {};
44 
45  template<>
46  struct is_integer_like_impl<const bool> : std::false_type {};
47 
48  template<>
49  struct is_integer_like_impl<volatile bool> : std::false_type {};
50 
51  template<>
52  struct is_integer_like_impl<const volatile bool> : std::false_type {};
53 
54  template<typename T>
55  struct is_integer_like_impl<T, std::enable_if_t<std::is_integral_v<T>>> : std::true_type {};
56  }
57 
58  template<typename T>
59  inline constexpr bool is_integer_like = detail::is_integer_like_impl<T>::value;
60 
61  template<typename T>
62  inline constexpr bool is_signed_integer_like = is_integer_like<T> and std::is_signed_v<T>;
63 
64  template<typename T>
65  inline constexpr bool is_unsigned_integer_like = is_integer_like<T> and std::is_unsigned_v<T>;
66 
67 
68  // -------------------- //
69  // is_initializer_list //
70  // -------------------- //
71 
75  template<typename T>
76  struct is_initializer_list : std::false_type {};
77 
79  template<typename T>
80  struct is_initializer_list<std::initializer_list<T>> : std::true_type {};
81 
83  template<typename T>
85 
87  template<typename T>
89 
91  template<typename T>
92  struct is_initializer_list<const T> : is_initializer_list<T> {};
93 
95  template<typename T>
96  struct is_initializer_list<volatile T> : is_initializer_list<T> {};
97 
98 
99  // ----------------- //
100  // boolean_testable //
101  // ----------------- //
102 
103  namespace detail
104  {
105 #ifdef __cpp_concepts
106  template<typename B>
107  concept boolean_testable_impl = std::convertible_to<B, bool>;
108 #else
109  template<typename B, typename = void>
110  struct boolean_testable_impl1 : std::false_type {};
111 
112  template<typename B>
113  struct boolean_testable_impl1<B, std::enable_if_t<stdex::convertible_to<B, bool>>> : std::true_type {};
114 
115 
116  template<typename B, typename = void>
117  struct boolean_testable_impl2 : std::false_type {};
118 
119  template<typename B>
120  struct boolean_testable_impl2<B, std::enable_if_t<
121  detail::boolean_testable_impl1<B>::value and detail::boolean_testable_impl1<decltype(not std::declval<B>())>::value>> : std::true_type {};
122 #endif
123  }
124 
125 
126 #ifdef __cpp_concepts
127  template<typename B>
128  concept boolean_testable =
129  detail::boolean_testable_impl<B> and
130  requires (B&& b) { { not std::forward<B>(b) } -> detail::boolean_testable_impl; };
131 #else
132  template<typename B>
133  inline constexpr bool boolean_testable =
135 #endif
136 
137 
138  // ----------------------------- //
139  // WeaklyEqualityComparableWith //
140  // ----------------------------- //
141 
142 #ifdef __cpp_concepts
143  template<typename T, typename U>
144  concept WeaklyEqualityComparableWith =
145  requires(const std::remove_reference_t<T>& t, const std::remove_reference_t<U>& u) {
146  { t == u } -> boolean_testable;
147  { t != u } -> boolean_testable;
148  { u == t } -> boolean_testable;
149  { u != t } -> boolean_testable;
150  };
151 #else
152  namespace detail
153  {
154  template<typename T, typename U, typename = void>
155  struct WeaklyEqualityComparableWithImpl : std::false_type {};
156 
157  template<typename T, typename U>
158  struct WeaklyEqualityComparableWithImpl<T, U, std::enable_if_t<
159  boolean_testable<decltype(std::declval<const std::remove_reference_t<T>&>() == std::declval<const std::remove_reference_t<U>&>())> and
160  boolean_testable<decltype(std::declval<const std::remove_reference_t<T>&>() != std::declval<const std::remove_reference_t<U>&>())> and
161  boolean_testable<decltype(std::declval<const std::remove_reference_t<U>&>() == std::declval<const std::remove_reference_t<T>&>())> and
162  boolean_testable<decltype(std::declval<const std::remove_reference_t<U>&>() != std::declval<const std::remove_reference_t<T>&>())>
163  >> : std::true_type {};
164  }
165 
166  template<typename T, typename U>
167  inline constexpr bool
168  WeaklyEqualityComparableWith = detail::WeaklyEqualityComparableWithImpl<T, U>::value;
169 #endif
170 
171 
172  // --------------------- //
173  // PartiallyOrderedWith //
174  // --------------------- //
175 
176 #ifdef __cpp_concepts
177  template<typename T, typename U>
178  concept PartiallyOrderedWith =
179  requires(const std::remove_reference_t<T>& t, const std::remove_reference_t<U>& u) {
180  { t < u } -> boolean_testable;
181  { t > u } -> boolean_testable;
182  { t <= u } -> boolean_testable;
183  { t >= u } -> boolean_testable;
184  { u < t } -> boolean_testable;
185  { u > t } -> boolean_testable;
186  { u <= t } -> boolean_testable;
187  { u >= t } -> boolean_testable;
188  };
189 #else
190  namespace detail
191  {
192  template<typename T, typename U, typename = void>
193  struct PartiallyOrderedWithImpl : std::false_type {};
194 
195  template<typename T, typename U>
196  struct PartiallyOrderedWithImpl<T, U, std::enable_if_t<
197  OpenKalman::internal::boolean_testable<decltype(std::declval<const std::remove_reference_t<T>&>() < std::declval<const std::remove_reference_t<U>&>())> and
198  OpenKalman::internal::boolean_testable<decltype(std::declval<const std::remove_reference_t<T>&>() > std::declval<const std::remove_reference_t<U>&>())> and
199  OpenKalman::internal::boolean_testable<decltype(std::declval<const std::remove_reference_t<T>&>() <= std::declval<const std::remove_reference_t<U>&>())> and
200  OpenKalman::internal::boolean_testable<decltype(std::declval<const std::remove_reference_t<T>&>() >= std::declval<const std::remove_reference_t<U>&>())> and
201  OpenKalman::internal::boolean_testable<decltype(std::declval<const std::remove_reference_t<U>&>() < std::declval<const std::remove_reference_t<T>&>())> and
202  OpenKalman::internal::boolean_testable<decltype(std::declval<const std::remove_reference_t<U>&>() > std::declval<const std::remove_reference_t<T>&>())> and
203  OpenKalman::internal::boolean_testable<decltype(std::declval<const std::remove_reference_t<U>&>() <= std::declval<const std::remove_reference_t<T>&>())> and
204  OpenKalman::internal::boolean_testable<decltype(std::declval<const std::remove_reference_t<U>&>() >= std::declval<const std::remove_reference_t<T>&>())>
205  >> : std::true_type {};
206  }
207 
208  template<typename T, typename U>
209  inline constexpr bool
210  PartiallyOrderedWith = detail::PartiallyOrderedWithImpl<T, U>::value;
211 #endif
212 
213 
214 }
215 
216 
217 #endif
Definitions relating to standard c++ library concepts.
Whether the argument is a specialization of std::initializer_list.
Definition: exposition.hpp:76
Definition: basics.hpp:48