forked from mpusz/mp-units
refactor: got rid of gcc-9 backlog
BREAKING CHANGE: gcc-9.3 no longer supported
This commit is contained in:
@@ -76,16 +76,8 @@ using common_quantity_point = decltype(
|
||||
|
||||
} // namespace units
|
||||
|
||||
#if COMP_MSVC || COMP_GCC >= 10
|
||||
|
||||
namespace std {
|
||||
|
||||
#else
|
||||
|
||||
namespace concepts {
|
||||
|
||||
#endif
|
||||
|
||||
template<units::Quantity Q1, units::Quantity Q2>
|
||||
requires units::equivalent_dim<typename Q1::dimension, typename Q2::dimension>
|
||||
struct common_type<Q1, Q2> {
|
||||
|
||||
-73
@@ -26,10 +26,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <ostream>
|
||||
|
||||
#if COMP_MSVC || COMP_GCC >= 10
|
||||
#include <compare>
|
||||
#endif
|
||||
|
||||
namespace units {
|
||||
|
||||
@@ -76,8 +73,6 @@ struct basic_fixed_string {
|
||||
return basic_fixed_string<CharT, N + N2>(txt);
|
||||
}
|
||||
|
||||
#if COMP_MSVC || COMP_GCC >= 10
|
||||
|
||||
[[nodiscard]] constexpr bool operator==(const basic_fixed_string& other) const
|
||||
{
|
||||
return std::ranges::equal(*this, other);
|
||||
@@ -92,74 +87,6 @@ struct basic_fixed_string {
|
||||
return std::lexicographical_compare_three_way(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
[[nodiscard]] constexpr friend bool operator==(const basic_fixed_string& lhs, const basic_fixed_string& rhs) noexcept
|
||||
{
|
||||
for (size_t i = 0; i != lhs.size(); ++i)
|
||||
if (lhs.data_[i] != rhs.data_[i]) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr friend bool operator!=(const basic_fixed_string& lhs, const basic_fixed_string& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template<typename CharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator==(const basic_fixed_string&,
|
||||
const basic_fixed_string<CharT2, N2>&) noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename CharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator!=(const basic_fixed_string&,
|
||||
const basic_fixed_string<CharT2, N2>&) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename CharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator<(const basic_fixed_string& lhs,
|
||||
const basic_fixed_string<CharT2, N2>& rhs) noexcept
|
||||
{
|
||||
using std::begin, std::end;
|
||||
auto first1 = begin(lhs.data_);
|
||||
auto first2 = begin(rhs.data_);
|
||||
const auto last1 = std::prev(end(lhs.data_)); // do not waste time for '\0'
|
||||
const auto last2 = std::prev(end(rhs.data_));
|
||||
|
||||
for (; (first1 != last1) && (first2 != last2); ++first1, (void)++first2) {
|
||||
if (*first1 < *first2) return true;
|
||||
if (*first2 < *first1) return false;
|
||||
}
|
||||
return first1 == last1 && first2 != last2;
|
||||
}
|
||||
|
||||
template<typename CharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator>(const basic_fixed_string& lhs,
|
||||
const basic_fixed_string<CharT2, N2>& rhs) noexcept
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
template<typename CharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator<=(const basic_fixed_string& lhs,
|
||||
const basic_fixed_string<CharT2, N2>& rhs) noexcept
|
||||
{
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
|
||||
template<typename CharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator>=(const basic_fixed_string& lhs,
|
||||
const basic_fixed_string<CharT2, N2>& rhs) noexcept
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os,
|
||||
const basic_fixed_string& txt)
|
||||
|
||||
+7
-70
@@ -22,7 +22,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <concepts>
|
||||
|
||||
#if __clang__
|
||||
#define COMP_CLANG __clang_major__
|
||||
@@ -33,29 +33,6 @@
|
||||
#define COMP_MSVC _MSC_VER
|
||||
#endif
|
||||
|
||||
#if COMP_MSVC || COMP_GCC >= 10
|
||||
|
||||
#include <concepts>
|
||||
|
||||
#else
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
#include <range/v3/range.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
#if COMP_MSVC || COMP_GCC >= 10 || COMP_CLANG >= 11
|
||||
|
||||
#define AUTO auto
|
||||
#define SAME_AS(T) std::same_as<T>
|
||||
|
||||
#else
|
||||
|
||||
#define AUTO
|
||||
#define SAME_AS(T) T
|
||||
|
||||
#endif
|
||||
|
||||
#if COMP_MSVC
|
||||
|
||||
#define TYPENAME typename
|
||||
@@ -66,53 +43,13 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if COMP_GCC
|
||||
|
||||
namespace std {
|
||||
|
||||
#if COMP_GCC
|
||||
#if COMP_GCC >= 10
|
||||
|
||||
template<class T>
|
||||
concept default_constructible = constructible_from<T>;
|
||||
|
||||
#else
|
||||
|
||||
// concepts
|
||||
using concepts::common_reference_with;
|
||||
using concepts::common_with;
|
||||
using concepts::constructible_from;
|
||||
using concepts::convertible_to;
|
||||
using concepts::default_constructible;
|
||||
using concepts::derived_from;
|
||||
using concepts::equality_comparable;
|
||||
using concepts::equality_comparable_with;
|
||||
// using concepts::floating_point;
|
||||
using concepts::integral;
|
||||
using concepts::regular;
|
||||
using concepts::same_as;
|
||||
using concepts::totally_ordered;
|
||||
using concepts::totally_ordered_with;
|
||||
|
||||
namespace ranges {
|
||||
|
||||
using ::ranges::forward_range;
|
||||
using ::ranges::range_value_t;
|
||||
|
||||
}
|
||||
|
||||
// missing in Range-v3
|
||||
template<class T>
|
||||
concept floating_point = std::is_floating_point_v<T>;
|
||||
|
||||
template<class F, class... Args>
|
||||
concept invocable =
|
||||
requires(F&& f, Args&&... args) {
|
||||
std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
|
||||
};
|
||||
|
||||
template<class F, class... Args>
|
||||
concept regular_invocable = invocable<F, Args...>;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
template<class T>
|
||||
concept default_constructible = constructible_from<T>;
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <units/bits/external/hacks.h>
|
||||
#include <units/ratio.h>
|
||||
#include <units/bits/external/type_traits.h>
|
||||
#include <functional>
|
||||
|
||||
namespace units {
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace units {
|
||||
*/
|
||||
template<std::intmax_t N, Quantity Q>
|
||||
requires(N != 0)
|
||||
inline Quantity AUTO pow(const Q& q) noexcept
|
||||
inline Quantity auto pow(const Q& q) noexcept
|
||||
requires requires { std::pow(q.count(), N); }
|
||||
{
|
||||
using dim = dimension_pow<typename Q::dimension, N>;
|
||||
@@ -70,7 +70,7 @@ inline TYPENAME Q::rep pow(const Q&) noexcept
|
||||
* @return Quantity The result of computation
|
||||
*/
|
||||
template<Quantity Q>
|
||||
inline Quantity AUTO sqrt(const Q& q) noexcept
|
||||
inline Quantity auto sqrt(const Q& q) noexcept
|
||||
requires requires { std::sqrt(q.count()); }
|
||||
{
|
||||
using dim = dimension_sqrt<typename Q::dimension>;
|
||||
@@ -99,7 +99,7 @@ inline quantity<D, U, Rep> exp(const quantity<D, U, Rep>& q)
|
||||
* @return Quantity The absolute value of a provided quantity
|
||||
*/
|
||||
template<Quantity Q>
|
||||
inline Quantity AUTO abs(const Q& q) noexcept
|
||||
inline Quantity auto abs(const Q& q) noexcept
|
||||
requires requires { std::abs(q.count()); }
|
||||
{
|
||||
return Q(std::abs(q.count()));
|
||||
@@ -115,7 +115,7 @@ inline Quantity AUTO abs(const Q& q) noexcept
|
||||
*/
|
||||
template<Quantity Q>
|
||||
requires requires { std::numeric_limits<typename Q::rep>::epsilon(); }
|
||||
constexpr Quantity AUTO epsilon() noexcept
|
||||
constexpr Quantity auto epsilon() noexcept
|
||||
{
|
||||
return Q(std::numeric_limits<typename Q::rep>::epsilon());
|
||||
}
|
||||
|
||||
+26
-107
@@ -29,11 +29,7 @@
|
||||
#include <units/bits/to_string.h>
|
||||
#include <units/dimensionless.h>
|
||||
#include <units/quantity_cast.h>
|
||||
|
||||
#if COMP_MSVC || COMP_GCC >= 10
|
||||
#include <compare>
|
||||
#endif
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace units {
|
||||
@@ -90,78 +86,60 @@ public:
|
||||
|
||||
[[nodiscard]] constexpr rep count() const noexcept { return value_; }
|
||||
|
||||
template<typename T = Rep>
|
||||
[[nodiscard]] static constexpr quantity zero() noexcept
|
||||
requires requires { quantity_values<T>::zero(); }
|
||||
// requires requires { quantity_values<Rep>::zero(); } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires { quantity_values<Rep>::zero(); }
|
||||
{
|
||||
return quantity(quantity_values<Rep>::zero());
|
||||
}
|
||||
|
||||
template<typename T = Rep>
|
||||
[[nodiscard]] static constexpr quantity one() noexcept
|
||||
requires requires { quantity_values<T>::one(); }
|
||||
// requires requires { quantity_values<Rep>::one(); } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires { quantity_values<Rep>::one(); }
|
||||
{
|
||||
return quantity(quantity_values<Rep>::one());
|
||||
}
|
||||
|
||||
template<typename T = Rep>
|
||||
[[nodiscard]] static constexpr quantity min() noexcept
|
||||
requires requires { quantity_values<T>::min(); }
|
||||
// requires requires { quantity_values<Rep>::min(); } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires { quantity_values<Rep>::min(); }
|
||||
{
|
||||
return quantity(quantity_values<Rep>::min());
|
||||
}
|
||||
|
||||
template<typename T = Rep>
|
||||
[[nodiscard]] static constexpr quantity max() noexcept
|
||||
requires requires { quantity_values<T>::max(); }
|
||||
// requires requires { quantity_values<Rep>::max(); } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires { quantity_values<Rep>::max(); }
|
||||
{
|
||||
return quantity(quantity_values<Rep>::max());
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr quantity operator+() const { return *this; }
|
||||
|
||||
template<typename T = Rep>
|
||||
[[nodiscard]] constexpr quantity operator-() const
|
||||
requires std::regular_invocable<std::negate<>, T>
|
||||
// requires std::regular_invocable<std::negate<>, rep> // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires std::regular_invocable<std::negate<>, rep>
|
||||
{
|
||||
return quantity(-count());
|
||||
}
|
||||
|
||||
template<typename T = Rep>
|
||||
constexpr quantity& operator++()
|
||||
requires requires(T v) { { ++v } -> SAME_AS(T&); }
|
||||
// requires requires(rep v) { { ++v } -> std::same_as<rep&>; } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires(rep v) { { ++v } -> std::same_as<rep&>; }
|
||||
{
|
||||
++value_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T = Rep>
|
||||
[[nodiscard]] constexpr quantity operator++(int)
|
||||
requires requires(T v) { { v++ } -> SAME_AS(T); }
|
||||
// requires requires(rep v) { { v++ } -> std::same_as<rep>; } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires(rep v) { { v++ } -> std::same_as<rep>; }
|
||||
{
|
||||
return quantity(value_++);
|
||||
}
|
||||
|
||||
template<typename T = Rep>
|
||||
constexpr quantity& operator--()
|
||||
requires requires(T v) { { --v } -> SAME_AS(T&); }
|
||||
// requires requires(rep v) { { --v } -> std::same_as<rep&>; } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires(rep v) { { --v } -> std::same_as<rep&>; }
|
||||
{
|
||||
--value_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T = Rep>
|
||||
[[nodiscard]] constexpr quantity operator--(int)
|
||||
requires requires(T v) { { v-- } -> SAME_AS(T); }
|
||||
// requires requires(rep v) { { v-- } -> std::same_as<rep>; } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires(rep v) { { v-- } -> std::same_as<rep>; }
|
||||
{
|
||||
return quantity(value_--);
|
||||
}
|
||||
@@ -198,22 +176,19 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<Scalar Value, typename T = Rep>
|
||||
constexpr quantity& operator%=(const Value& rhs)
|
||||
template<Scalar Value>
|
||||
requires (!treat_as_floating_point<rep>) &&
|
||||
(!treat_as_floating_point<Value>) &&
|
||||
requires(T v1, Value v2) { { v1 %= v2 } -> SAME_AS(T&); }
|
||||
// requires(rep v1, Value v2) { { v1 %= v2 } -> SAME_AS(rep&); } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
(!treat_as_floating_point<Value>)
|
||||
constexpr quantity& operator%=(const Value& rhs)
|
||||
requires requires(rep v1, Value v2) { { v1 %= v2 } -> std::same_as<rep&>; }
|
||||
{
|
||||
value_ %= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T = Rep>
|
||||
constexpr quantity& operator%=(const quantity& q)
|
||||
requires (!treat_as_floating_point<rep>) &&
|
||||
requires(T v1, T v2) { { v1 %= v2 } -> SAME_AS(T&); }
|
||||
// requires(rep v1, rep v2) { { v1 %= v2 } -> std::same_as<rep&>; } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires(rep v1, rep v2) { { v1 %= v2 } -> std::same_as<rep&>; }
|
||||
{
|
||||
value_ %= q.count();
|
||||
return *this;
|
||||
@@ -229,8 +204,8 @@ public:
|
||||
}
|
||||
|
||||
template<typename U2, typename Rep2>
|
||||
[[nodiscard]] friend constexpr Quantity AUTO operator+(const quantity& lhs, const quantity<D, U2, Rep2>& rhs)
|
||||
requires std::regular_invocable<std::plus<>, Rep, Rep2>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator+(const quantity& lhs, const quantity<D, U2, Rep2>& rhs)
|
||||
{
|
||||
using common_rep = decltype(lhs.count() + rhs.count());
|
||||
using ret = common_quantity<quantity, quantity<D, U2, Rep2>, common_rep>;
|
||||
@@ -244,8 +219,8 @@ public:
|
||||
}
|
||||
|
||||
template<typename U2, typename Rep2>
|
||||
[[nodiscard]] friend constexpr Quantity AUTO operator-(const quantity& lhs, const quantity<D, U2, Rep2>& rhs)
|
||||
requires std::regular_invocable<std::minus<>, Rep, Rep2>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator-(const quantity& lhs, const quantity<D, U2, Rep2>& rhs)
|
||||
{
|
||||
using common_rep = decltype(lhs.count() - rhs.count());
|
||||
using ret = common_quantity<quantity, quantity<D, U2, Rep2>, common_rep>;
|
||||
@@ -253,8 +228,8 @@ public:
|
||||
}
|
||||
|
||||
template<Scalar Value>
|
||||
[[nodiscard]] friend constexpr Quantity AUTO operator*(const quantity& q, const Value& v)
|
||||
requires std::regular_invocable<std::multiplies<>, Rep, Value>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator*(const quantity& q, const Value& v)
|
||||
{
|
||||
using common_rep = decltype(q.count() * v);
|
||||
using ret = quantity<D, U, common_rep>;
|
||||
@@ -262,15 +237,15 @@ public:
|
||||
}
|
||||
|
||||
template<Scalar Value>
|
||||
[[nodiscard]] friend constexpr Quantity AUTO operator*(const Value& v, const quantity& q)
|
||||
requires std::regular_invocable<std::multiplies<>, Value, Rep>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator*(const Value& v, const quantity& q)
|
||||
{
|
||||
return q * v;
|
||||
}
|
||||
|
||||
template<typename D2, typename U2, typename Rep2>
|
||||
[[nodiscard]] friend constexpr Quantity AUTO operator*(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
|
||||
requires std::regular_invocable<std::multiplies<>, Rep, Rep2>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator*(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
|
||||
{
|
||||
using dim = dimension_multiply<D, D2>;
|
||||
using ret_unit = downcast_unit<dim, (U::ratio / dimension_unit<D>::ratio) * (U2::ratio / dimension_unit<D2>::ratio) * dimension_unit<dim>::ratio>;
|
||||
@@ -280,8 +255,8 @@ public:
|
||||
}
|
||||
|
||||
template<Scalar Value>
|
||||
[[nodiscard]] friend constexpr Quantity AUTO operator/(const Value& v, const quantity& q)
|
||||
requires std::regular_invocable<std::divides<>, Value, Rep>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator/(const Value& v, const quantity& q)
|
||||
{
|
||||
Expects(q.count() != 0);
|
||||
|
||||
@@ -293,8 +268,8 @@ public:
|
||||
}
|
||||
|
||||
template<Scalar Value>
|
||||
[[nodiscard]] friend constexpr Quantity AUTO operator/(const quantity& q, const Value& v)
|
||||
requires std::regular_invocable<std::divides<>, Rep, Value>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator/(const quantity& q, const Value& v)
|
||||
{
|
||||
Expects(v != Value{0});
|
||||
|
||||
@@ -304,8 +279,8 @@ public:
|
||||
}
|
||||
|
||||
template<typename D2, typename U2, typename Rep2>
|
||||
[[nodiscard]] friend constexpr Quantity AUTO operator/(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
|
||||
requires std::regular_invocable<std::divides<>, Rep, Rep2>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator/(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
|
||||
{
|
||||
Expects(rhs.count() != 0);
|
||||
|
||||
@@ -317,10 +292,10 @@ public:
|
||||
}
|
||||
|
||||
template<Scalar Value>
|
||||
[[nodiscard]] friend constexpr Quantity AUTO operator%(const quantity& q, const Value& v)
|
||||
requires (!treat_as_floating_point<Rep>) &&
|
||||
(!treat_as_floating_point<Value>) &&
|
||||
std::regular_invocable<std::modulus<>, Rep, Value>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator%(const quantity& q, const Value& v)
|
||||
{
|
||||
using common_rep = decltype(q.count() % v);
|
||||
using ret = quantity<D, U, common_rep>;
|
||||
@@ -328,90 +303,34 @@ public:
|
||||
}
|
||||
|
||||
template<typename U2, typename Rep2>
|
||||
[[nodiscard]] friend constexpr Quantity AUTO operator%(const quantity& lhs, const quantity<D, U2, Rep2>& rhs)
|
||||
requires (!treat_as_floating_point<Rep>) &&
|
||||
(!treat_as_floating_point<Rep2>) &&
|
||||
std::regular_invocable<std::modulus<>, Rep, Rep2>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator%(const quantity& lhs, const quantity<D, U2, Rep2>& rhs)
|
||||
{
|
||||
using common_rep = decltype(lhs.count() % rhs.count());
|
||||
using ret = common_quantity<quantity, quantity<D, U2, Rep2>, common_rep>;
|
||||
return ret(ret(lhs).count() % ret(rhs).count());
|
||||
}
|
||||
|
||||
#if COMP_MSVC || COMP_GCC >= 10
|
||||
|
||||
template<typename D2, typename U2, typename Rep2>
|
||||
[[nodiscard]] friend constexpr auto operator<=>(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
|
||||
requires equivalent_dim<D, D2> &&
|
||||
std::three_way_comparable_with<Rep, Rep2>
|
||||
[[nodiscard]] friend constexpr auto operator<=>(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
|
||||
{
|
||||
using cq = common_quantity<quantity, quantity<D2, U2, Rep2>>;
|
||||
return cq(lhs).count() <=> cq(rhs).count();
|
||||
}
|
||||
|
||||
template<typename D2, typename U2, typename Rep2>
|
||||
[[nodiscard]] friend constexpr bool operator==(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
|
||||
requires equivalent_dim<D, D2> &&
|
||||
std::equality_comparable_with<Rep, Rep2>
|
||||
[[nodiscard]] friend constexpr bool operator==(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
|
||||
{
|
||||
using cq = common_quantity<quantity, quantity<D2, U2, Rep2>>;
|
||||
return cq(lhs).count() == cq(rhs).count();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<typename D2, typename U2, typename Rep2>
|
||||
[[nodiscard]] friend constexpr bool operator==(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
|
||||
requires equivalent_dim<D, D2> &&
|
||||
std::equality_comparable_with<Rep, Rep2>
|
||||
{
|
||||
using cq = common_quantity<quantity, quantity<D2, U2, Rep2>>;
|
||||
return cq(lhs).count() == cq(rhs).count();
|
||||
}
|
||||
|
||||
template<typename D2, typename U2, typename Rep2>
|
||||
[[nodiscard]] friend constexpr bool operator!=(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
|
||||
requires equivalent_dim<D, D2> &&
|
||||
std::equality_comparable_with<Rep, Rep2>
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template<typename D2, typename U2, typename Rep2>
|
||||
[[nodiscard]] friend constexpr bool operator<(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
|
||||
requires equivalent_dim<D, D2> &&
|
||||
std::totally_ordered_with<Rep, Rep2>
|
||||
{
|
||||
using cq = common_quantity<quantity, quantity<D2, U2, Rep2>>;
|
||||
return cq(lhs).count() < cq(rhs).count();
|
||||
}
|
||||
|
||||
template<typename D2, typename U2, typename Rep2>
|
||||
[[nodiscard]] friend constexpr bool operator<=(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
|
||||
requires equivalent_dim<D, D2> &&
|
||||
std::totally_ordered_with<Rep, Rep2>
|
||||
{
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
|
||||
template<typename D2, typename U2, typename Rep2>
|
||||
[[nodiscard]] friend constexpr bool operator>(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
|
||||
requires equivalent_dim<D, D2> &&
|
||||
std::totally_ordered_with<Rep, Rep2>
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
template<typename D2, typename U2, typename Rep2>
|
||||
[[nodiscard]] friend constexpr bool operator>=(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
|
||||
requires equivalent_dim<D, D2> &&
|
||||
std::totally_ordered_with<Rep, Rep2>
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class CharT, class Traits>
|
||||
friend std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const quantity& q)
|
||||
{
|
||||
|
||||
@@ -313,8 +313,8 @@ constexpr ratio cast_ratio(const Q1& from, const Q2& to)
|
||||
* @tparam To a target quantity type to cast to
|
||||
*/
|
||||
template<Quantity To, typename D, typename U, typename Rep>
|
||||
[[nodiscard]] constexpr auto quantity_cast(const quantity<D, U, Rep>& q)
|
||||
requires QuantityOf<To, D>
|
||||
[[nodiscard]] constexpr auto quantity_cast(const quantity<D, U, Rep>& q)
|
||||
{
|
||||
using c_ratio = std::integral_constant<ratio, detail::cast_ratio(quantity<D, U, Rep>(), To())>;
|
||||
using c_rep = std::common_type_t<typename To::rep, Rep>;
|
||||
@@ -337,8 +337,8 @@ template<Quantity To, typename D, typename U, typename Rep>
|
||||
* @tparam ToD a dimension type to use for a target quantity
|
||||
*/
|
||||
template<Dimension ToD, typename D, typename U, typename Rep>
|
||||
[[nodiscard]] constexpr auto quantity_cast(const quantity<D, U, Rep>& q)
|
||||
requires equivalent_dim<ToD, D>
|
||||
[[nodiscard]] constexpr auto quantity_cast(const quantity<D, U, Rep>& q)
|
||||
{
|
||||
return quantity_cast<quantity<ToD, dimension_unit<ToD>, Rep>>(q);
|
||||
}
|
||||
@@ -356,8 +356,8 @@ template<Dimension ToD, typename D, typename U, typename Rep>
|
||||
* @tparam ToU a unit type to use for a target quantity
|
||||
*/
|
||||
template<Unit ToU, typename D, typename U, typename Rep>
|
||||
[[nodiscard]] constexpr auto quantity_cast(const quantity<D, U, Rep>& q)
|
||||
requires UnitOf<ToU, D>
|
||||
[[nodiscard]] constexpr auto quantity_cast(const quantity<D, U, Rep>& q)
|
||||
{
|
||||
return quantity_cast<quantity<D, ToU, Rep>>(q);
|
||||
}
|
||||
@@ -397,9 +397,9 @@ template<Scalar ToRep, typename D, typename U, typename Rep>
|
||||
* @tparam CastSpec a target quantity point type to cast to or anything that works for quantity_cast
|
||||
*/
|
||||
template<typename CastSpec, typename D, typename U, typename Rep>
|
||||
[[nodiscard]] constexpr auto quantity_point_cast(const quantity_point<D, U, Rep>& qp)
|
||||
requires is_specialization_of<CastSpec, quantity_point> ||
|
||||
requires(quantity<D, U, Rep> q) { quantity_cast<CastSpec>(q); }
|
||||
[[nodiscard]] constexpr auto quantity_point_cast(const quantity_point<D, U, Rep>& qp)
|
||||
{
|
||||
if constexpr (is_specialization_of<CastSpec, quantity_point>)
|
||||
return quantity_point(quantity_cast<typename CastSpec::quantity_type>(qp.relative()));
|
||||
|
||||
@@ -24,10 +24,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <units/quantity.h>
|
||||
|
||||
#if COMP_MSVC || COMP_GCC >= 10
|
||||
#include <compare>
|
||||
#endif
|
||||
|
||||
namespace units {
|
||||
|
||||
@@ -69,69 +66,53 @@ public:
|
||||
|
||||
[[nodiscard]] constexpr quantity_type relative() const noexcept { return q_; }
|
||||
|
||||
template<typename Q = quantity_type>
|
||||
[[nodiscard]] static constexpr quantity_point min() noexcept
|
||||
requires requires { Q::min(); }
|
||||
// requires requires { quantity_type::min(); } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires { quantity_type::min(); }
|
||||
{
|
||||
return quantity_point(quantity_type::min());
|
||||
}
|
||||
|
||||
template<typename Q = quantity_type>
|
||||
[[nodiscard]] static constexpr quantity_point max() noexcept
|
||||
requires requires { Q::max(); }
|
||||
// requires requires { quantity_type::max(); } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires { quantity_type::max(); }
|
||||
{
|
||||
return quantity_point(quantity_type::max());
|
||||
}
|
||||
|
||||
template<typename Q = quantity_type>
|
||||
requires requires(Q q) { ++q; }
|
||||
constexpr quantity_point& operator++()
|
||||
// requires requires(quantity_type q) { ++q; } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires(quantity_type q) { ++q; }
|
||||
{
|
||||
++q_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Q = quantity_type>
|
||||
[[nodiscard]] constexpr quantity_point operator++(int)
|
||||
requires requires(Q q) { q++; }
|
||||
// requires requires(quantity_type q) { q++; } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires(quantity_type q) { q++; }
|
||||
{
|
||||
return quantity_point(q_++);
|
||||
}
|
||||
|
||||
template<typename Q = quantity_type>
|
||||
requires requires(Q q) { --q; }
|
||||
constexpr quantity_point& operator--()
|
||||
// requires requires(quantity_type q) { --q; } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires(quantity_type q) { --q; }
|
||||
{
|
||||
--q_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Q = quantity_type>
|
||||
[[nodiscard]] constexpr quantity_point operator--(int)
|
||||
requires requires(Q q) { q--; }
|
||||
// requires requires(quantity_type q) { q--; } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires(quantity_type q) { q--; }
|
||||
{
|
||||
return quantity_point(q_--);
|
||||
}
|
||||
|
||||
template<typename Q = quantity_type>
|
||||
requires requires(Q q1, Q q2) { q1 += q2; }
|
||||
constexpr quantity_point& operator+=(const quantity_type& q)
|
||||
// requires requires(quantity_type q) { q += q; } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires(quantity_type q) { q += q; }
|
||||
{
|
||||
q_ += q;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Q = quantity_type>
|
||||
requires requires(Q q1, Q q2) { q1 -= q2; }
|
||||
constexpr quantity_point& operator-=(const quantity_type& q)
|
||||
// requires requires(quantity_type q) { q1 -= q2; } // TODO gated by gcc-9 (fixed in gcc-10)
|
||||
requires requires(quantity_type q1, quantity_type q2) { q1 -= q2; }
|
||||
{
|
||||
q_ -= q;
|
||||
return *this;
|
||||
@@ -139,100 +120,58 @@ public:
|
||||
|
||||
// Hidden Friends
|
||||
// Below friend functions are to be found via argument-dependent lookup only
|
||||
#if COMP_MSVC || COMP_GCC >= 10
|
||||
|
||||
template<Quantity Q>
|
||||
[[nodiscard]] friend constexpr QuantityPoint auto operator+(const quantity_point& lhs, const Q& rhs)
|
||||
requires requires { lhs.relative() + rhs; }
|
||||
{
|
||||
const auto q = lhs.relative() + rhs;
|
||||
using q_type = decltype(q);
|
||||
return quantity_point<typename q_type::dimension, typename q_type::unit, typename q_type::rep>(q);
|
||||
}
|
||||
|
||||
template<Quantity Q>
|
||||
[[nodiscard]] friend constexpr QuantityPoint auto operator+(const Q& lhs, const quantity_point& rhs)
|
||||
requires requires { rhs + lhs; }
|
||||
{
|
||||
return rhs + lhs;
|
||||
}
|
||||
|
||||
template<Quantity Q>
|
||||
[[nodiscard]] friend constexpr QuantityPoint auto operator-(const quantity_point& lhs, const Q& rhs)
|
||||
requires requires { lhs.relative() - rhs; }
|
||||
{
|
||||
const auto q = lhs.relative() - rhs;
|
||||
using q_type = decltype(q);
|
||||
return quantity_point<typename q_type::dimension, typename q_type::unit, typename q_type::rep>(q);
|
||||
}
|
||||
|
||||
template<QuantityPoint QP>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator-(const quantity_point& lhs, const QP& rhs)
|
||||
requires requires { lhs.relative() - rhs.relative(); }
|
||||
{
|
||||
return lhs.relative() - rhs.relative();
|
||||
}
|
||||
|
||||
template<QuantityPoint QP>
|
||||
[[nodiscard]] friend constexpr auto operator<=>(const quantity_point& lhs, const QP& rhs)
|
||||
requires std::three_way_comparable_with<quantity_type, typename QP::quantity_type>
|
||||
[[nodiscard]] friend constexpr auto operator<=>(const quantity_point& lhs, const QP& rhs)
|
||||
{
|
||||
return lhs.relative() <=> rhs.relative();
|
||||
}
|
||||
|
||||
template<QuantityPoint QP>
|
||||
[[nodiscard]] friend constexpr bool operator==(const quantity_point& lhs, const QP& rhs)
|
||||
requires std::equality_comparable_with<quantity_type, typename QP::quantity_type>
|
||||
[[nodiscard]] friend constexpr bool operator==(const quantity_point& lhs, const QP& rhs)
|
||||
{
|
||||
return lhs.relative() == rhs.relative();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<QuantityPoint QP>
|
||||
[[nodiscard]] friend constexpr bool operator==(const quantity_point& lhs, const QP& rhs)
|
||||
requires std::equality_comparable_with<quantity_type, typename QP::quantity_type>
|
||||
{
|
||||
return lhs.relative() == rhs.relative();
|
||||
}
|
||||
|
||||
template<QuantityPoint QP>
|
||||
[[nodiscard]] friend constexpr bool operator!=(const quantity_point& lhs, const QP& rhs)
|
||||
requires std::equality_comparable_with<quantity_type, typename QP::quantity_type>
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template<QuantityPoint QP>
|
||||
[[nodiscard]] friend constexpr bool operator<(const quantity_point& lhs, const QP& rhs)
|
||||
requires std::totally_ordered_with<quantity_type, typename QP::quantity_type>
|
||||
{
|
||||
return lhs.relative() < rhs.relative();
|
||||
}
|
||||
|
||||
template<QuantityPoint QP>
|
||||
[[nodiscard]] friend constexpr bool operator<=(const quantity_point& lhs, const QP& rhs)
|
||||
requires std::totally_ordered_with<quantity_type, typename QP::quantity_type>
|
||||
{
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
|
||||
template<QuantityPoint QP>
|
||||
[[nodiscard]] friend constexpr bool operator>(const quantity_point& lhs, const QP& rhs)
|
||||
requires std::totally_ordered_with<quantity_type, typename QP::quantity_type>
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
template<QuantityPoint QP>
|
||||
[[nodiscard]] friend constexpr bool operator>=(const quantity_point& lhs, const QP& rhs)
|
||||
requires std::totally_ordered_with<quantity_type, typename QP::quantity_type>
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename D, typename U, typename Rep>
|
||||
quantity_point(quantity<D, U, Rep>) -> quantity_point<D, U, Rep>;
|
||||
|
||||
template<QuantityPoint QP, Quantity Q>
|
||||
[[nodiscard]] constexpr QuantityPoint AUTO operator+(const QP& lhs, const Q& rhs)
|
||||
requires requires { lhs.relative() + rhs; }
|
||||
{
|
||||
return quantity_point(lhs.relative() + rhs);
|
||||
}
|
||||
|
||||
template<Quantity Q, QuantityPoint QP>
|
||||
[[nodiscard]] constexpr QuantityPoint AUTO operator+(const Q& lhs, const QP& rhs)
|
||||
requires requires { rhs + lhs; }
|
||||
{
|
||||
return rhs + lhs;
|
||||
}
|
||||
|
||||
template<QuantityPoint QP, Quantity Q>
|
||||
[[nodiscard]] constexpr QuantityPoint AUTO operator-(const QP& lhs, const Q& rhs)
|
||||
requires requires { lhs.relative() - rhs; }
|
||||
{
|
||||
return quantity_point(lhs.relative() - rhs);
|
||||
}
|
||||
|
||||
template<QuantityPoint QP1, QuantityPoint QP2>
|
||||
[[nodiscard]] constexpr Quantity AUTO operator-(const QP1& lhs, const QP2& rhs)
|
||||
requires requires { lhs.relative() - rhs.relative(); }
|
||||
{
|
||||
return lhs.relative() - rhs.relative();
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename D, typename U, typename Rep>
|
||||
|
||||
@@ -55,24 +55,8 @@ struct ratio {
|
||||
detail::normalize(num, den, exp);
|
||||
}
|
||||
|
||||
#if COMP_MSVC || COMP_GCC >= 10
|
||||
|
||||
[[nodiscard]] friend constexpr bool operator==(const ratio&, const ratio&) = default;
|
||||
|
||||
#else
|
||||
|
||||
[[nodiscard]] friend constexpr bool operator==(const ratio& lhs, const ratio& rhs)
|
||||
{
|
||||
return lhs.num == rhs.num && lhs.den == rhs.den && lhs.exp == rhs.exp;
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr bool operator!=(const ratio& lhs, const ratio& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
[[nodiscard]] friend constexpr ratio operator*(const ratio& lhs, const ratio& rhs)
|
||||
{
|
||||
const std::intmax_t gcd1 = std::gcd(lhs.num, rhs.den);
|
||||
|
||||
@@ -25,10 +25,7 @@
|
||||
#include <units/bits/external/fixed_string.h>
|
||||
#include <units/bits/external/hacks.h>
|
||||
#include <gsl/gsl_assert>
|
||||
|
||||
#if COMP_MSVC || COMP_GCC >= 10
|
||||
#include <compare>
|
||||
#endif
|
||||
|
||||
namespace units {
|
||||
|
||||
@@ -125,8 +122,6 @@ struct basic_symbol_text {
|
||||
return basic_symbol_text<StandardCharT, 1, 1>(lhs) + rhs;
|
||||
}
|
||||
|
||||
#if COMP_MSVC || COMP_GCC >= 10
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2, std::size_t M2>
|
||||
[[nodiscard]] friend constexpr auto operator<=>(const basic_symbol_text& lhs,
|
||||
const basic_symbol_text<StandardCharT2, N2, M2>& rhs) noexcept
|
||||
@@ -141,217 +136,6 @@ struct basic_symbol_text {
|
||||
{
|
||||
return lhs.standard() == rhs.standard() && lhs.ascii() == rhs.ascii();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// I did not update the below operators with comparing ASCII as this code is going to be deleted soon anyway...
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2, std::size_t M2>
|
||||
[[nodiscard]] constexpr friend bool operator==(const basic_symbol_text& lhs,
|
||||
const basic_symbol_text<StandardCharT2, N2, M2>& rhs) noexcept
|
||||
{
|
||||
return lhs.standard() == rhs.standard();
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2, std::size_t M2>
|
||||
[[nodiscard]] constexpr friend bool operator!=(const basic_symbol_text& lhs,
|
||||
const basic_symbol_text<StandardCharT2, N2, M2>& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr friend bool operator==(const basic_symbol_text& lhs,
|
||||
const basic_fixed_string<StandardCharT, N>& rhs) noexcept
|
||||
{
|
||||
return lhs.standard() == rhs;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr friend bool operator!=(const basic_symbol_text& lhs,
|
||||
const basic_fixed_string<StandardCharT, N>& rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator==(const basic_symbol_text&,
|
||||
const basic_fixed_string<StandardCharT2, N2>&) noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator!=(const basic_symbol_text&,
|
||||
const basic_fixed_string<StandardCharT2, N2>&) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr friend bool operator==(const basic_symbol_text& lhs,
|
||||
const StandardCharT (&rhs)[N + 1]) noexcept
|
||||
{
|
||||
return lhs.standard() == rhs;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr friend bool operator!=(const basic_symbol_text& lhs,
|
||||
const StandardCharT (&rhs)[N + 1]) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator==(const basic_symbol_text&,
|
||||
const StandardCharT2 (&)[N2 + 1]) noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator!=(const basic_symbol_text&,
|
||||
const StandardCharT2 (&)[N2 + 1]) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr friend bool operator==(const basic_symbol_text& lhs,
|
||||
StandardCharT rhs) noexcept
|
||||
{
|
||||
return lhs.standard() == rhs;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr friend bool operator!=(const basic_symbol_text& lhs,
|
||||
StandardCharT rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template<typename StandardCharT2>
|
||||
[[nodiscard]] constexpr friend bool operator==(const basic_symbol_text&,
|
||||
StandardCharT2) noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename StandardCharT2>
|
||||
[[nodiscard]] constexpr friend bool operator!=(const basic_symbol_text&,
|
||||
StandardCharT2) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2, std::size_t M2>
|
||||
[[nodiscard]] constexpr friend bool operator<(const basic_symbol_text& lhs,
|
||||
const basic_symbol_text<StandardCharT2, N2, M2>& rhs) noexcept
|
||||
{
|
||||
return lhs.standard() < rhs.standard();
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator<(const basic_symbol_text& lhs,
|
||||
const basic_fixed_string<StandardCharT2, N2>& rhs) noexcept
|
||||
{
|
||||
return lhs.standard() < rhs;
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator<(const basic_symbol_text& lhs,
|
||||
const StandardCharT2 (&rhs)[N2]) noexcept
|
||||
{
|
||||
return lhs.standard() < basic_fixed_string(rhs);
|
||||
}
|
||||
|
||||
template<typename StandardCharT2>
|
||||
[[nodiscard]] constexpr friend bool operator<(const basic_symbol_text& lhs,
|
||||
StandardCharT2 rhs) noexcept
|
||||
{
|
||||
return lhs.standard() < basic_fixed_string(rhs);
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2, std::size_t M2>
|
||||
[[nodiscard]] constexpr friend bool operator>(const basic_symbol_text& lhs,
|
||||
const basic_symbol_text<StandardCharT2, N2, M2>& rhs) noexcept
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator>(const basic_symbol_text& lhs,
|
||||
const basic_fixed_string<StandardCharT2, N2>& rhs) noexcept
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator>(const basic_symbol_text& lhs,
|
||||
const StandardCharT2 (&rhs)[N2]) noexcept
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
template<typename StandardCharT2>
|
||||
[[nodiscard]] constexpr friend bool operator>(const basic_symbol_text& lhs,
|
||||
StandardCharT2 rhs) noexcept
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2, std::size_t M2>
|
||||
[[nodiscard]] constexpr friend bool operator<=(const basic_symbol_text& lhs,
|
||||
const basic_symbol_text<StandardCharT2, N2, M2>& rhs) noexcept
|
||||
{
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator<=(const basic_symbol_text& lhs,
|
||||
const basic_fixed_string<StandardCharT2, N2>& rhs) noexcept
|
||||
{
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator<=(const basic_symbol_text& lhs,
|
||||
const StandardCharT2 (&rhs)[N2]) noexcept
|
||||
{
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
|
||||
template<typename StandardCharT2>
|
||||
[[nodiscard]] constexpr friend bool operator<=(const basic_symbol_text& lhs,
|
||||
StandardCharT2 rhs) noexcept
|
||||
{
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2, std::size_t M2>
|
||||
[[nodiscard]] constexpr friend bool operator>=(const basic_symbol_text& lhs,
|
||||
const basic_symbol_text<StandardCharT2, N2, M2>& rhs) noexcept
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator>=(const basic_symbol_text& lhs,
|
||||
const basic_fixed_string<StandardCharT2, N2>& rhs) noexcept
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
template<typename StandardCharT2, std::size_t N2>
|
||||
[[nodiscard]] constexpr friend bool operator>=(const basic_symbol_text& lhs,
|
||||
const StandardCharT2 (&rhs)[N2]) noexcept
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
template<typename StandardCharT2>
|
||||
[[nodiscard]] constexpr friend bool operator>=(const basic_symbol_text& lhs,
|
||||
StandardCharT2 rhs) noexcept
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
basic_symbol_text(char) -> basic_symbol_text<char, 1, 1>;
|
||||
|
||||
Reference in New Issue
Block a user