diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 23a24713..fe247e88 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,5 +25,4 @@ Until then, please code alike what is there already: ## Backward Compatibility -Before submission, please remember to check if the code compiles fine on all the supported compilers (especially gcc-9.3 and MSVC are tricky). -Unfortunately, we cannot add gcc-9.3 to the CI process as it is [not supported by Conan Docker images](https://github.com/conan-io/conan-docker-tools/issues/200). +Before submission, please remember to check if the code compiles fine on all the supported compilers (gcc-10 and MSVC so far). diff --git a/conanfile.py b/conanfile.py index a757b5dd..00fc4e8e 100644 --- a/conanfile.py +++ b/conanfile.py @@ -66,8 +66,8 @@ class UnitsConan(ConanFile): compiler = self.settings.compiler version = Version(self.settings.compiler.version) if compiler == "gcc": - if version < "9.3": - raise ConanInvalidConfiguration("mp-units requires at least g++-9.3") + if version < "10.0": + raise ConanInvalidConfiguration("mp-units requires at least g++-10") elif compiler == "Visual Studio": if version < "16": raise ConanInvalidConfiguration("mp-units requires at least MSVC 16") @@ -88,11 +88,6 @@ class UnitsConan(ConanFile): def configure(self): self._validate_compiler_settings() - def requirements(self): - if ((self.settings.compiler == "gcc" and Version(self.settings.compiler.version) < "10") or - self.settings.compiler == "clang"): - self.requires("range-v3/0.11.0") - def build_requirements(self): if self._run_tests: self.build_requires("catch2/2.13.0") @@ -123,10 +118,6 @@ class UnitsConan(ConanFile): "-Wno-literal-suffix", "-Wno-non-template-friend", ] - if version < "10": - self.cpp_info.cxxflags.extend([ - "-fconcepts" - ]) elif compiler == "Visual Studio": self.cpp_info.cxxflags = [ "/utf-8", diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 532abc63..2a47137f 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,7 +1,7 @@ # Release notes - **0.6.0 WIP** - - Minimum compiler version supported changed to gcc-9.3 + - gcc-9 is no longer supported (at least gcc-10 is required) - MSVC 16.7 support added - linear_algebra updated to 0.7.0/stable - fmt updated to 7.0.3 diff --git a/docs/design/quantity.rst b/docs/design/quantity.rst index 6212886b..a4695c44 100644 --- a/docs/design/quantity.rst +++ b/docs/design/quantity.rst @@ -44,7 +44,7 @@ a few additional member types and functions:: template requires detail::basic_arithmetic && (!equivalent_dim) - [[nodiscard]] constexpr Quantity AUTO operator/(const quantity& lhs, + [[nodiscard]] constexpr Quantity auto operator/(const quantity& lhs, const quantity& rhs); Additional functions provide the support for operations that result in a diff --git a/docs/index.rst b/docs/index.rst index f0697b60..cd430e0d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -16,7 +16,7 @@ with a permissive `MIT license `_ (only for gcc versions < 10.0) to provide - C++20 concepts library definitions. - `{fmt} `_ to provide text formatting of quantities. - `ms-gsl `_ to verify runtime contracts with `Expects` macro. diff --git a/example/alternative_namespaces/units_str.h b/example/alternative_namespaces/units_str.h index 3b0bfacd..2dffc459 100644 --- a/example/alternative_namespaces/units_str.h +++ b/example/alternative_namespaces/units_str.h @@ -4,7 +4,7 @@ #include #include // get at the units text of the quantity, without its numeric value -inline auto constexpr units_str(const units::Quantity AUTO& q) +inline auto constexpr units_str(const units::Quantity auto& q) { typedef std::remove_cvref_t qtype; return units::detail::unit_text(); diff --git a/example/avg_speed.cpp b/example/avg_speed.cpp index a0c4dbd1..ce7d3782 100644 --- a/example/avg_speed.cpp +++ b/example/avg_speed.cpp @@ -44,13 +44,13 @@ fixed_double_si_avg_speed(si::length d, } template -constexpr Speed AUTO si_avg_speed(si::length d, +constexpr Speed auto si_avg_speed(si::length d, si::time t) { return d / t; } -constexpr Speed AUTO avg_speed(Length AUTO d, Time AUTO t) +constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; } @@ -68,7 +68,7 @@ void example() // SI (int) { using namespace units::physical::si::literals; - constexpr Length AUTO distance = 220q_km; // constructed from a UDL + constexpr Length auto distance = 220q_km; // constructed from a UDL constexpr si::time duration(2); // constructed from a value std::cout << "SI units with 'int' as representation\n"; @@ -82,7 +82,7 @@ void example() // SI (double) { using namespace units::physical::si::literals; - constexpr Length AUTO distance = 220.q_km; // constructed from a UDL + constexpr Length auto distance = 220.q_km; // constructed from a UDL constexpr si::time duration(2); // constructed from a value std::cout << "\nSI units with 'double' as representation\n"; @@ -98,7 +98,7 @@ void example() // Customary Units (int) { using namespace units::physical::international::literals; - constexpr Length AUTO distance = 140q_mi; // constructed from a UDL + constexpr Length auto distance = 140q_mi; // constructed from a UDL constexpr si::time duration(2); // constructed from a value std::cout << "\nUS Customary Units with 'int' as representation\n"; @@ -114,7 +114,7 @@ void example() // Customary Units (double) { using namespace units::physical::international::literals; - constexpr Length AUTO distance = 140.q_mi; // constructed from a UDL + constexpr Length auto distance = 140.q_mi; // constructed from a UDL constexpr si::time duration(2); // constructed from a value std::cout << "\nUS Customary Units with 'double' as representation\n"; @@ -132,7 +132,7 @@ void example() // CGS (int) { using namespace units::physical::cgs::literals; - constexpr Length AUTO distance = 22'000'000q_cm; // constructed from a UDL + constexpr Length auto distance = 22'000'000q_cm; // constructed from a UDL constexpr cgs::time duration(2); // constructed from a value std::cout << "\nCGS units with 'int' as representation\n"; @@ -151,7 +151,7 @@ void example() // CGS (double) { using namespace units::physical::cgs::literals; - constexpr Length AUTO distance = 22'000'000.q_cm; // constructed from a UDL + constexpr Length auto distance = 22'000'000.q_cm; // constructed from a UDL constexpr cgs::time duration(2); // constructed from a value std::cout << "\nCGS units with 'double' as representation\n"; diff --git a/example/capacitor_time_curve.cpp b/example/capacitor_time_curve.cpp index cdfa9fc1..51a3e446 100644 --- a/example/capacitor_time_curve.cpp +++ b/example/capacitor_time_curve.cpp @@ -41,7 +41,7 @@ int main() constexpr auto R = 4.7q_kR; for (auto t = 0q_ms; t <= 50q_ms; ++t) { - const Voltage AUTO Vt = V0 * units::exp(-t / (R * C)); + const Voltage auto Vt = V0 * units::exp(-t / (R * C)); std::cout << "at " << t << " voltage is "; diff --git a/example/experimental_angle.cpp b/example/experimental_angle.cpp index d15c75be..620ebe98 100644 --- a/example/experimental_angle.cpp +++ b/example/experimental_angle.cpp @@ -34,7 +34,7 @@ int main() auto torque = 20.0q_Nm; auto energy = 20.0q_J; - physical::Angle AUTO angle = torque / energy; + physical::Angle auto angle = torque / energy; std::cout << angle << '\n'; } diff --git a/example/glide_computer.cpp b/example/glide_computer.cpp index b35dacec..76f68167 100644 --- a/example/glide_computer.cpp +++ b/example/glide_computer.cpp @@ -27,10 +27,7 @@ #include #include #include - -#if COMP_MSVC || COMP_GCC >= 10 #include -#endif // horizontal/vertical vector namespace { @@ -59,10 +56,8 @@ public: constexpr Q magnitude() const { return magnitude_; } - template [[nodiscard]] constexpr vector operator-() const - requires requires(QQ q) { -q; } - // requires requires { -magnitude(); } // TODO gated by gcc-9 (fixed in gcc-10) + requires requires { -magnitude(); } { return vector(-magnitude()); } @@ -92,15 +87,17 @@ public: } template + requires (Scalar || Dimensionless) [[nodiscard]] friend constexpr auto operator*(const vector& lhs, const V& value) - requires (Scalar || Dimensionless) && requires { lhs.magnitude() * value; } + requires requires { lhs.magnitude() * value; } { return vector(lhs.magnitude() * value); } template + requires (Scalar || Dimensionless) [[nodiscard]] friend constexpr auto operator*(const V& value, const vector& rhs) - requires (Scalar || Dimensionless) && requires { value * rhs.magnitude(); } + requires requires { value * rhs.magnitude(); } { return vector(value * rhs.magnitude()); } @@ -112,8 +109,6 @@ public: return lhs.magnitude() / rhs.magnitude(); } -#if COMP_MSVC || COMP_GCC >= 10 - template [[nodiscard]] friend constexpr auto operator<=>(const vector& lhs, const vector& rhs) requires requires { lhs.magnitude() <=> rhs.magnitude(); } @@ -128,56 +123,8 @@ public: return lhs.magnitude() == rhs.magnitude(); } -#else - - template - [[nodiscard]] friend constexpr auto operator==(const vector& lhs, const vector& rhs) - requires requires { lhs.magnitude() == rhs.magnitude(); } - { - return lhs.magnitude() == rhs.magnitude(); - } - - template - [[nodiscard]] friend constexpr auto operator!=(const vector& lhs, const vector& rhs) - requires requires { lhs.magnitude() != rhs.magnitude(); } - { - return !(lhs == rhs); - } - - template - [[nodiscard]] friend constexpr auto operator<(const vector& lhs, const vector& rhs) - requires requires { lhs.magnitude() < rhs.magnitude(); } - { - return lhs.magnitude() < rhs.magnitude(); - } - - template - [[nodiscard]] friend constexpr auto operator>(const vector& lhs, const vector& rhs) - requires requires { lhs.magnitude() > rhs.magnitude(); } - { - return rhs < lhs; - } - - template - [[nodiscard]] friend constexpr auto operator<=(const vector& lhs, const vector& rhs) - requires requires { lhs.magnitude() <= rhs.magnitude(); } - { - return !(rhs < lhs); - } - - template - [[nodiscard]] friend constexpr auto operator>=(const vector& lhs, const vector& rhs) - requires requires { lhs.magnitude() >= rhs.magnitude(); } - { - return !(lhs < rhs); - } - -#endif - - // template - // requires Quantity // TODO gated by gcc-9 (fixed in gcc-10) - template - requires Quantity + template + requires Quantity friend std::basic_ostream& operator<<(std::basic_ostream& os, const vector& v) { return os << v.magnitude(); @@ -278,7 +225,7 @@ auto get_gliders() return gliders; } -constexpr Dimensionless AUTO glide_ratio(const glider::polar_point& polar) +constexpr Dimensionless auto glide_ratio(const glider::polar_point& polar) { return polar.v / -polar.climb; } diff --git a/example/hello_units.cpp b/example/hello_units.cpp index 25d20810..a49d12cb 100644 --- a/example/hello_units.cpp +++ b/example/hello_units.cpp @@ -27,7 +27,7 @@ using namespace units::physical; -constexpr Speed AUTO avg_speed(Length AUTO d, Time AUTO t) +constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; } @@ -35,10 +35,10 @@ constexpr Speed AUTO avg_speed(Length AUTO d, Time AUTO t) int main() { using namespace units::physical::si::literals; - Speed AUTO v1 = avg_speed(220q_km, 2q_h); - Speed AUTO v2 = avg_speed(si::length(140), si::time(2)); - Speed AUTO v3 = quantity_cast(v2); - Speed AUTO v4 = quantity_cast(v3); + Speed auto v1 = avg_speed(220q_km, 2q_h); + Speed auto v2 = avg_speed(si::length(140), si::time(2)); + Speed auto v3 = quantity_cast(v2); + Speed auto v4 = quantity_cast(v3); std::cout << v1 << '\n'; // 110 km/h std::cout << fmt::format("{}", v2) << '\n'; // 70 mi/h diff --git a/example/measurement.cpp b/example/measurement.cpp index 5691c4ef..1237e7fc 100644 --- a/example/measurement.cpp +++ b/example/measurement.cpp @@ -22,11 +22,8 @@ #include #include -#include - -#if COMP_MSVC || COMP_GCC >= 10 #include -#endif +#include namespace { @@ -105,41 +102,8 @@ public: return measurement(val, val * rhs.relative_uncertainty()); } -#if COMP_MSVC || COMP_GCC >= 10 - [[nodiscard]] constexpr auto operator<=>(const measurement&) const = default; -#else - - [[nodiscard]] friend constexpr bool operator==(const measurement& lhs, const measurement& rhs) - { - return lhs.value() == rhs.value() && lhs.uncertainty() == rhs.uncertainty(); - } - - [[nodiscard]] friend constexpr bool operator!=(const measurement& lhs, const measurement& rhs) - { - return !(lhs == rhs); - } - - [[nodiscard]] friend constexpr bool operator<(const measurement& lhs, const measurement& rhs) - { - return lhs.value() == rhs.value() ? lhs.uncertainty() < rhs.uncertainty() : lhs.value() < rhs.value(); - } - - [[nodiscard]] friend constexpr bool operator>(const measurement& lhs, const measurement& rhs) { return rhs < lhs; } - - [[nodiscard]] friend constexpr bool operator<=(const measurement& lhs, const measurement& rhs) - { - return !(rhs < lhs); - } - - [[nodiscard]] friend constexpr bool operator>=(const measurement& lhs, const measurement& rhs) - { - return !(lhs < rhs); - } - -#endif - friend std::ostream& operator<<(std::ostream& os, const measurement& v) { return os << v.value() << " ± " << v.uncertainty(); @@ -166,7 +130,7 @@ void example() const auto a = si::acceleration>(measurement(9.8, 0.1)); const auto t = si::time>(measurement(1.2, 0.1)); - const Speed AUTO v1 = a * t; + const Speed auto v1 = a * t; std::cout << a << " * " << t << " = " << v1 << " = " << quantity_cast(v1) << '\n'; si::length> length(measurement(123., 1.)); diff --git a/example/total_energy.cpp b/example/total_energy.cpp index 4b15ca92..3ec087ac 100644 --- a/example/total_energy.cpp +++ b/example/total_energy.cpp @@ -32,7 +32,7 @@ namespace { using namespace units::physical; -Energy AUTO total_energy(Momentum AUTO p, Mass AUTO m, Speed AUTO c) +Energy auto total_energy(Momentum auto p, Mass auto m, Speed auto c) { return sqrt(pow<2>(p * c) + pow<2>(m * pow<2>(c))); } @@ -42,13 +42,13 @@ void si_example() using namespace units::physical::si; using GeV = gigaelectronvolt; - constexpr Speed AUTO c = si2019::speed_of_light<>; + constexpr Speed auto c = si2019::speed_of_light<>; std::cout << "\n*** SI units (c = " << c << ") ***\n"; - const Momentum AUTO p = 4.q_GeV / c; - const Mass AUTO m = 3.q_GeV / pow<2>(c); - const Energy AUTO E = total_energy(p, m, c); + const Momentum auto p = 4.q_GeV / c; + const Mass auto m = 3.q_GeV / pow<2>(c); + const Energy auto E = total_energy(p, m, c); std::cout << "[in GeV]\n" << "p = " << p << "\n" @@ -73,10 +73,10 @@ void natural_example() using namespace units::physical::natural; using GeV = gigaelectronvolt; - constexpr Speed AUTO c = speed_of_light<>; + constexpr Speed auto c = speed_of_light<>; const momentum p(4); const mass m(3); - const Energy AUTO E = total_energy(p, m, c); + const Energy auto E = total_energy(p, m, c); std::cout << "\n*** Natural units (c = " << c << ") ***\n" << "p = " << p << "\n" diff --git a/example/unknown_dimension.cpp b/example/unknown_dimension.cpp index f6437b0c..cf90be90 100644 --- a/example/unknown_dimension.cpp +++ b/example/unknown_dimension.cpp @@ -26,7 +26,7 @@ namespace { template -constexpr units::physical::Speed AUTO avg_speed(D d, T t) +constexpr units::physical::Speed auto avg_speed(D d, T t) { return d / t; } @@ -36,13 +36,13 @@ void example() using namespace units::physical; using namespace units::physical::si::literals; - Length AUTO d1 = 123q_m; - Time AUTO t1 = 10q_s; - Speed AUTO v1 = avg_speed(d1, t1); + Length auto d1 = 123q_m; + Time auto t1 = 10q_s; + Speed auto v1 = avg_speed(d1, t1); auto temp1 = v1 * 50q_m; // produces intermediate unknown dimension with 'unknown_coherent_unit' as its 'coherent_unit' - Speed AUTO v2 = temp1 / 100q_m; // back to known dimensions again - Length AUTO d2 = v2 * 60q_s; + Speed auto v2 = temp1 / 100q_m; // back to known dimensions again + Length auto d2 = v2 * 60q_s; std::cout << "d1 = " << d1 << '\n'; std::cout << "t1 = " << t1 << '\n'; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 832cc02c..35ad4f77 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -74,17 +74,6 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") -Wno-literal-suffix -Wno-non-template-friend ) - - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0) - target_compile_options(mp-units - INTERFACE - -fconcepts - ) - target_link_libraries(mp-units - INTERFACE - $,CONAN_PKG::range-v3,range-v3::range-v3> - ) - endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") target_compile_options(mp-units INTERFACE diff --git a/src/include/units/bits/common_quantity.h b/src/include/units/bits/common_quantity.h index b0530395..20304e83 100644 --- a/src/include/units/bits/common_quantity.h +++ b/src/include/units/bits/common_quantity.h @@ -76,16 +76,8 @@ using common_quantity_point = decltype( } // namespace units -#if COMP_MSVC || COMP_GCC >= 10 - namespace std { -#else - -namespace concepts { - -#endif - template requires units::equivalent_dim struct common_type { diff --git a/src/include/units/bits/external/fixed_string.h b/src/include/units/bits/external/fixed_string.h index 2f355be3..18adc0bd 100644 --- a/src/include/units/bits/external/fixed_string.h +++ b/src/include/units/bits/external/fixed_string.h @@ -26,10 +26,7 @@ #include #include #include - -#if COMP_MSVC || COMP_GCC >= 10 #include -#endif namespace units { @@ -76,8 +73,6 @@ struct basic_fixed_string { return basic_fixed_string(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 - [[nodiscard]] constexpr friend bool operator==(const basic_fixed_string&, - const basic_fixed_string&) noexcept - { - return false; - } - - template - [[nodiscard]] constexpr friend bool operator!=(const basic_fixed_string&, - const basic_fixed_string&) noexcept - { - return true; - } - - template - [[nodiscard]] constexpr friend bool operator<(const basic_fixed_string& lhs, - const basic_fixed_string& 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 - [[nodiscard]] constexpr friend bool operator>(const basic_fixed_string& lhs, - const basic_fixed_string& rhs) noexcept - { - return rhs < lhs; - } - - template - [[nodiscard]] constexpr friend bool operator<=(const basic_fixed_string& lhs, - const basic_fixed_string& rhs) noexcept - { - return !(rhs < lhs); - } - - template - [[nodiscard]] constexpr friend bool operator>=(const basic_fixed_string& lhs, - const basic_fixed_string& rhs) noexcept - { - return !(lhs < rhs); - } - -#endif - template friend std::basic_ostream& operator<<(std::basic_ostream& os, const basic_fixed_string& txt) diff --git a/src/include/units/bits/external/hacks.h b/src/include/units/bits/external/hacks.h index 9831a48f..28f781b9 100644 --- a/src/include/units/bits/external/hacks.h +++ b/src/include/units/bits/external/hacks.h @@ -22,7 +22,7 @@ #pragma once -#include +#include #if __clang__ #define COMP_CLANG __clang_major__ @@ -33,29 +33,6 @@ #define COMP_MSVC _MSC_VER #endif -#if COMP_MSVC || COMP_GCC >= 10 - -#include - -#else - -#include -#include - -#endif - -#if COMP_MSVC || COMP_GCC >= 10 || COMP_CLANG >= 11 - -#define AUTO auto -#define SAME_AS(T) std::same_as - -#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 - concept default_constructible = constructible_from; - -#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 - concept floating_point = std::is_floating_point_v; - - template - concept invocable = - requires(F&& f, Args&&... args) { - std::invoke(std::forward(f), std::forward(args)...); - }; - - template - concept regular_invocable = invocable; - -#endif -#endif +template +concept default_constructible = constructible_from; } // namespace std + +#endif diff --git a/src/include/units/concepts.h b/src/include/units/concepts.h index 1ec4e064..45cf4c9a 100644 --- a/src/include/units/concepts.h +++ b/src/include/units/concepts.h @@ -27,6 +27,7 @@ #include #include #include +#include namespace units { diff --git a/src/include/units/math.h b/src/include/units/math.h index f528c1c1..86bcd773 100644 --- a/src/include/units/math.h +++ b/src/include/units/math.h @@ -40,7 +40,7 @@ namespace units { */ template 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; @@ -70,7 +70,7 @@ inline TYPENAME Q::rep pow(const Q&) noexcept * @return Quantity The result of computation */ template -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; @@ -99,7 +99,7 @@ inline quantity exp(const quantity& q) * @return Quantity The absolute value of a provided quantity */ template -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 requires requires { std::numeric_limits::epsilon(); } -constexpr Quantity AUTO epsilon() noexcept +constexpr Quantity auto epsilon() noexcept { return Q(std::numeric_limits::epsilon()); } diff --git a/src/include/units/quantity.h b/src/include/units/quantity.h index c7336543..382b245d 100644 --- a/src/include/units/quantity.h +++ b/src/include/units/quantity.h @@ -29,11 +29,7 @@ #include #include #include - -#if COMP_MSVC || COMP_GCC >= 10 #include -#endif - #include namespace units { @@ -90,78 +86,60 @@ public: [[nodiscard]] constexpr rep count() const noexcept { return value_; } - template [[nodiscard]] static constexpr quantity zero() noexcept - requires requires { quantity_values::zero(); } - // requires requires { quantity_values::zero(); } // TODO gated by gcc-9 (fixed in gcc-10) + requires requires { quantity_values::zero(); } { return quantity(quantity_values::zero()); } - template [[nodiscard]] static constexpr quantity one() noexcept - requires requires { quantity_values::one(); } - // requires requires { quantity_values::one(); } // TODO gated by gcc-9 (fixed in gcc-10) + requires requires { quantity_values::one(); } { return quantity(quantity_values::one()); } - template [[nodiscard]] static constexpr quantity min() noexcept - requires requires { quantity_values::min(); } - // requires requires { quantity_values::min(); } // TODO gated by gcc-9 (fixed in gcc-10) + requires requires { quantity_values::min(); } { return quantity(quantity_values::min()); } - template [[nodiscard]] static constexpr quantity max() noexcept - requires requires { quantity_values::max(); } - // requires requires { quantity_values::max(); } // TODO gated by gcc-9 (fixed in gcc-10) + requires requires { quantity_values::max(); } { return quantity(quantity_values::max()); } [[nodiscard]] constexpr quantity operator+() const { return *this; } - template [[nodiscard]] constexpr quantity operator-() const - requires std::regular_invocable, T> - // requires std::regular_invocable, rep> // TODO gated by gcc-9 (fixed in gcc-10) + requires std::regular_invocable, rep> { return quantity(-count()); } - template constexpr quantity& operator++() - requires requires(T v) { { ++v } -> SAME_AS(T&); } - // requires requires(rep v) { { ++v } -> std::same_as; } // TODO gated by gcc-9 (fixed in gcc-10) + requires requires(rep v) { { ++v } -> std::same_as; } { ++value_; return *this; } - template [[nodiscard]] constexpr quantity operator++(int) - requires requires(T v) { { v++ } -> SAME_AS(T); } - // requires requires(rep v) { { v++ } -> std::same_as; } // TODO gated by gcc-9 (fixed in gcc-10) + requires requires(rep v) { { v++ } -> std::same_as; } { return quantity(value_++); } - template constexpr quantity& operator--() - requires requires(T v) { { --v } -> SAME_AS(T&); } - // requires requires(rep v) { { --v } -> std::same_as; } // TODO gated by gcc-9 (fixed in gcc-10) + requires requires(rep v) { { --v } -> std::same_as; } { --value_; return *this; } - template [[nodiscard]] constexpr quantity operator--(int) - requires requires(T v) { { v-- } -> SAME_AS(T); } - // requires requires(rep v) { { v-- } -> std::same_as; } // TODO gated by gcc-9 (fixed in gcc-10) + requires requires(rep v) { { v-- } -> std::same_as; } { return quantity(value_--); } @@ -198,22 +176,19 @@ public: return *this; } - template - constexpr quantity& operator%=(const Value& rhs) + template requires (!treat_as_floating_point) && - (!treat_as_floating_point) && - 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) + constexpr quantity& operator%=(const Value& rhs) + requires requires(rep v1, Value v2) { { v1 %= v2 } -> std::same_as; } { value_ %= rhs; return *this; } - template constexpr quantity& operator%=(const quantity& q) requires (!treat_as_floating_point) && - requires(T v1, T v2) { { v1 %= v2 } -> SAME_AS(T&); } - // requires(rep v1, rep v2) { { v1 %= v2 } -> std::same_as; } // TODO gated by gcc-9 (fixed in gcc-10) + requires(rep v1, rep v2) { { v1 %= v2 } -> std::same_as; } { value_ %= q.count(); return *this; @@ -229,8 +204,8 @@ public: } template - [[nodiscard]] friend constexpr Quantity AUTO operator+(const quantity& lhs, const quantity& rhs) requires std::regular_invocable, Rep, Rep2> + [[nodiscard]] friend constexpr Quantity auto operator+(const quantity& lhs, const quantity& rhs) { using common_rep = decltype(lhs.count() + rhs.count()); using ret = common_quantity, common_rep>; @@ -244,8 +219,8 @@ public: } template - [[nodiscard]] friend constexpr Quantity AUTO operator-(const quantity& lhs, const quantity& rhs) requires std::regular_invocable, Rep, Rep2> + [[nodiscard]] friend constexpr Quantity auto operator-(const quantity& lhs, const quantity& rhs) { using common_rep = decltype(lhs.count() - rhs.count()); using ret = common_quantity, common_rep>; @@ -253,8 +228,8 @@ public: } template - [[nodiscard]] friend constexpr Quantity AUTO operator*(const quantity& q, const Value& v) requires std::regular_invocable, Rep, Value> + [[nodiscard]] friend constexpr Quantity auto operator*(const quantity& q, const Value& v) { using common_rep = decltype(q.count() * v); using ret = quantity; @@ -262,15 +237,15 @@ public: } template - [[nodiscard]] friend constexpr Quantity AUTO operator*(const Value& v, const quantity& q) requires std::regular_invocable, Value, Rep> + [[nodiscard]] friend constexpr Quantity auto operator*(const Value& v, const quantity& q) { return q * v; } template - [[nodiscard]] friend constexpr Quantity AUTO operator*(const quantity& lhs, const quantity& rhs) requires std::regular_invocable, Rep, Rep2> + [[nodiscard]] friend constexpr Quantity auto operator*(const quantity& lhs, const quantity& rhs) { using dim = dimension_multiply; using ret_unit = downcast_unit::ratio) * (U2::ratio / dimension_unit::ratio) * dimension_unit::ratio>; @@ -280,8 +255,8 @@ public: } template - [[nodiscard]] friend constexpr Quantity AUTO operator/(const Value& v, const quantity& q) requires std::regular_invocable, Value, Rep> + [[nodiscard]] friend constexpr Quantity auto operator/(const Value& v, const quantity& q) { Expects(q.count() != 0); @@ -293,8 +268,8 @@ public: } template - [[nodiscard]] friend constexpr Quantity AUTO operator/(const quantity& q, const Value& v) requires std::regular_invocable, Rep, Value> + [[nodiscard]] friend constexpr Quantity auto operator/(const quantity& q, const Value& v) { Expects(v != Value{0}); @@ -304,8 +279,8 @@ public: } template - [[nodiscard]] friend constexpr Quantity AUTO operator/(const quantity& lhs, const quantity& rhs) requires std::regular_invocable, Rep, Rep2> + [[nodiscard]] friend constexpr Quantity auto operator/(const quantity& lhs, const quantity& rhs) { Expects(rhs.count() != 0); @@ -317,10 +292,10 @@ public: } template - [[nodiscard]] friend constexpr Quantity AUTO operator%(const quantity& q, const Value& v) requires (!treat_as_floating_point) && (!treat_as_floating_point) && std::regular_invocable, Rep, Value> + [[nodiscard]] friend constexpr Quantity auto operator%(const quantity& q, const Value& v) { using common_rep = decltype(q.count() % v); using ret = quantity; @@ -328,90 +303,34 @@ public: } template - [[nodiscard]] friend constexpr Quantity AUTO operator%(const quantity& lhs, const quantity& rhs) requires (!treat_as_floating_point) && (!treat_as_floating_point) && std::regular_invocable, Rep, Rep2> + [[nodiscard]] friend constexpr Quantity auto operator%(const quantity& lhs, const quantity& rhs) { using common_rep = decltype(lhs.count() % rhs.count()); using ret = common_quantity, common_rep>; return ret(ret(lhs).count() % ret(rhs).count()); } -#if COMP_MSVC || COMP_GCC >= 10 - template - [[nodiscard]] friend constexpr auto operator<=>(const quantity& lhs, const quantity& rhs) requires equivalent_dim && std::three_way_comparable_with + [[nodiscard]] friend constexpr auto operator<=>(const quantity& lhs, const quantity& rhs) { using cq = common_quantity>; return cq(lhs).count() <=> cq(rhs).count(); } template - [[nodiscard]] friend constexpr bool operator==(const quantity& lhs, const quantity& rhs) requires equivalent_dim && std::equality_comparable_with + [[nodiscard]] friend constexpr bool operator==(const quantity& lhs, const quantity& rhs) { using cq = common_quantity>; return cq(lhs).count() == cq(rhs).count(); } -#else - - template - [[nodiscard]] friend constexpr bool operator==(const quantity& lhs, const quantity& rhs) - requires equivalent_dim && - std::equality_comparable_with - { - using cq = common_quantity>; - return cq(lhs).count() == cq(rhs).count(); - } - - template - [[nodiscard]] friend constexpr bool operator!=(const quantity& lhs, const quantity& rhs) - requires equivalent_dim && - std::equality_comparable_with - { - return !(lhs == rhs); - } - - template - [[nodiscard]] friend constexpr bool operator<(const quantity& lhs, const quantity& rhs) - requires equivalent_dim && - std::totally_ordered_with - { - using cq = common_quantity>; - return cq(lhs).count() < cq(rhs).count(); - } - - template - [[nodiscard]] friend constexpr bool operator<=(const quantity& lhs, const quantity& rhs) - requires equivalent_dim && - std::totally_ordered_with - { - return !(rhs < lhs); - } - - template - [[nodiscard]] friend constexpr bool operator>(const quantity& lhs, const quantity& rhs) - requires equivalent_dim && - std::totally_ordered_with - { - return rhs < lhs; - } - - template - [[nodiscard]] friend constexpr bool operator>=(const quantity& lhs, const quantity& rhs) - requires equivalent_dim && - std::totally_ordered_with - { - return !(lhs < rhs); - } - -#endif - template friend std::basic_ostream& operator<<(std::basic_ostream& os, const quantity& q) { diff --git a/src/include/units/quantity_cast.h b/src/include/units/quantity_cast.h index 2f51af6b..d695b671 100644 --- a/src/include/units/quantity_cast.h +++ b/src/include/units/quantity_cast.h @@ -313,8 +313,8 @@ constexpr ratio cast_ratio(const Q1& from, const Q2& to) * @tparam To a target quantity type to cast to */ template -[[nodiscard]] constexpr auto quantity_cast(const quantity& q) requires QuantityOf +[[nodiscard]] constexpr auto quantity_cast(const quantity& q) { using c_ratio = std::integral_constant(), To())>; using c_rep = std::common_type_t; @@ -337,8 +337,8 @@ template * @tparam ToD a dimension type to use for a target quantity */ template -[[nodiscard]] constexpr auto quantity_cast(const quantity& q) requires equivalent_dim +[[nodiscard]] constexpr auto quantity_cast(const quantity& q) { return quantity_cast, Rep>>(q); } @@ -356,8 +356,8 @@ template * @tparam ToU a unit type to use for a target quantity */ template -[[nodiscard]] constexpr auto quantity_cast(const quantity& q) requires UnitOf +[[nodiscard]] constexpr auto quantity_cast(const quantity& q) { return quantity_cast>(q); } @@ -397,9 +397,9 @@ template * @tparam CastSpec a target quantity point type to cast to or anything that works for quantity_cast */ template -[[nodiscard]] constexpr auto quantity_point_cast(const quantity_point& qp) requires is_specialization_of || requires(quantity q) { quantity_cast(q); } +[[nodiscard]] constexpr auto quantity_point_cast(const quantity_point& qp) { if constexpr (is_specialization_of) return quantity_point(quantity_cast(qp.relative())); diff --git a/src/include/units/quantity_point.h b/src/include/units/quantity_point.h index 863851ba..3777ef32 100644 --- a/src/include/units/quantity_point.h +++ b/src/include/units/quantity_point.h @@ -24,10 +24,7 @@ #pragma once #include - -#if COMP_MSVC || COMP_GCC >= 10 #include -#endif namespace units { @@ -69,69 +66,53 @@ public: [[nodiscard]] constexpr quantity_type relative() const noexcept { return q_; } - template [[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 [[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 - 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 [[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 - 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 [[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 - 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 - 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 + [[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(q); + } + + template + [[nodiscard]] friend constexpr QuantityPoint auto operator+(const Q& lhs, const quantity_point& rhs) + requires requires { rhs + lhs; } + { + return rhs + lhs; + } + + template + [[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(q); + } + + template + [[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 - [[nodiscard]] friend constexpr auto operator<=>(const quantity_point& lhs, const QP& rhs) requires std::three_way_comparable_with + [[nodiscard]] friend constexpr auto operator<=>(const quantity_point& lhs, const QP& rhs) { return lhs.relative() <=> rhs.relative(); } template - [[nodiscard]] friend constexpr bool operator==(const quantity_point& lhs, const QP& rhs) requires std::equality_comparable_with + [[nodiscard]] friend constexpr bool operator==(const quantity_point& lhs, const QP& rhs) { return lhs.relative() == rhs.relative(); } -#else - - template - [[nodiscard]] friend constexpr bool operator==(const quantity_point& lhs, const QP& rhs) - requires std::equality_comparable_with - { - return lhs.relative() == rhs.relative(); - } - - template - [[nodiscard]] friend constexpr bool operator!=(const quantity_point& lhs, const QP& rhs) - requires std::equality_comparable_with - { - return !(lhs == rhs); - } - - template - [[nodiscard]] friend constexpr bool operator<(const quantity_point& lhs, const QP& rhs) - requires std::totally_ordered_with - { - return lhs.relative() < rhs.relative(); - } - - template - [[nodiscard]] friend constexpr bool operator<=(const quantity_point& lhs, const QP& rhs) - requires std::totally_ordered_with - { - return !(rhs < lhs); - } - - template - [[nodiscard]] friend constexpr bool operator>(const quantity_point& lhs, const QP& rhs) - requires std::totally_ordered_with - { - return rhs < lhs; - } - - template - [[nodiscard]] friend constexpr bool operator>=(const quantity_point& lhs, const QP& rhs) - requires std::totally_ordered_with - { - return !(lhs < rhs); - } - -#endif }; template quantity_point(quantity) -> quantity_point; -template -[[nodiscard]] constexpr QuantityPoint AUTO operator+(const QP& lhs, const Q& rhs) - requires requires { lhs.relative() + rhs; } -{ - return quantity_point(lhs.relative() + rhs); -} - -template -[[nodiscard]] constexpr QuantityPoint AUTO operator+(const Q& lhs, const QP& rhs) - requires requires { rhs + lhs; } -{ - return rhs + lhs; -} - -template -[[nodiscard]] constexpr QuantityPoint AUTO operator-(const QP& lhs, const Q& rhs) - requires requires { lhs.relative() - rhs; } -{ - return quantity_point(lhs.relative() - rhs); -} - -template -[[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 diff --git a/src/include/units/ratio.h b/src/include/units/ratio.h index c21f196c..ff98b0bf 100644 --- a/src/include/units/ratio.h +++ b/src/include/units/ratio.h @@ -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); diff --git a/src/include/units/symbol_text.h b/src/include/units/symbol_text.h index 131979ac..f38ee6f2 100644 --- a/src/include/units/symbol_text.h +++ b/src/include/units/symbol_text.h @@ -25,10 +25,7 @@ #include #include #include - -#if COMP_MSVC || COMP_GCC >= 10 #include -#endif namespace units { @@ -125,8 +122,6 @@ struct basic_symbol_text { return basic_symbol_text(lhs) + rhs; } -#if COMP_MSVC || COMP_GCC >= 10 - template [[nodiscard]] friend constexpr auto operator<=>(const basic_symbol_text& lhs, const basic_symbol_text& 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 - [[nodiscard]] constexpr friend bool operator==(const basic_symbol_text& lhs, - const basic_symbol_text& rhs) noexcept - { - return lhs.standard() == rhs.standard(); - } - - template - [[nodiscard]] constexpr friend bool operator!=(const basic_symbol_text& lhs, - const basic_symbol_text& rhs) noexcept - { - return !(lhs == rhs); - } - - [[nodiscard]] constexpr friend bool operator==(const basic_symbol_text& lhs, - const basic_fixed_string& rhs) noexcept - { - return lhs.standard() == rhs; - } - - [[nodiscard]] constexpr friend bool operator!=(const basic_symbol_text& lhs, - const basic_fixed_string& rhs) noexcept - { - return !(lhs == rhs); - } - - template - [[nodiscard]] constexpr friend bool operator==(const basic_symbol_text&, - const basic_fixed_string&) noexcept - { - return false; - } - - template - [[nodiscard]] constexpr friend bool operator!=(const basic_symbol_text&, - const basic_fixed_string&) 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 - [[nodiscard]] constexpr friend bool operator==(const basic_symbol_text&, - const StandardCharT2 (&)[N2 + 1]) noexcept - { - return false; - } - - template - [[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 - [[nodiscard]] constexpr friend bool operator==(const basic_symbol_text&, - StandardCharT2) noexcept - { - return false; - } - - template - [[nodiscard]] constexpr friend bool operator!=(const basic_symbol_text&, - StandardCharT2) noexcept - { - return true; - } - - template - [[nodiscard]] constexpr friend bool operator<(const basic_symbol_text& lhs, - const basic_symbol_text& rhs) noexcept - { - return lhs.standard() < rhs.standard(); - } - - template - [[nodiscard]] constexpr friend bool operator<(const basic_symbol_text& lhs, - const basic_fixed_string& rhs) noexcept - { - return lhs.standard() < rhs; - } - - template - [[nodiscard]] constexpr friend bool operator<(const basic_symbol_text& lhs, - const StandardCharT2 (&rhs)[N2]) noexcept - { - return lhs.standard() < basic_fixed_string(rhs); - } - - template - [[nodiscard]] constexpr friend bool operator<(const basic_symbol_text& lhs, - StandardCharT2 rhs) noexcept - { - return lhs.standard() < basic_fixed_string(rhs); - } - - template - [[nodiscard]] constexpr friend bool operator>(const basic_symbol_text& lhs, - const basic_symbol_text& rhs) noexcept - { - return rhs < lhs; - } - - template - [[nodiscard]] constexpr friend bool operator>(const basic_symbol_text& lhs, - const basic_fixed_string& rhs) noexcept - { - return rhs < lhs; - } - - template - [[nodiscard]] constexpr friend bool operator>(const basic_symbol_text& lhs, - const StandardCharT2 (&rhs)[N2]) noexcept - { - return rhs < lhs; - } - - template - [[nodiscard]] constexpr friend bool operator>(const basic_symbol_text& lhs, - StandardCharT2 rhs) noexcept - { - return rhs < lhs; - } - - template - [[nodiscard]] constexpr friend bool operator<=(const basic_symbol_text& lhs, - const basic_symbol_text& rhs) noexcept - { - return !(rhs < lhs); - } - - template - [[nodiscard]] constexpr friend bool operator<=(const basic_symbol_text& lhs, - const basic_fixed_string& rhs) noexcept - { - return !(rhs < lhs); - } - - template - [[nodiscard]] constexpr friend bool operator<=(const basic_symbol_text& lhs, - const StandardCharT2 (&rhs)[N2]) noexcept - { - return !(rhs < lhs); - } - - template - [[nodiscard]] constexpr friend bool operator<=(const basic_symbol_text& lhs, - StandardCharT2 rhs) noexcept - { - return !(rhs < lhs); - } - - template - [[nodiscard]] constexpr friend bool operator>=(const basic_symbol_text& lhs, - const basic_symbol_text& rhs) noexcept - { - return !(lhs < rhs); - } - - template - [[nodiscard]] constexpr friend bool operator>=(const basic_symbol_text& lhs, - const basic_fixed_string& rhs) noexcept - { - return !(lhs < rhs); - } - - template - [[nodiscard]] constexpr friend bool operator>=(const basic_symbol_text& lhs, - const StandardCharT2 (&rhs)[N2]) noexcept - { - return !(lhs < rhs); - } - - template - [[nodiscard]] constexpr friend bool operator>=(const basic_symbol_text& lhs, - StandardCharT2 rhs) noexcept - { - return !(lhs < rhs); - } - -#endif - }; basic_symbol_text(char) -> basic_symbol_text; diff --git a/test_package/test_package.cpp b/test_package/test_package.cpp index ba5d8742..86df020c 100644 --- a/test_package/test_package.cpp +++ b/test_package/test_package.cpp @@ -25,7 +25,7 @@ using namespace units::physical; -constexpr Speed AUTO avg_speed(Length AUTO d, Time AUTO t) +constexpr Speed auto avg_speed(Length auto d, Time auto t) { return d / t; }