OpenKalman
cast_to.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) 2024-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 
17 #ifndef OPENKALMAN_VALUES_CAST_TO_HPP
18 #define OPENKALMAN_VALUES_CAST_TO_HPP
19 
20 #include <cstdint>
21 #include "basics/basics.hpp"
28 
29 namespace OpenKalman::values
30 {
36  template<typename T, typename Arg>
37  struct fixed_cast
38  {
39  using value_type = T;
40  static constexpr auto value {static_cast<value_type>(values::fixed_value_of_v<Arg>)};
41  using type = fixed_cast;
42  constexpr operator value_type() const { return value; }
43  constexpr value_type operator()() const { return value; }
44  };
45 
46 
47 #ifndef __cpp_concepts
48  namespace detail
49  {
50  template<typename Arg, typename T, typename = void>
51  struct value_type_convertible : std::false_type {};
52 
53  template<typename Arg, typename T>
54  struct value_type_convertible<Arg, T, std::enable_if_t<
55  stdex::convertible_to<typename value_type_of<Arg>::type, T>>>
56  : std::true_type {};
57 
58 
59  template<typename T, typename Arg, typename = void, typename = void>
60  struct is_fixable : std::false_type {};
61 
62  template<typename T, typename Arg>
63  struct is_fixable<T, Arg, std::void_t<fixed_value<T, fixed_value_of_v<Arg>>>>
64  : std::true_type {};
65 
66 
67  template<typename Arg, typename T, typename = void>
68  struct real_types_convertible : std::false_type {};
69 
70  template<typename Arg, typename T>
71  struct real_types_convertible<Arg, T, std::enable_if_t<
72  stdex::convertible_to<typename real_type_of<Arg>::type, typename real_type_of<T>::type> >>
73  : std::true_type {};
74  }
75 #endif
76 
77 
85 #ifdef __cpp_concepts
86  template<typename T, typename Arg> requires
87  std::same_as<T, std::decay_t<T>> and
88  (not number<T> or not complex<Arg>) and
89  std::convertible_to<value_type_of_t<Arg>, T>
90 #else
91  template<typename T, typename Arg, std::enable_if_t<
92  (not number<T> or not complex<Arg>) and
93  std::is_same_v<T, std::decay_t<T>> and
95 #endif
96  constexpr decltype(auto)
97  cast_to(Arg&& arg)
98  {
99  if constexpr (std::is_same_v<T, value_type_of_t<Arg>>)
100  {
101  return std::forward<Arg>(arg);
102  }
103  else if constexpr (fixed<Arg>)
104  {
105 #ifdef __cpp_concepts
106  if constexpr (requires { typename fixed_value<T, fixed_value_of_v<Arg>>; })
107 #else
108  if constexpr (detail::is_fixable<T, Arg>::value)
109 #endif
111  else
112  return fixed_cast<T, std::decay_t<Arg>>{};
113  }
114  else
115  {
116  return static_cast<T>(values::to_value_type(std::forward<Arg>(arg)));
117  }
118  }
119 
120 
129 #ifdef __cpp_concepts
130  template<number T, complex Arg> requires
131  std::same_as<T, std::decay_t<T>> and
132  std::convertible_to<real_type_of_t<Arg>, real_type_of_t<T>>
133  constexpr complex decltype(auto)
134 #else
135  template<typename T, typename Arg, std::enable_if_t<
136  number<T> and
137  complex<Arg> and
138  std::is_same_v<T, std::decay_t<T>> and
140  constexpr decltype(auto)
141 #endif
142  cast_to(Arg&& arg)
143  {
144  if constexpr (std::is_same_v<T, value_type_of_t<Arg>>)
145  return std::forward<Arg>(arg);
146  else
147  return internal::make_complex_number<real_type_of_t<T>>(std::forward<Arg>(arg));
148  }
149 
150 }
151 
152 #endif
typename real_type_of< T >::type real_type_of_t
Helper template for real_type_of.
Definition: real_type_of.hpp:55
Definition: fixed_value.hpp:41
typename value_type_of< T >::type value_type_of_t
Helper template for value_type_of.
Definition: value_type_of.hpp:52
constexpr bool complex
T is a value that reduces to std::complex or a custom complex type.
Definition: complex.hpp:47
Definition for values::to_value_type.
decltype(auto) constexpr to_value_type(Arg &&arg)
Convert, if necessary, a fixed or dynamic value to its underlying base type.
Definition: to_value_type.hpp:28
Definition for value:value_type_of and value:value_type_of_t.
A fixed value cast from another fixed value.
Definition: cast_to.hpp:37
Definition for values::abs.
Definition: fixed-constants.hpp:23
decltype(auto) constexpr cast_to(Arg &&arg)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: cast_to.hpp:97
Definition: cast_to.hpp:60
Basic definitions for OpenKalman as a whole.
Definition for values::complex.
Definition for values::value.