OpenKalman
make_complex_number.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-2024 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_MAKE_COMPLEX_NUMBER_HPP
18 #define OPENKALMAN_MAKE_COMPLEX_NUMBER_HPP
19 
23 #include "values/math/real.hpp"
24 #include "values/math/imag.hpp"
26 
28 {
36 #ifdef __cpp_concepts
37  template<values::complex T, std::convertible_to<real_type_of_t<T>> Re, std::convertible_to<real_type_of_t<T>> Im = Re> requires
38  values::value<Re> and values::value<Im> and (not values::complex<Re>) and (not values::complex<Im>)
39 #else
40  template<typename T, typename Re, typename Im = Re, std::enable_if_t<values::complex<T> and
41  std::is_convertible_v<Re, real_type_of_t<T>> and std::is_convertible_v<Im, real_type_of_t<T>> and
42  values::value<Re> and values::value<Im> and (not values::complex<Re>) and (not values::complex<Im>), int> = 0>
43 #endif
44  constexpr std::decay_t<T>
45  make_complex_number(Re&& re, Im&& im = 0)
46  {
47  return interface::number_traits<std::decay_t<T>>::make_complex(std::forward<Re>(re), std::forward<Im>(im));
48  }
49 
50 
58 #ifdef __cpp_concepts
59  template<values::value T, values::complex Arg> requires std::constructible_from<real_type_of_t<T>, real_type_of_t<Arg>>
60  constexpr values::complex decltype(auto)
61 #else
62  template<typename T, typename Arg, std::enable_if_t<values::value<T> and values::complex<Arg> and
63  std::is_constructible_v<real_type_of_t<T>, real_type_of_t<Arg>>, int> = 0>
64  constexpr decltype(auto)
65 #endif
66  make_complex_number(Arg&& arg)
67  {
68  using R = real_type_of_t<T>;
69  if constexpr (std::is_same_v<R, std::decay_t<Arg>>)
70  {
71  return std::forward<Arg>(arg);
72  }
73  else
74  {
75  return interface::number_traits<std::decay_t<T>>::make_complex(
76  static_cast<R>(values::real(arg)), static_cast<R>(values::imag(arg)));
77  }
78  }
79 
80 
88 #ifdef __cpp_concepts
89  template<values::number Re, values::number Im> requires
90  (not values::complex<Re>) and (not values::complex<Im>) and std::common_with<Re, Im>
91  constexpr values::complex auto
92 #else
93  template<typename Re, typename Im, std::enable_if_t<values::number<Re> and values::number<Im> and
94  (not values::complex<Re>) and (not values::complex<Im>), int> = 0>
95  constexpr auto
96 #endif
97  make_complex_number(const Re& re, const Im& im = 0)
98  {
99  return interface::number_traits<std::decay_t<std::common_type_t<Re, Im>>>::make_complex(re, im);
100  }
101 
102 
103 } // namespace OpenKalman::values::internal
104 
105 #endif //OPENKALMAN_MAKE_COMPLEX_NUMBER_HPP
constexpr auto imag(Arg arg)
A constexpr function to obtain the imaginary part of a (complex) number.
Definition: imag.hpp:40
constexpr bool complex
T is a values::value that reduces to std::complex or a custom complex type.
Definition: complex.hpp:46
Definition for values::imag.
Definition of utilities for atan functions.
Definition: dynamic.hpp:26
constexpr auto real(Arg arg)
A constexpr function to obtain the real part of a (complex) number.
Definition: real.hpp:40
Definition for value:real_type_of_t.
Definition for values::number.
Definition for values::real.
Traits for arithmetic and complex scalar types.
Definition for ::complex.