Skip to content

Commit b802b7c

Browse files
committed
Add complex number support
1 parent b56de86 commit b802b7c

File tree

1 file changed

+76
-33
lines changed

1 file changed

+76
-33
lines changed

include/boost/math/concepts/concepts.hpp

Lines changed: 76 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <type_traits>
1717
#include <limits>
1818
#include <iterator>
19+
#include <complex>
1920
#include <boost/math/tools/config.hpp>
2021
#include <boost/math/policies/policy.hpp>
2122

@@ -79,32 +80,45 @@ inline constexpr bool has_##member##_v = is_detected<has_##member##_t, T>::value
7980

8081
BOOST_MATH_HAS_MEMBER_FUNCTION(begin)
8182
BOOST_MATH_HAS_MEMBER_FUNCTION(end)
83+
BOOST_MATH_HAS_MEMBER_FUNCTION(real)
84+
BOOST_MATH_HAS_MEMBER_FUNCTION(imag)
8285

8386
} // Namespace detail
8487

8588
template <typename T>
86-
concept Integral = std::is_integral_v<T>;
89+
concept integral = std::is_integral_v<T>;
8790

8891
template <typename T>
89-
concept Signed_integral = Integral<T> && std::is_signed_v<T>;
92+
concept signed_integral = integral<T> && std::is_signed_v<T>;
9093

9194
template <typename T>
92-
concept Unsigned_integral = Integral<T> && std::is_unsigned_v<T>;
95+
concept unsigned_integral = integral<T> && std::is_unsigned_v<T>;
9396

9497
template <typename T>
95-
concept Real = std::is_floating_point_v<T>;
98+
concept real = std::is_floating_point_v<T>;
9699

97100
template <typename T>
98-
concept Arithmetic = std::is_arithmetic_v<T>;
101+
concept complex = std::is_same_v<T, std::complex<float>>
102+
|| std::is_same_v<T, std::complex<double>>
103+
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
104+
|| std::is_same_v<T, std::complex<long double>>
105+
#endif
106+
;
99107

100108
template <typename T>
101-
concept Signed_arithmetic = Arithmetic<T> && std::is_signed_v<T>;
109+
concept real_or_complex = real<T> || complex<T>;
102110

103111
template <typename T>
104-
concept Unsigned_arithmetic = Arithmetic<T> && std::is_unsigned_v<T>;
112+
concept arithmetic = std::is_arithmetic_v<T>;
105113

106114
template <typename T>
107-
concept Arbitrary_unsigned_arithmetic_type = Unsigned_arithmetic<T> ||
115+
concept signed_arithmetic = arithmetic<T> && std::is_signed_v<T>;
116+
117+
template <typename T>
118+
concept unsigned_arithmetic = arithmetic<T> && std::is_unsigned_v<T>;
119+
120+
template <typename T>
121+
concept arbitrary_unsigned_arithmetic_type = unsigned_arithmetic<T> ||
108122
(detail::op_valid_v<T, T, std::equal_to<>> &&
109123
detail::op_valid_v<T, T, std::not_equal_to<>> &&
110124
detail::op_valid_v<T, T, std::greater<>> &&
@@ -117,36 +131,45 @@ concept Arbitrary_unsigned_arithmetic_type = Unsigned_arithmetic<T> ||
117131
detail::op_valid_v<T, T, std::divides<>>);
118132

119133
template <typename T>
120-
concept Arbitrary_signed_arithmetic_type = Signed_arithmetic<T> ||
121-
(Arbitrary_unsigned_arithmetic_type<T> &&
134+
concept arbitrary_signed_arithmetic_type = signed_arithmetic<T> ||
135+
(arbitrary_unsigned_arithmetic_type<T> &&
122136
(detail::op_valid_v<T, T, std::negate<>> ||
123137
std::numeric_limits<T>::is_signed));
124138

125139
template <typename T>
126-
concept Arbitrary_arithmetic_type = Arbitrary_unsigned_arithmetic_type<T> ||
127-
Arbitrary_signed_arithmetic_type<T>;
140+
concept arbitrary_arithmetic_type = arbitrary_unsigned_arithmetic_type<T> ||
141+
arbitrary_signed_arithmetic_type<T>;
128142

129143
template <typename T>
130-
concept Aribitrary_unsigned_integer_type = Arbitrary_unsigned_arithmetic_type<T> &&
144+
concept arbitrary_unsigned_integer_type = arbitrary_unsigned_arithmetic_type<T> &&
131145
std::numeric_limits<T>::is_integer;
132146

133147
template <typename T>
134-
concept Aribitrary_signed_integer_type = Arbitrary_signed_arithmetic_type<T> &&
148+
concept arbitrary_signed_integer_type = arbitrary_signed_arithmetic_type<T> &&
135149
std::numeric_limits<T>::is_integer;
136150

137151
template <typename T>
138-
concept Aribitrary_integer_type = Aribitrary_unsigned_integer_type<T> ||
139-
Aribitrary_signed_integer_type<T>;
152+
concept arbitrary_integer_type = arbitrary_unsigned_integer_type<T> ||
153+
arbitrary_signed_integer_type<T>;
140154

141155
template <typename T>
142-
concept Aribitrary_real_type = Arbitrary_arithmetic_type<T> &&
156+
concept arbitrary_real_type = arbitrary_arithmetic_type<T> &&
143157
!std::numeric_limits<T>::is_integer;
144158

159+
template <typename T>
160+
concept arbitrary_complex_type = complex<T> ||
161+
(detail::has_real_v<T> &&
162+
detail::has_imag_v<T>);
163+
164+
template <typename T>
165+
concept arbitrary_real_or_complex_type = arbitrary_real_type<T> ||
166+
arbitrary_complex_type<T>;
167+
145168
template <typename T>
146169
concept policy = boost::math::policies::is_policy<T>::value;
147170

148171
// Workaround for LIBCPP versions that have <concepts> but have not implemented concepts in <iterator>
149-
#if defined(_LIBCPP_VERSION) && !defined(_LIBCPP___ITERATOR_CONCEPTS_H)
172+
#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 13000
150173

151174
template <typename T>
152175
concept forward_iterator = std::is_same_v<typename std::iterator_traits<T>::iterator_category(), std::forward_iterator_tag>;
@@ -180,27 +203,31 @@ concept random_access_container = is_container<T> &&
180203

181204
} // boost::math::concepts
182205

183-
#define BOOST_MATH_INTEGRAL boost::math::concepts::Integral
184-
#define BOOST_MATH_SIGNED_INTEGRAL boost::math::concepts::Signed_integral
185-
#define BOOST_MATH_UNSIGNED_INTEGRAL boost::math::concepts::Unsigned_integral
186-
#define BOOST_MATH_REAL boost::math::concepts::Real
187-
#define BOOST_MATH_ARITHMETIC boost::math::concepts::Arithmetic
188-
#define BOOST_MATH_SIGNED_ARITHMETIC boost::math::concepts::Signed_arithmetic
189-
#define BOOST_MATH_UNSIGNED_ARITHMETIC boost::math::concepts::Unsigned_arithmetic
190-
#define BOOST_MATH_ARBITRARY_UNSIGNED_ARITHMETIC boost::math::concepts::Arbitrary_unsigned_arithmetic_type
191-
#define BOOST_MATH_ARBITRARY_SIGNED_ARITHMETIC boost::math::concepts::Arbitrary_signed_arithmetic_type
192-
#define BOOST_MATH_ARBITRARY_ARITHMETIC boost::math::concepts::Arbitrary_arithmetic_type
193-
#define BOOST_MATH_ARBITRARY_UNSIGNED_INTEGER boost::math::concepts::Aribitrary_unsigned_integer_type
194-
#define BOOST_MATH_ARBITRARY_SIGNED_INTEGER boost::math::concepts::Aribitrary_signed_integer_type
195-
#define BOOST_MATH_ARBITRARY_INTEGER boost::math::concepts::Aribitrary_integer_type
196-
#define BOOST_MATH_ARBITRARY_REAL boost::math::concepts::Aribitrary_real_type
206+
#define BOOST_MATH_INTEGRAL boost::math::concepts::integral
207+
#define BOOST_MATH_SIGNED_INTEGRAL boost::math::concepts::signed_integral
208+
#define BOOST_MATH_UNSIGNED_INTEGRAL boost::math::concepts::unsigned_integral
209+
#define BOOST_MATH_REAL boost::math::concepts::real
210+
#define BOOST_MATH_COMPLEX boost::math::concepts::complex
211+
#define BOOST_MATH_REAL_OR_COMPLEX boost::math::concepts::real_or_complex
212+
#define BOOST_MATH_ARITHMETIC boost::math::concepts::arithmetic
213+
#define BOOST_MATH_SIGNED_ARITHMETIC boost::math::concepts::signed_arithmetic
214+
#define BOOST_MATH_UNSIGNED_ARITHMETIC boost::math::concepts::unsigned_arithmetic
215+
#define BOOST_MATH_ARBITRARY_UNSIGNED_ARITHMETIC boost::math::concepts::arbitrary_unsigned_arithmetic_type
216+
#define BOOST_MATH_ARBITRARY_SIGNED_ARITHMETIC boost::math::concepts::arbitrary_signed_arithmetic_type
217+
#define BOOST_MATH_ARBITRARY_ARITHMETIC boost::math::concepts::arbitrary_arithmetic_type
218+
#define BOOST_MATH_ARBITRARY_UNSIGNED_INTEGER boost::math::concepts::arbitrary_unsigned_integer_type
219+
#define BOOST_MATH_ARBITRARY_SIGNED_INTEGER boost::math::concepts::arbitrary_signed_integer_type
220+
#define BOOST_MATH_ARBITRARY_INTEGER boost::math::concepts::arbitrary_integer_type
221+
#define BOOST_MATH_ARBITRARY_REAL boost::math::concepts::arbitrary_real_type
222+
#define BOOST_MATH_ARBITRARY_COMPLEX boost::math::concepts::arbitrary_complex_type
223+
#define BOOST_MATH_ARBITRARY_REAL_OR_COMPLEX boost::math::concepts::arbitrary_real_or_complex_type
197224
#define BOOST_MATH_POLICY boost::math::concepts::policy
198225
#define BOOST_MATH_CONTAINER boost::math::concepts::is_container
199226
#define BOOST_MATH_RANDOM_ACCESS_CONTAINER boost::math::concepts::random_access_container
200227
#define BOOST_MATH_REQUIRES(X, T) requires X<T>
201228

202229
// Workaround for LIBCPP versions that have <concepts> but have not implemented concepts in <iterator>
203-
#if defined(_LIBCPP_VERSION) && !defined(_LIBCPP___ITERATOR_CONCEPTS_H)
230+
#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 13000
204231

205232
#define BOOST_MATH_FORWARD_ITER boost::math::concepts::forward_iterator
206233
#define BOOST_MATH_BIDIRECTIONAL_ITER boost::math::concepts::bidirectional_iterator
@@ -233,6 +260,14 @@ concept random_access_container = is_container<T> &&
233260
# define BOOST_MATH_REAL typename
234261
#endif
235262

263+
#ifndef BOOST_MATH_COMPLEX
264+
# define BOOST_MATH_COMPLEX typename
265+
#endif
266+
267+
#ifndef BOOST_MATH_REAL_OR_COMPLEX
268+
# define BOOST_MATH_REAL_OR_COMPLEX typename
269+
#endif
270+
236271
#ifndef BOOST_MATH_ARITHMETIC
237272
# define BOOST_MATH_ARITHMETIC typename
238273
#endif
@@ -273,6 +308,14 @@ concept random_access_container = is_container<T> &&
273308
# define BOOST_MATH_ARBITRARY_REAL typename
274309
#endif
275310

311+
#ifndef BOOST_MATH_ARBITRARY_COMPLEX
312+
# define BOOST_MATH_ARBITRARY_COMPLEX typename
313+
#endif
314+
315+
#ifndef BOOST_MATH_ARBITRARY_REAL_OR_COMPLEX
316+
# define BOOST_MATH_ARBITRARY_REAL_OR_COMPLEX typename
317+
#endif
318+
276319
#ifndef BOOST_MATH_POLICY
277320
# define BOOST_MATH_POLICY typename
278321
#endif

0 commit comments

Comments
 (0)