16 #ifndef OPENKALMAN_LANGUAGE_FEATURES_HPP 17 #define OPENKALMAN_LANGUAGE_FEATURES_HPP 20 # define OPENKALMAN_CPP_FEATURE_CONCEPTS true 21 # define OPENKALMAN_CPP_FEATURE_CONCEPTS_2 (__clang_major__ >= 15) // optimal value may be as low as > 10 (ver. 10.0.0) 22 #elif defined(__GNUC__) 23 # define OPENKALMAN_CPP_FEATURE_CONCEPTS (__GNUC__ >= 20) // optimal value may be as low as > 10 (ver. 10.1.0) 24 # define OPENKALMAN_CPP_FEATURE_CONCEPTS_2 (__GNUC__ >= 12) // optimal value may be as low as > 10 (ver. 10.1.0) 26 # define OPENKALMAN_CPP_FEATURE_CONCEPTS true 27 # define OPENKALMAN_CPP_FEATURE_CONCEPTS_2 true 31 #ifdef __cpp_lib_math_constants 38 #ifdef __cpp_lib_concepts 40 template<std::
floating_po
int T>
inline constexpr T e_v = 2.718281828459045235360287471352662498L;
41 template<std::
floating_po
int T>
inline constexpr T log2e_v = 1.442695040888963407359924681001892137L;
42 template<std::
floating_po
int T>
inline constexpr T log10e_v = 0.434294481903251827651128918916605082L;
43 template<std::
floating_po
int T>
inline constexpr T pi_v = 3.141592653589793238462643383279502884L;
44 template<std::
floating_po
int T>
inline constexpr T inv_pi_v = 0.318309886183790671537767526745028724L;
45 template<std::
floating_po
int T>
inline constexpr T inv_sqrtpi_v = 0.564189583547756286948079451560772586L;
46 template<std::
floating_po
int T>
inline constexpr T ln2_v = 0.693147180559945309417232121458176568L;
47 template<std::
floating_po
int T>
inline constexpr T ln10_v = 2.302585092994045684017991454684364208L;
48 template<std::
floating_po
int T>
inline constexpr T sqrt2_v = 1.414213562373095048801688724209698079L;
49 template<std::
floating_po
int T>
inline constexpr T sqrt3_v = 1.732050807568877293527446341505872367L;
50 template<std::
floating_po
int T>
inline constexpr T inv_sqrt3_v = 0.577350269189625764509148780501957456L;
51 template<std::
floating_po
int T>
inline constexpr T egamma_v = 0.577215664901532860606512090082402431L;
52 template<std::
floating_po
int T>
inline constexpr T phi_v = 1.618033988749894848204586834365638118L;
54 #include <type_traits> 55 template<
typename T, std::enable_if_t<std::is_
floating_po
int_v<T>,
int> = 0>
inline constexpr T e_v = 2.718281828459045235360287471352662498L;
56 template<
typename T, std::enable_if_t<std::is_
floating_po
int_v<T>,
int> = 0>
inline constexpr T log2e_v = 1.442695040888963407359924681001892137L;
57 template<
typename T, std::enable_if_t<std::is_
floating_po
int_v<T>,
int> = 0>
inline constexpr T log10e_v = 0.434294481903251827651128918916605082L;
58 template<
typename T, std::enable_if_t<std::is_
floating_po
int_v<T>,
int> = 0>
inline constexpr T pi_v = 3.141592653589793238462643383279502884L;
59 template<
typename T, std::enable_if_t<std::is_
floating_po
int_v<T>,
int> = 0>
inline constexpr T inv_pi_v = 0.318309886183790671537767526745028724L;
60 template<
typename T, std::enable_if_t<std::is_
floating_po
int_v<T>,
int> = 0>
inline constexpr T inv_sqrtpi_v = 0.564189583547756286948079451560772586L;
61 template<
typename T, std::enable_if_t<std::is_
floating_po
int_v<T>,
int> = 0>
inline constexpr T ln2_v = 0.693147180559945309417232121458176568L;
62 template<
typename T, std::enable_if_t<std::is_
floating_po
int_v<T>,
int> = 0>
inline constexpr T ln10_v = 2.302585092994045684017991454684364208L;
63 template<
typename T, std::enable_if_t<std::is_
floating_po
int_v<T>,
int> = 0>
inline constexpr T sqrt2_v = 1.414213562373095048801688724209698079L;
64 template<
typename T, std::enable_if_t<std::is_
floating_po
int_v<T>,
int> = 0>
inline constexpr T sqrt3_v = 1.732050807568877293527446341505872367L;
65 template<
typename T, std::enable_if_t<std::is_
floating_po
int_v<T>,
int> = 0>
inline constexpr T inv_sqrt3_v = 0.577350269189625764509148780501957456L;
66 template<
typename T, std::enable_if_t<std::is_
floating_po
int_v<T>,
int> = 0>
inline constexpr T egamma_v = 0.577215664901532860606512090082402431L;
67 template<
typename T, std::enable_if_t<std::is_
floating_po
int_v<T>,
int> = 0>
inline constexpr T phi_v = 1.618033988749894848204586834365638118L;
70 inline constexpr
double e = e_v<double>;
71 inline constexpr
double log2e = log2e_v<double>;
72 inline constexpr
double log10e = log10e_v<double>;
73 inline constexpr
double pi = pi_v<double>;
74 inline constexpr
double inv_pi = inv_pi_v<double>;
75 inline constexpr
double inv_sqrtpi = inv_sqrtpi_v<double>;
76 inline constexpr
double ln2 = ln2_v<double>;
77 inline constexpr
double ln10 = ln10_v<double>;
78 inline constexpr
double sqrt2 = sqrt2_v<double>;
79 inline constexpr
double sqrt3 = sqrt3_v<double>;
80 inline constexpr
double inv_sqrt3 = inv_sqrt3_v<double>;
81 inline constexpr
double egamma = egamma_v<double>;
82 inline constexpr
double phi = phi_v<double>;
88 constexpr std::size_t
operator ""_uz(
unsigned long long x) {
return x; };
91 #ifndef __cpp_lib_integer_comparison_functions 94 template<
typename T,
typename U>
95 constexpr
bool cmp_equal(T t, U u) noexcept
97 if constexpr (std::is_signed_v<T> == std::is_signed_v<U>)
99 else if constexpr (std::is_signed_v<T>)
100 return t >= 0 && std::make_unsigned_t<T>(t) == u;
102 return u >= 0 && std::make_unsigned_t<U>(u) == t;
105 template<
typename T,
typename U>
106 constexpr
bool cmp_not_equal(T t, U u) noexcept
108 return !cmp_equal(t, u);
111 template<
typename T,
typename U>
112 constexpr
bool cmp_less(T t, U u) noexcept
114 if constexpr (std::is_signed_v<T> == std::is_signed_v<U>)
return t < u;
115 else if constexpr (std::is_signed_v<T>)
return t < 0 or std::make_unsigned_t<T>(t) < u;
116 else return u >= 0 and t < std::make_unsigned_t<U>(u);
119 template<
typename T,
typename U>
120 constexpr
bool cmp_greater(T t, U u) noexcept
122 return cmp_less(u, t);
125 template<
typename T,
typename U>
126 constexpr
bool cmp_less_equal(T t, U u) noexcept
128 return not cmp_less(u, t);
131 template<
typename T,
typename U>
132 constexpr
bool cmp_greater_equal(T t, U u) noexcept
134 return not cmp_less(t, u);
140 #ifndef __cpp_impl_three_way_comparison 145 enum struct Ord : signed char { equivalent = 0, less = -1, greater = 1, unordered = 2 };
151 struct unspecified { constexpr unspecified(unspecified*) noexcept {} };
153 detail::Ord my_value;
164 template<
typename I, std::enable_if_t<std::is_constructible_v<std::ptrdiff_t, I>,
int> = 0>
165 explicit constexpr
partial_ordering(I i) : my_value(static_cast<detail::Ord>(i)) {}
167 [[nodiscard]]
friend constexpr
bool 168 operator==(partial_ordering v, unspecified) noexcept {
return v.my_value == detail::Ord::equivalent; }
170 [[nodiscard]]
friend constexpr
bool 171 operator==(unspecified, partial_ordering v) noexcept {
return v.my_value == detail::Ord::equivalent; }
173 [[nodiscard]]
friend constexpr
bool 174 operator==(partial_ordering v, partial_ordering w) noexcept {
return v.my_value == w.my_value; };
176 [[nodiscard]]
friend constexpr
bool 177 operator<(partial_ordering v, unspecified) noexcept {
return v.my_value == detail::Ord::less; }
179 [[nodiscard]]
friend constexpr
bool 180 operator<(unspecified, partial_ordering v) noexcept {
return v.my_value == detail::Ord::greater; }
182 [[nodiscard]]
friend constexpr
bool 183 operator>(partial_ordering v, unspecified) noexcept {
return v.my_value == detail::Ord::greater; }
185 [[nodiscard]]
friend constexpr
bool 186 operator>(unspecified, partial_ordering v) noexcept {
return v.my_value == detail::Ord::less; }
188 [[nodiscard]]
friend constexpr
bool 189 operator<=(partial_ordering v, unspecified) noexcept {
return v.my_value <= detail::Ord::equivalent; }
191 [[nodiscard]]
friend constexpr
bool 192 operator<=(unspecified, partial_ordering v) noexcept {
return v.my_value == detail::Ord::greater or v.my_value == detail::Ord::equivalent; }
194 [[nodiscard]]
friend constexpr
bool 195 operator>=(partial_ordering v, unspecified) noexcept {
return v.my_value == detail::Ord::greater or v.my_value == detail::Ord::equivalent; }
197 [[nodiscard]]
friend constexpr
bool 198 operator>=(unspecified, partial_ordering v) noexcept {
return v.my_value <= detail::Ord::equivalent; }
203 inline constexpr
partial_ordering partial_ordering::less(detail::Ord::less);
205 inline constexpr
partial_ordering partial_ordering::equivalent(detail::Ord::equivalent);
207 inline constexpr
partial_ordering partial_ordering::greater(detail::Ord::greater);
209 inline constexpr
partial_ordering partial_ordering::unordered(detail::Ord::unordered);
214 template<
typename T,
typename U>
216 operator() [[nodiscard]] (T&& t, U&& u)
const 218 if (t == u)
return partial_ordering::equivalent;
219 if (t < u)
return partial_ordering::less;
220 if (t > u)
return partial_ordering::greater;
221 return partial_ordering::unordered;
224 using is_transparent = void;
231 #if not defined(__cpp_lib_remove_cvref) or not defined(__cpp_lib_ranges) 235 struct remove_cvref {
using type = std::remove_cv_t<std::remove_reference_t<T>>; };
238 using remove_cvref_t =
typename remove_cvref<T>::type;
250 constexpr std::decay_t<T> operator()(T&& t)
const noexcept {
return std::forward<T>(t); }
258 #ifndef __cpp_lib_bounded_array_traits 264 template<
typename T, std::
size_t N>
277 template<
typename T,
typename =
void>
300 inline constexpr
bool is_signed_integer_like = is_integer_like<T> and std::is_signed_v<T>;
303 inline constexpr
bool is_unsigned_integer_like = is_integer_like<T> and std::is_unsigned_v<T>;
308 #if __cplusplus < 202002L 317 template<
typename T> constexpr T& reference_wrapper_FUN(T& t) noexcept {
return t; }
318 template<
typename T>
void reference_wrapper_FUN(T&&) =
delete;
325 #ifdef __cpp_lib_remove_cvref 326 using std::remove_cvref_t;
333 template<
typename U,
typename = std::
void_t<decltype(detail::reference_wrapper_FUN<T>(std::declval<U>()))>,
334 std::enable_if_t<not std::is_same_v<reference_wrapper, remove_cvref_t<U>>,
int> = 0>
335 constexpr
reference_wrapper(U&& u) noexcept(noexcept(detail::reference_wrapper_FUN<T>(std::forward<U>(u))))
336 : ptr(std::addressof(detail::reference_wrapper_FUN<T>(std::forward<U>(u)))) {}
345 constexpr
operator T& ()
const noexcept {
return *ptr; }
346 constexpr T&
get()
const noexcept {
return *ptr; }
349 template<
typename... ArgTypes>
350 constexpr std::invoke_result_t<T&, ArgTypes...>
351 operator() (ArgTypes&&... args )
const noexcept(std::is_nothrow_invocable_v<T&, ArgTypes...>)
353 return get()(std::forward<ArgTypes>(args)...);
368 constexpr std::reference_wrapper<T>
369 ref(T& t) noexcept {
return {t}; };
372 constexpr std::reference_wrapper<T>
373 ref(std::reference_wrapper<T> t) noexcept {
return std::move(t); };
376 void ref(
const T&&) =
delete;
379 constexpr std::reference_wrapper<const T>
380 cref(
const T& t) noexcept {
return {t}; };
383 constexpr std::reference_wrapper<const T>
384 cref(std::reference_wrapper<T> t) noexcept {
return std::move(t); };
387 void cref(
const T&&) =
delete;
392 #ifndef __cpp_lib_concepts 402 [[nodiscard]] constexpr T&& operator()(T&& t)
const noexcept {
return std::forward<T>(t); }
404 struct is_transparent;
412 using type_identity_t =
typename type_identity<T>::type;
415 template<
typename T,
typename...Args>
416 inline constexpr
bool 417 destructible = std::is_nothrow_destructible_v<T>;
420 template<
typename T,
typename...Args>
421 inline constexpr
bool 422 constructible_from = destructible<T> and std::is_constructible_v<T, Args...>;
427 template<
typename From,
typename To,
typename =
void>
430 template<
typename From,
typename To>
434 template<
typename From,
typename To>
435 inline constexpr
bool 440 inline constexpr
bool 441 move_constructible = constructible_from<T, T> and convertible_to<T, T>;
445 inline constexpr
bool copy_constructible =
446 move_constructible<T> and
447 constructible_from<T, T&> and convertible_to<T&, T> and
448 constructible_from<T, const T&> && convertible_to<const T&, T> and
449 constructible_from<T, const T> && convertible_to<const T, T>;
453 inline constexpr
bool 455 std::is_object_v<T> and
456 std::is_move_constructible_v<T> and
457 std::is_assignable_v<T&, T>
462 inline constexpr
bool 464 std::is_copy_constructible_v<T> and
466 std::is_assignable_v<T&, T&> and
467 std::is_assignable_v<T&, const T&> and
468 std::is_assignable_v<T&, const T>;
472 inline constexpr
bool 473 semiregular = copyable<T> and std::is_default_constructible_v<T>;
483 #if __cplusplus < 202002L 488 template<
typename>
static constexpr
bool is_reference_wrapper_v =
false;
489 template<
typename U>
static constexpr
bool is_reference_wrapper_v<std::reference_wrapper<U>> =
true;
491 template<
typename T>
using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
493 template<
typename C,
typename P,
typename O,
typename...Args>
494 static constexpr decltype(
auto)
495 invoke_memptr(P C::* member, O&&
object, Args&&... args)
497 if constexpr (std::is_function_v<P>)
499 if constexpr (std::is_same_v<C, remove_cvref_t<O>> or std::is_base_of_v<C, remove_cvref_t<O>>)
500 return (std::forward<O>(
object) .* member)(std::forward<Args>(args)...);
501 else if constexpr (is_reference_wrapper_v<remove_cvref_t<O>>)
502 return (
object.
get() .* member)(std::forward<Args>(args)...);
504 return ((*std::forward<O>(
object)) .* member)(std::forward<Args>(args)...);
508 static_assert(std::is_object_v<P> &&
sizeof...(args) == 0);
509 if constexpr (std::is_same_v<C, remove_cvref_t<O>> or std::is_base_of_v<C, remove_cvref_t<O>>)
510 return std::forward<O>(object) .* member;
511 else if constexpr (is_reference_wrapper_v<remove_cvref_t<O>>)
512 return object.get() .* member;
514 return (*std::forward<O>(
object)) .* member;
524 template<
typename F,
typename...Args>
525 static constexpr decltype(
auto)
526 invoke(F&& f, Args&&... args) noexcept(std::is_nothrow_invocable_v<F, Args...>)
528 if constexpr (std::is_member_pointer_v<remove_cvref_t<F>>)
529 return invoke_memptr(f, std::forward<Args>(args)...);
531 return std::forward<F>(f)(std::forward<Args>(args)...);
537 #if __cplusplus < 202302L 544 #ifdef __cpp_concepts 545 template<
typename R,
typename F,
typename...Args> requires std::is_invocable_r_v<R, F, Args...>
547 template<
typename R,
typename F,
typename...Args, std::enable_if_t<std::is_invocable_r_v<R, F, Args...>,
int> = 0>
549 constexpr R invoke_r(F&& f, Args&&... args) noexcept(std::is_nothrow_invocable_r_v<R, F, Args...>)
551 #if __cplusplus < 202002L 556 if constexpr (std::is_void_v<R>)
557 s::invoke(std::forward<F>(f), std::forward<Args>(args)...);
559 return s::invoke(std::forward<F>(f), std::forward<Args>(args)...);
567 namespace std_get_detail
572 #ifndef __cpp_concepts 573 template<std::
size_t i,
typename T,
typename =
void>
576 template<std::
size_t i,
typename T>
580 template<std::
size_t i,
typename T,
typename =
void>
583 template<std::
size_t i,
typename T>
588 template<std::
size_t i>
591 #ifdef __cpp_concepts 592 template<
typename T> requires
593 requires { std::declval<T&&>().
template get<i>(); } or
594 requires { get<i>(std::declval<T&&>()); }
598 constexpr decltype(
auto)
599 operator() [[nodiscard]] (T&& t)
const 601 #ifdef __cpp_concepts 602 if constexpr (requires { std::forward<T>(t).
template get<i>(); })
606 return std::forward<T>(t).
template get<i>();
608 return get<i>(std::forward<T>(t));
618 template<std::
size_t i>
625 #endif //OPENKALMAN_LANGUAGE_FEATURES_HPP Definition: language-features.hpp:399
Definition: language-features.hpp:262
A generalization of std::greater in which the arguments may be of different types.
Definition: greater.hpp:29
decltype(auto) constexpr get(Arg &&arg, I i)
A generalization of std::get.
Definition: get.hpp:62
Definition: language-features.hpp:36
A generalization of std::less in which the arguments may be of different types.
Definition: less.hpp:29
Definition: tuple_reverse.hpp:103
constexpr bool value
T is numerical value or is reducible to a numerical value.
Definition: value.hpp:31
Definition: language-features.hpp:212
Definition: language-features.hpp:149
The root namespace for OpenKalman.
Definition: basics.hpp:34
Definition: language-features.hpp:589
Definition: language-features.hpp:278
Definition: language-features.hpp:574
Definition: language-features.hpp:247
Definition: language-features.hpp:581
Definition: language-features.hpp:409
Definition: language-features.hpp:428
Definition: basics.hpp:48
Definition: language-features.hpp:323