From 748e657589d4721d6419d3dd285d8574728410e3 Mon Sep 17 00:00:00 2001 From: Chip Hogg Date: Tue, 29 Oct 2024 20:32:56 -0400 Subject: [PATCH] Update troubleshooting guide The biggest change is that we add a new section for the new kind of error, when users try to pass something to a `QuantityMaker` even though it's already a `Quantity` (and similar for `QuantityPoint`). We also update the guidance to recommend `unblock_int_div` instead of the obsolete `integer_quotient`. Other than that, the PR basically consists of running the build under the five configurations shown here, and copy-pasting error messages. Most changes are just line number tweaks. Some changed implementation details do show up in the error messages. Also, sometimes the compiler changed to be more or less verbose. The details of the changes aren't really important (assuming that I copy-pasted correctly). It's just an update. Fixes #288. --- au/error_examples.cc | 14 + docs/troubleshooting.md | 886 +++++++++++++++++++++++++--------------- 2 files changed, 580 insertions(+), 320 deletions(-) diff --git a/au/error_examples.cc b/au/error_examples.cc index 4d05b2f4..0d7f0f2e 100644 --- a/au/error_examples.cc +++ b/au/error_examples.cc @@ -36,6 +36,20 @@ void example_private_constructor() { constexpr QuantityD length{5.5}; } +//////////////////////////////////////////////////////////////////////////////////////////////////// +// SECTION: ... + +void example_input_to_maker() { + constexpr auto x = meters(1); + constexpr auto x_pt = meters_pt(1); + + // A (BROKEN): passing something that is already a quantity to a quantity maker. + meters(x); + + // B (BROKEN): same as above, but with quantity _points_. + meters_pt(x_pt); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// // SECTION: Dangerous conversion diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index c170c223..a5623ad2 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -82,13 +82,13 @@ It's the "classic" error the units library aims to prevent. au/error_examples.cc:33:17: error: calling a private constructor of class 'au::Quantity' set_timeout(0.5); ^ - ./au/quantity.hh:419:15: note: declared private here + au/code/au/quantity.hh:400:15: note: declared private here constexpr Quantity(Rep value) : value_{value} {} ^ au/error_examples.cc:36:33: error: calling a private constructor of class 'au::Quantity' constexpr QuantityD length{5.5}; ^ - ./au/quantity.hh:419:15: note: declared private here + au/code/au/quantity.hh:400:15: note: declared private here constexpr Quantity(Rep value) : value_{value} {} ^ ``` @@ -98,13 +98,13 @@ It's the "classic" error the units library aims to prevent. au/error_examples.cc:33:17: error: calling a private constructor of class 'au::Quantity' set_timeout(0.5); ^ - ./au/quantity.hh:419:15: note: declared private here + au/code/au/quantity.hh:400:15: note: declared private here constexpr Quantity(Rep value) : value_{value} {} ^ au/error_examples.cc:36:33: error: calling a private constructor of class 'au::Quantity' constexpr QuantityD length{5.5}; ^ - ./au/quantity.hh:419:15: note: declared private here + au/code/au/quantity.hh:400:15: note: declared private here constexpr Quantity(Rep value) : value_{value} {} ^ ``` @@ -115,20 +115,22 @@ It's the "classic" error the units library aims to prevent. au/error_examples.cc:33:20: error: 'constexpr au::Quantity::Quantity(au::Quantity::Rep) [with UnitT = au::Seconds; RepT = double; au::Quantity::Rep = double]' is private within this context 33 | set_timeout(0.5); | ^ - In file included from ./au/math.hh:22, - from ./au/au.hh:19, + In file included from au/code/au/prefix.hh:18, + from au/code/au/chrono_interop.hh:20, + from au/code/au/au.hh:17, from au/error_examples.cc:15: - ./au/quantity.hh:419:15: note: declared private here - 419 | constexpr Quantity(Rep value) : value_{value} {} + au/code/au/quantity.hh:400:15: note: declared private here + 400 | constexpr Quantity(Rep value) : value_{value} {} | ^~~~~~~~ au/error_examples.cc:36:43: error: 'constexpr au::Quantity::Quantity(au::Quantity::Rep) [with UnitT = au::Meters; RepT = double; au::Quantity::Rep = double]' is private within this context 36 | constexpr QuantityD length{5.5}; | ^ - In file included from ./au/math.hh:22, - from ./au/au.hh:19, + In file included from au/code/au/prefix.hh:18, + from au/code/au/chrono_interop.hh:20, + from au/code/au/au.hh:17, from au/error_examples.cc:15: - ./au/quantity.hh:419:15: note: declared private here - 419 | constexpr Quantity(Rep value) : value_{value} {} + au/code/au/quantity.hh:400:15: note: declared private here + 400 | constexpr Quantity(Rep value) : value_{value} {} | ^~~~~~~~ ``` @@ -152,6 +154,150 @@ It's the "classic" error the units library aims to prevent. D:\a\au\au\au.hh(3269): note: see declaration of 'au::Quantity' ``` +## Input to Maker + +**Meaning:** This happens when you try to pass something to a "maker" (quantity maker, or quantity +point maker), but it's _already_ a `Quantity` or `QuantityPoint`. + +**Solution:** Generally, this is pretty easy: just remove the redundant call. + +!!! example + **Code** + + === "Broken" + ```cpp + constexpr auto x = meters(1); + constexpr auto x_pt = meters_pt(1); + + // A (BROKEN): passing something that is already a quantity to a quantity maker. + meters(x); + + // B (BROKEN): same as above, but with quantity _points_. + meters_pt(x_pt); + ``` + + === "Fixed" + ```cpp + constexpr auto x = meters(1); + constexpr auto x_pt = meters_pt(1); + + // A (FIXED): just use the quantity directly. + x; + + // B (FIXED): just use the quantity point directly. + x_pt; + ``` + + **Compiler error (clang 14)** + ``` + au/code/au/quantity.hh:523:9: error: static_assert failed due to requirement 'is_not_already_a_quantity' "Input to QuantityMaker is already a Quantity" + static_assert(is_not_already_a_quantity, "Input to QuantityMaker is already a Quantity"); + ^ ~~~~~~~~~~~~~~~~~~~~~~~~~ + au/error_examples.cc:47:11: note: in instantiation of function template specialization 'au::QuantityMaker::operator()' requested here + meters(x); + ^ + In file included from au/error_examples.cc:15: + In file included from au/code/au/au.hh:17: + In file included from au/code/au/chrono_interop.hh:20: + In file included from au/code/au/prefix.hh:19: + au/code/au/quantity_point.hh:295:9: error: static_assert failed due to requirement 'is_not_already_a_quantity_point' "Input to QuantityPointMaker is already a QuantityPoint" + static_assert(is_not_already_a_quantity_point, + ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + au/error_examples.cc:50:14: note: in instantiation of function template specialization 'au::QuantityPointMaker::operator()' requested here + meters_pt(x_pt); + ^ + In file included from au/error_examples.cc:15: + In file included from au/code/au/au.hh:17: + In file included from au/code/au/chrono_interop.hh:20: + In file included from au/code/au/prefix.hh:18: + ``` + + **Compiler error (clang 11)** + ``` + au/code/au/quantity.hh:523:9: error: static_assert failed due to requirement 'is_not_already_a_quantity' "Input to QuantityMaker is already a Quantity" + static_assert(is_not_already_a_quantity, "Input to QuantityMaker is already a Quantity"); + ^ ~~~~~~~~~~~~~~~~~~~~~~~~~ + au/error_examples.cc:47:11: note: in instantiation of function template specialization 'au::QuantityMaker::operator()' requested here + meters(x); + ^ + In file included from au/error_examples.cc:15: + In file included from au/code/au/au.hh:17: + In file included from au/code/au/chrono_interop.hh:20: + In file included from au/code/au/prefix.hh:19: + au/code/au/quantity_point.hh:295:9: error: static_assert failed due to requirement 'is_not_already_a_quantity_point' "Input to QuantityPointMaker is already a QuantityPoint" + static_assert(is_not_already_a_quantity_point, + ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + au/error_examples.cc:50:14: note: in instantiation of function template specialization 'au::QuantityPointMaker::operator()' requested here + meters_pt(x_pt); + ^ + In file included from au/error_examples.cc:15: + In file included from au/code/au/au.hh:17: + In file included from au/code/au/chrono_interop.hh:20: + In file included from au/code/au/prefix.hh:18: + ``` + + **Compiler error (gcc 10)** + ``` + In file included from au/code/au/prefix.hh:18, + from au/code/au/chrono_interop.hh:20, + from au/code/au/au.hh:17, + from au/error_examples.cc:15: + au/code/au/quantity.hh: In instantiation of 'constexpr void au::QuantityMaker::operator()(au::Quantity) const [with U = au::Meters; R = int; UnitT = au::Meters]': + au/error_examples.cc:47:13: required from here + au/code/au/quantity.hh:523:23: error: static assertion failed: Input to QuantityMaker is already a Quantity + 523 | static_assert(is_not_already_a_quantity, "Input to QuantityMaker is already a Quantity"); + | ^~~~~~~~~~~~~~~~~~~~~~~~~ + In file included from au/code/au/prefix.hh:19, + from au/code/au/chrono_interop.hh:20, + from au/code/au/au.hh:17, + from au/error_examples.cc:15: + au/code/au/quantity_point.hh: In instantiation of 'constexpr void au::QuantityPointMaker::operator()(au::QuantityPoint) const [with U = au::Meters; R = int; Unit = au::Meters]': + au/error_examples.cc:50:19: required from here + au/code/au/quantity_point.hh:295:23: error: static assertion failed: Input to QuantityPointMaker is already a QuantityPoint + 295 | static_assert(is_not_already_a_quantity_point, + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` + + **Compiler error (MSVC 2019 x64)** + ``` + D:\a\au\au\au.hh(4391): error C2338: Input to QuantityMaker is already a Quantity + error_examples.cc(48): note: see reference to function template instantiation 'void au::QuantityMaker::operator ()(au::Quantity) const' being compiled + error_examples.cc(48): note: see reference to function template instantiation 'void au::QuantityMaker::operator ()(au::Quantity) const' being compiled + D:\a\au\au\au.hh(5111): error C2338: Input to QuantityPointMaker is already a QuantityPoint + error_examples.cc(51): note: see reference to function template instantiation 'void au::QuantityPointMaker::operator ()(au::QuantityPoint) const' being compiled + with + [ + Unit=au::Meters, + T=int + ] + error_examples.cc(51): note: see reference to function template instantiation 'void au::QuantityPointMaker::operator ()(au::QuantityPoint) const' being compiled + with + [ + Unit=au::Meters, + T=int + ] + ``` + + + **Compiler error (MSVC 2022 x64)** + ``` + D:\a\au\au\au.hh(4391): error C2338: static_assert failed: 'Input to QuantityMaker is already a Quantity' + D:\a\au\au\au.hh(4391): note: the template instantiation context (the oldest one first) is + error_examples.cc(48): note: see reference to function template instantiation 'void au::QuantityMaker::operator ()(au::Quantity) const' being compiled + error_examples.cc(48): note: see the first reference to 'au::QuantityMaker::operator ()' in 'au::example_input_to_maker' + D:\a\au\au\au.hh(5111): error C2338: static_assert failed: 'Input to QuantityPointMaker is already a QuantityPoint' + D:\a\au\au\au.hh(5111): note: the template instantiation context (the oldest one first) is + error_examples.cc(51): note: see reference to function template instantiation 'void au::QuantityPointMaker::operator ()(au::QuantityPoint) const' being compiled + with + [ + Unit=au::Meters, + T=int + ] + error_examples.cc(51): note: see the first reference to 'au::QuantityPointMaker::operator ()' in 'au::example_input_to_maker' + ``` + + + ## Dangerous conversion **Meaning:** This is a _physically_ meaningful conversion, but we think the risk of a grossly @@ -212,50 +358,40 @@ operation (at least in this format). **Compiler error (clang 14)** ``` - ./au/quantity.hh:168:9: error: static_assert failed due to requirement 'IMPLICIT_OK' "Dangerous conversion for integer Rep! See: https://aurora-opensource.github.io/au/main/troubleshooting/#dangerous-conversion" + au/code/au/quantity.hh:163:9: error: static_assert failed due to requirement 'IMPLICIT_OK' "Dangerous conversion for integer Rep! See: https://aurora-opensource.github.io/au/main/troubleshooting/#dangerous-conversion" static_assert( ^ - ./au/quantity.hh:206:16: note: in instantiation of function template specialization 'au::Quantity::as' requested here - return as(NewUnit{}); - ^ - au/error_examples.cc:44:16: note: in instantiation of function template specialization 'au::Quantity::as' requested here + au/error_examples.cc:58:16: note: in instantiation of function template specialization 'au::Quantity::as, void>' requested here inches(24).as(feet); ^ In file included from au/error_examples.cc:15: - In file included from ./au/au.hh:19: - In file included from ./au/math.hh:22: - ./au/quantity.hh:168:9: error: static_assert failed due to requirement 'IMPLICIT_OK' "Dangerous conversion for integer Rep! See: https://aurora-opensource.github.io/au/main/troubleshooting/#dangerous-conversion" + In file included from au/code/au/au.hh:17: + In file included from au/code/au/chrono_interop.hh:20: + In file included from au/code/au/prefix.hh:18: + au/code/au/quantity.hh:163:9: error: static_assert failed due to requirement 'IMPLICIT_OK' "Dangerous conversion for integer Rep! See: https://aurora-opensource.github.io/au/main/troubleshooting/#dangerous-conversion" static_assert( ^ - ./au/quantity.hh:206:16: note: in instantiation of function template specialization 'au::Quantity, int>::as' requested here - return as(NewUnit{}); - ^ - au/error_examples.cc:47:20: note: in instantiation of function template specialization 'au::Quantity, int>::as' requested here + au/error_examples.cc:61:20: note: in instantiation of function template specialization 'au::Quantity, int>::as, void>' requested here giga(hertz)(1).as(hertz); ^ ``` **Compiler error (clang 11)** ``` - ./au/quantity.hh:168:9: error: static_assert failed due to requirement 'IMPLICIT_OK' "Dangerous conversion for integer Rep! See: https://aurora-opensource.github.io/au/main/troubleshooting/#dangerous-conversion" + au/code/au/quantity.hh:163:9: error: static_assert failed due to requirement 'IMPLICIT_OK' "Dangerous conversion for integer Rep! See: https://aurora-opensource.github.io/au/main/troubleshooting/#dangerous-conversion" static_assert( ^ - ./au/quantity.hh:206:16: note: in instantiation of function template specialization 'au::Quantity::as' requested here - return as(NewUnit{}); - ^ - au/error_examples.cc:44:16: note: in instantiation of function template specialization 'au::Quantity::as' requested here + au/error_examples.cc:58:16: note: in instantiation of function template specialization 'au::Quantity::as, void>' requested here inches(24).as(feet); ^ In file included from au/error_examples.cc:15: - In file included from ./au/au.hh:19: - In file included from ./au/math.hh:22: - ./au/quantity.hh:168:9: error: static_assert failed due to requirement 'IMPLICIT_OK' "Dangerous conversion for integer Rep! See: https://aurora-opensource.github.io/au/main/troubleshooting/#dangerous-conversion" + In file included from au/code/au/au.hh:17: + In file included from au/code/au/chrono_interop.hh:20: + In file included from au/code/au/prefix.hh:18: + au/code/au/quantity.hh:163:9: error: static_assert failed due to requirement 'IMPLICIT_OK' "Dangerous conversion for integer Rep! See: https://aurora-opensource.github.io/au/main/troubleshooting/#dangerous-conversion" static_assert( ^ - ./au/quantity.hh:206:16: note: in instantiation of function template specialization 'au::Quantity, int>::as' requested here - return as(NewUnit{}); - ^ - au/error_examples.cc:47:20: note: in instantiation of function template specialization 'au::Quantity, int>::as' requested here + au/error_examples.cc:61:20: note: in instantiation of function template specialization 'au::Quantity, int>::as, void>' requested here giga(hertz)(1).as(hertz); ^ ``` @@ -326,7 +462,8 @@ dimension. Then, figure out how to fix your expression so it has the right dime **Compiler error (clang 14)** ``` In file included from au/error_examples.cc:15: - In file included from ./au/au.hh:17: + In file included from au/code/au/au.hh:17: + In file included from au/code/au/chrono_interop.hh:17: In file included from external/llvm_14_toolchain_llvm/bin/../include/c++/v1/chrono:697: In file included from external/llvm_14_toolchain_llvm/bin/../include/c++/v1/__chrono/calendar.h:13: In file included from external/llvm_14_toolchain_llvm/bin/../include/c++/v1/__chrono/duration.h:14: @@ -334,13 +471,13 @@ dimension. Then, figure out how to fix your expression so it has the right dime external/llvm_14_toolchain_llvm/bin/../include/c++/v1/type_traits:2388:25: error: no type named 'type' in 'std::common_type, au::Quantity>' template using common_type_t = typename common_type<_Tp...>::type; ^~~~~ - ./au/quantity.hh:582:20: note: in instantiation of template type alias 'common_type_t' requested here + au/code/au/quantity.hh:625:20: note: in instantiation of template type alias 'common_type_t' requested here using C = std::common_type_t; ^ - ./au/quantity.hh:620:20: note: in instantiation of function template specialization 'au::detail::using_common_type, au::Quantity, au::detail::Plus>' requested here + au/code/au/quantity.hh:663:20: note: in instantiation of function template specialization 'au::detail::using_common_type, au::Quantity, au::detail::Plus>' requested here return detail::using_common_type(q1, q2, detail::plus); ^ - au/error_examples.cc:55:15: note: in instantiation of function template specialization 'au::operator+' requested here + au/error_examples.cc:69:15: note: in instantiation of function template specialization 'au::operator+' requested here meters(1) + seconds(1); ^ ``` @@ -348,18 +485,19 @@ dimension. Then, figure out how to fix your expression so it has the right dime **Compiler error (clang 11)** ``` In file included from au/error_examples.cc:15: - In file included from ./au/au.hh:17: + In file included from au/code/au/au.hh:17: + In file included from au/code/au/chrono_interop.hh:17: In file included from external/llvm_11_toolchain_llvm/bin/../include/c++/v1/chrono:828: external/llvm_11_toolchain_llvm/bin/../include/c++/v1/type_traits:2462:25: error: no type named 'type' in 'std::__1::common_type, au::Quantity>' template using common_type_t = typename common_type<_Tp...>::type; ^~~~~ - ./au/quantity.hh:582:20: note: in instantiation of template type alias 'common_type_t' requested here + au/code/au/quantity.hh:625:20: note: in instantiation of template type alias 'common_type_t' requested here using C = std::common_type_t; ^ - ./au/quantity.hh:620:20: note: in instantiation of function template specialization 'au::detail::using_common_type, au::Quantity, au::detail::Plus>' requested here + au/code/au/quantity.hh:663:20: note: in instantiation of function template specialization 'au::detail::using_common_type, au::Quantity, au::detail::Plus>' requested here return detail::using_common_type(q1, q2, detail::plus); ^ - au/error_examples.cc:55:15: note: in instantiation of function template specialization 'au::operator+' requested here + au/error_examples.cc:69:15: note: in instantiation of function template specialization 'au::operator+' requested here meters(1) + seconds(1); ^ ``` @@ -368,26 +506,26 @@ dimension. Then, figure out how to fix your expression so it has the right dime ``` In file included from external/sysroot_x86_64//include/c++/10.3.0/ratio:39, from external/sysroot_x86_64//include/c++/10.3.0/chrono:39, - from ./au/au.hh:17, + from au/code/au/chrono_interop.hh:17, + from au/code/au/au.hh:17, from au/error_examples.cc:15: external/sysroot_x86_64//include/c++/10.3.0/type_traits: In substitution of 'template using common_type_t = typename std::common_type::type [with _Tp = {au::Quantity, au::Quantity}]': - ./au/quantity.hh:582:11: required from 'constexpr auto au::detail::using_common_type(T, U, Func) [with T = au::Quantity; U = au::Quantity; Func = au::detail::Plus]' - ./au/quantity.hh:620:37: required from 'constexpr auto au::operator+(au::Quantity, au::Quantity) [with U1 = au::Meters; U2 = au::Seconds; R1 = int; R2 = int]' - au/error_examples.cc:55:26: required from here + au/code/au/quantity.hh:625:11: required from 'constexpr auto au::detail::using_common_type(T, U, Func) [with T = au::Quantity; U = au::Quantity; Func = au::detail::Plus]' + au/code/au/quantity.hh:663:37: required from 'constexpr auto au::operator+(au::Quantity, au::Quantity) [with U1 = au::Meters; U2 = au::Seconds; R1 = int; R2 = int]' + au/error_examples.cc:69:26: required from here external/sysroot_x86_64//include/c++/10.3.0/type_traits:2562:11: error: no type named 'type' in 'struct std::common_type, au::Quantity >' 2562 | using common_type_t = typename common_type<_Tp...>::type; | ^~~~~~~~~~~~~ - In file included from ./au/math.hh:22, - from ./au/au.hh:19, + In file included from au/code/au/prefix.hh:18, + from au/code/au/chrono_interop.hh:20, + from au/code/au/au.hh:17, from au/error_examples.cc:15: - ./au/quantity.hh: In instantiation of 'constexpr auto au::detail::using_common_type(T, U, Func) [with T = au::Quantity; U = au::Quantity; Func = au::detail::Plus]': - ./au/quantity.hh:620:37: required from 'constexpr auto au::operator+(au::Quantity, au::Quantity) [with U1 = au::Meters; U2 = au::Seconds; R1 = int; R2 = int]' - au/error_examples.cc:55:26: required from here - ./au/quantity.hh:584:94: error: no type named 'type' in 'struct std::common_type, au::Quantity >' - 584 | std::is_same>::value, + au/code/au/quantity.hh: In instantiation of 'constexpr auto au::detail::using_common_type(T, U, Func) [with T = au::Quantity; U = au::Quantity; Func = au::detail::Plus]': + au/code/au/quantity.hh:663:37: required from 'constexpr auto au::operator+(au::Quantity, au::Quantity) [with U1 = au::Meters; U2 = au::Seconds; R1 = int; R2 = int]' + au/error_examples.cc:69:26: required from here + au/code/au/quantity.hh:627:94: error: no type named 'type' in 'struct std::common_type, au::Quantity >' + 627 | std::is_same>::value, | ^~~~~ - ./au/quantity.hh: In instantiation of 'static constexpr void au::Quantity::warn_if_integer_division() [with OtherRep = int; UnitT = au::Meters; RepT = int]': - ./au/quantity.hh:348:43: required from here ``` **Compiler error (MSVC 2019 x64)** @@ -398,143 +536,147 @@ dimension. Then, figure out how to fix your expression so it has the right dime T=au::Quantity, U=au::Quantity ] - D:\a\au\au\au.hh(3365): note: see reference to alias template instantiation 'std::common_type_t,U>' being compiled + D:\a\au\au\au.hh(4493): note: see reference to alias template instantiation 'std::common_type_t,U>' being compiled with [ U=au::Quantity ] - D:\a\au\au\au.hh(3403): note: see reference to function template instantiation 'auto au::detail::using_common_type,au::Quantity,au::detail::Plus>(T,U,Func)' being compiled + D:\a\au\au\au.hh(4531): note: see reference to function template instantiation 'auto au::detail::using_common_type,au::Quantity,au::detail::Plus>(T,U,Func)' being compiled with [ T=au::Quantity, U=au::Quantity, Func=au::detail::Plus ] - error_examples.cc(56): note: see reference to function template instantiation 'auto au::operator +(au::Quantity,au::Quantity)' being compiled - D:\a\au\au\au.hh(3365): error C2938: 'std::common_type_t' : Failed to specialize alias template - D:\a\au\au\au.hh(3367): error C2057: expected constant expression - D:\a\au\au\au.hh(3252): error C2668: 'au::Quantity::as': ambiguous call to overloaded function - D:\a\au\au\au.hh(2943): note: could be 'auto au::Quantity::as::value,void>::type>(NewUnit) const' + error_examples.cc(70): note: see reference to function template instantiation 'auto au::operator +(au::Quantity,au::Quantity)' being compiled + D:\a\au\au\au.hh(4493): error C2938: 'std::common_type_t' : Failed to specialize alias template + D:\a\au\au\au.hh(4495): error C2057: expected constant expression + D:\a\au\au\au.hh(4367): error C2668: 'au::Quantity::as': ambiguous call to overloaded function + D:\a\au\au\au.hh(4023): note: could be 'auto au::Quantity::as::type>::value,void>::type>(NewUnit) const' with [ NewRep=TargetUnit::Rep, NewUnit=TargetUnit::Rep ] - D:\a\au\au\au.hh(2928): note: or 'auto au::Quantity::as(NewUnit) const' + D:\a\au\au\au.hh(4013): note: or 'auto au::Quantity::as(NewUnit) const' with [ NewRep=TargetUnit::Rep, Unit=au::Meters, NewUnit=au::Meters ] - D:\a\au\au\au.hh(3252): note: while trying to match the argument list '(Unit)' + D:\a\au\au\au.hh(4367): note: while trying to match the argument list '(Unit)' with [ Unit=au::Meters ] - D:\a\au\au\au.hh(3360): note: see reference to function template instantiation 'auto au::rep_cast(au::Quantity)' being compiled - D:\a\au\au\au.hh(3370): note: see reference to function template instantiation 'auto au::detail::cast_to_common_type(au::Quantity)' being compiled - D:\a\au\au\au.hh(3252): error C2668: 'au::Quantity::as': ambiguous call to overloaded function - D:\a\au\au\au.hh(2943): note: could be 'auto au::Quantity::as::value,void>::type>(NewUnit) const' + D:\a\au\au\au.hh(4488): note: see reference to function template instantiation 'auto au::rep_cast(au::Quantity)' being compiled + D:\a\au\au\au.hh(4498): note: see reference to function template instantiation 'auto au::detail::cast_to_common_type(au::Quantity)' being compiled + D:\a\au\au\au.hh(4367): error C2668: 'au::Quantity::as': ambiguous call to overloaded function + D:\a\au\au\au.hh(4023): note: could be 'auto au::Quantity::as::type>::value,void>::type>(NewUnit) const' with [ NewRep=TargetUnit::Rep, NewUnit=TargetUnit::Rep ] - D:\a\au\au\au.hh(2928): note: or 'auto au::Quantity::as(NewUnit) const' + D:\a\au\au\au.hh(4013): note: or 'auto au::Quantity::as(NewUnit) const' with [ NewRep=TargetUnit::Rep, Unit=au::Seconds, NewUnit=au::Seconds ] - D:\a\au\au\au.hh(3252): note: while trying to match the argument list '(Unit)' + D:\a\au\au\au.hh(4367): note: while trying to match the argument list '(Unit)' with [ Unit=au::Seconds ] - D:\a\au\au\au.hh(3360): note: see reference to function template instantiation 'auto au::rep_cast(au::Quantity)' being compiled - D:\a\au\au\au.hh(3370): note: see reference to function template instantiation 'auto au::detail::cast_to_common_type(au::Quantity)' being compiled - D:\a\au\au\au.hh(3370): error C2672: 'operator __surrogate_func': no matching overloaded function found - D:\a\au\au\au.hh(3370): error C2893: Failed to specialize function template 'auto au::detail::Plus::operator ()(const T &,const U &) const' - D:\a\au\au\au.hh(727): note: see declaration of 'au::detail::Plus::operator ()' - D:\a\au\au\au.hh(3370): note: With the following template arguments: - D:\a\au\au\au.hh(3370): note: 'T=void' - D:\a\au\au\au.hh(3370): note: 'U=void' + D:\a\au\au\au.hh(4488): note: see reference to function template instantiation 'auto au::rep_cast(au::Quantity)' being compiled + D:\a\au\au\au.hh(4498): note: see reference to function template instantiation 'auto au::detail::cast_to_common_type(au::Quantity)' being compiled + D:\a\au\au\au.hh(4498): error C2672: 'operator __surrogate_func': no matching overloaded function found + D:\a\au\au\au.hh(4498): error C2893: Failed to specialize function template 'auto au::detail::Plus::operator ()(const T &,const U &) const' + D:\a\au\au\au.hh(954): note: see declaration of 'au::detail::Plus::operator ()' + D:\a\au\au\au.hh(4498): note: With the following template arguments: + D:\a\au\au\au.hh(4498): note: 'T=void' + D:\a\au\au\au.hh(4498): note: 'U=void' ``` **Compiler error (MSVC 2022 x64)** ``` - C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.36.32532\include\type_traits(1227): error C2794: 'type': is not a member of any direct or indirect base class of 'std::common_type' + C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.41.34120\include\type_traits(1334): error C2794: 'type': is not a member of any direct or indirect base class of 'std::common_type' with [ T=au::Quantity, U=au::Quantity ] - D:\a\au\au\au.hh(3365): note: see reference to alias template instantiation 'std::common_type_t' being compiled + C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.41.34120\include\type_traits(1334): note: the template instantiation context (the oldest one first) is + error_examples.cc(70): note: see reference to function template instantiation 'auto au::operator +(au::Quantity,au::Quantity)' being compiled + D:\a\au\au\au.hh(4531): note: see reference to function template instantiation 'auto au::detail::using_common_type,au::Quantity,au::detail::Plus>(T,U,Func)' being compiled with [ T=au::Quantity, - U=au::Quantity + U=au::Quantity, + Func=au::detail::Plus ] - D:\a\au\au\au.hh(3403): note: see reference to function template instantiation 'auto au::detail::using_common_type,au::Quantity,au::detail::Plus>(T,U,Func)' being compiled + D:\a\au\au\au.hh(4493): note: see reference to alias template instantiation 'std::common_type_t' being compiled with [ T=au::Quantity, - U=au::Quantity, - Func=au::detail::Plus + U=au::Quantity ] - error_examples.cc(56): note: see reference to function template instantiation 'auto au::operator +(au::Quantity,au::Quantity)' being compiled - D:\a\au\au\au.hh(3365): error C2938: 'std::common_type_t' : Failed to specialize alias template - D:\a\au\au\au.hh(3367): error C2057: expected constant expression - D:\a\au\au\au.hh(3252): error C2668: 'au::Quantity::as': ambiguous call to overloaded function - D:\a\au\au\au.hh(2943): note: could be 'auto au::Quantity::as::value,void>::type>(NewUnit) const' + D:\a\au\au\au.hh(4493): error C2938: 'std::common_type_t' : Failed to specialize alias template + D:\a\au\au\au.hh(4495): error C2057: expected constant expression + D:\a\au\au\au.hh(4367): error C2668: 'au::Quantity::as': ambiguous call to overloaded function + D:\a\au\au\au.hh(4023): note: could be 'auto au::Quantity::as::type>::value,void>::type>(NewUnit) const' with [ NewRep=TargetUnit::Rep, NewUnit=TargetUnit::Rep ] - D:\a\au\au\au.hh(2928): note: or 'auto au::Quantity::as(NewUnit) const' + D:\a\au\au\au.hh(4013): note: or 'auto au::Quantity::as(NewUnit) const' with [ NewRep=TargetUnit::Rep, Unit=au::Meters, NewUnit=au::Meters ] - D:\a\au\au\au.hh(3252): note: while trying to match the argument list '(Unit)' + D:\a\au\au\au.hh(4367): note: while trying to match the argument list '(Unit)' with [ Unit=au::Meters ] - D:\a\au\au\au.hh(3360): note: see reference to function template instantiation 'auto au::rep_cast(au::Quantity)' being compiled - D:\a\au\au\au.hh(3370): note: see reference to function template instantiation 'auto au::detail::cast_to_common_type(au::Quantity)' being compiled - D:\a\au\au\au.hh(3252): error C2668: 'au::Quantity::as': ambiguous call to overloaded function - D:\a\au\au\au.hh(2943): note: could be 'auto au::Quantity::as::value,void>::type>(NewUnit) const' + D:\a\au\au\au.hh(4367): note: the template instantiation context (the oldest one first) is + D:\a\au\au\au.hh(4498): note: see reference to function template instantiation 'auto au::detail::cast_to_common_type(au::Quantity)' being compiled + D:\a\au\au\au.hh(4488): note: see reference to function template instantiation 'auto au::rep_cast(au::Quantity)' being compiled + D:\a\au\au\au.hh(4367): error C2668: 'au::Quantity::as': ambiguous call to overloaded function + D:\a\au\au\au.hh(4023): note: could be 'auto au::Quantity::as::type>::value,void>::type>(NewUnit) const' with [ NewRep=TargetUnit::Rep, NewUnit=TargetUnit::Rep ] - D:\a\au\au\au.hh(2928): note: or 'auto au::Quantity::as(NewUnit) const' + D:\a\au\au\au.hh(4013): note: or 'auto au::Quantity::as(NewUnit) const' with [ NewRep=TargetUnit::Rep, Unit=au::Seconds, NewUnit=au::Seconds ] - D:\a\au\au\au.hh(3252): note: while trying to match the argument list '(Unit)' + D:\a\au\au\au.hh(4367): note: while trying to match the argument list '(Unit)' with [ Unit=au::Seconds ] - D:\a\au\au\au.hh(3360): note: see reference to function template instantiation 'auto au::rep_cast(au::Quantity)' being compiled - D:\a\au\au\au.hh(3370): note: see reference to function template instantiation 'auto au::detail::cast_to_common_type(au::Quantity)' being compiled - D:\a\au\au\au.hh(3370): error C3889: call to object of class type 'au::detail::Plus': no matching call operator found - D:\a\au\au\au.hh(727): note: could be 'auto au::detail::Plus::operator ()(const T &,const U &) const' - D:\a\au\au\au.hh(3370): note: Failed to specialize function template 'auto au::detail::Plus::operator ()(const T &,const U &) const' - D:\a\au\au\au.hh(3370): note: With the following template arguments: - D:\a\au\au\au.hh(3370): note: 'T=void' - D:\a\au\au\au.hh(3370): note: 'U=void' + D:\a\au\au\au.hh(4367): note: the template instantiation context (the oldest one first) is + D:\a\au\au\au.hh(4498): note: see reference to function template instantiation 'auto au::detail::cast_to_common_type(au::Quantity)' being compiled + D:\a\au\au\au.hh(4488): note: see reference to function template instantiation 'auto au::rep_cast(au::Quantity)' being compiled + D:\a\au\au\au.hh(4498): error C3889: call to object of class type 'au::detail::Plus': no matching call operator found + D:\a\au\au\au.hh(954): note: could be 'auto au::detail::Plus::operator ()(const T &,const U &) const' + D:\a\au\au\au.hh(4498): note: Failed to specialize function template 'auto au::detail::Plus::operator ()(const T &,const U &) const' + D:\a\au\au\au.hh(4498): note: With the following template arguments: + D:\a\au\au\au.hh(4498): note: 'T=void' + D:\a\au\au\au.hh(4498): note: 'U=void' + D:\a\au\au\au.hh(4498): note: you cannot create a reference to 'void' ``` ## Integer division forbidden {#integer-division-forbidden} @@ -544,8 +686,8 @@ try to prevent wrong code that _looks_ correct from compiling. It turns out to use integral Reps without noticing, and thus to get integer division without noticing. This can lead to very large errors. -**Solution:** If you _really wanted_ integer division, call `integer_quotient()`. Otherwise, use -floating point types. +**Solution:** If you _really wanted_ integer division, wrap the denominator in `unblock_int_div()`. +Otherwise, use floating point types. !!! example @@ -565,25 +707,26 @@ floating point types. QuantityD t = meters(60.0) / (miles / hour)(65.0); ``` - === "Fixed (2. `integer_quotient()`)" + === "Fixed (2. `unblock_int_div()`)" ```cpp // (FIXED): 2. Integer result == (meter * hours / mile)(0) - auto t = integer_quotient(meters(60), (miles / hour)(65)); + auto t = meters(60) / unblock_int_div((miles / hour)(65)); ``` **Compiler error (clang 14)** ``` In file included from au/error_examples.cc:15: - In file included from ./au/au.hh:19: - In file included from ./au/math.hh:22: - ./au/quantity.hh:415:9: error: static_assert failed due to requirement '!uses_integer_division' "Integer division forbidden: use integer_quotient() if you really want it" - static_assert(!uses_integer_division, - ^ ~~~~~~~~~~~~~~~~~~~~~~ - ./au/quantity.hh:348:9: note: in instantiation of function template specialization 'au::Quantity::warn_if_integer_division' requested here - warn_if_integer_division(); + In file included from au/code/au/au.hh:17: + In file included from au/code/au/chrono_interop.hh:20: + In file included from au/code/au/prefix.hh:18: + au/code/au/quantity.hh:395:9: error: static_assert failed due to requirement 'are_units_quantity_equivalent || !uses_integer_division' "Integer division forbidden: wrap denominator in `unblock_int_div()` if you really want it" + static_assert(are_units_quantity_equivalent || !uses_integer_division, + ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + au/code/au/quantity.hh:325:9: note: in instantiation of function template specialization 'au::Quantity::warn_if_integer_division>, int>' requested here + warn_if_integer_division(); ^ - au/error_examples.cc:63:39: note: in instantiation of function template specialization 'au::Quantity::operator/>, int>' requested here + au/error_examples.cc:77:39: note: in instantiation of function template specialization 'au::Quantity::operator/>, int>' requested here QuantityD t = meters(60) / (miles / hour)(65); ^ ``` @@ -591,41 +734,46 @@ floating point types. **Compiler error (clang 11)** ``` In file included from au/error_examples.cc:15: - In file included from ./au/au.hh:19: - In file included from ./au/math.hh:22: - ./au/quantity.hh:415:9: error: static_assert failed due to requirement '!uses_integer_division' "Integer division forbidden: use integer_quotient() if you really want it" - static_assert(!uses_integer_division, - ^ ~~~~~~~~~~~~~~~~~~~~~~ - ./au/quantity.hh:348:9: note: in instantiation of function template specialization 'au::Quantity::warn_if_integer_division' requested here - warn_if_integer_division(); + In file included from au/code/au/au.hh:17: + In file included from au/code/au/chrono_interop.hh:20: + In file included from au/code/au/prefix.hh:18: + au/code/au/quantity.hh:395:9: error: static_assert failed due to requirement 'are_units_quantity_equivalent || !uses_integer_division' "Integer division forbidden: wrap denominator in `unblock_int_div()` if you really want it" + static_assert(are_units_quantity_equivalent || !uses_integer_division, + ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + au/code/au/quantity.hh:325:9: note: in instantiation of function template specialization 'au::Quantity::warn_if_integer_division>, int>' requested here + warn_if_integer_division(); ^ - au/error_examples.cc:63:39: note: in instantiation of function template specialization 'au::Quantity::operator/>, int>' requested here + au/error_examples.cc:77:39: note: in instantiation of function template specialization 'au::Quantity::operator/>, int>' requested here QuantityD t = meters(60) / (miles / hour)(65); ^ ``` **Compiler error (gcc 10)** ``` - au/error_examples.cc:63:58: in 'constexpr' expansion of 'au::meters.au::QuantityMaker::operator()(60).au::Quantity::operator/ >, int>(au::miles.au::QuantityMaker::operator/((au::hour, const au::SingularNameFor())).au::QuantityMaker > >::operator()(65))' - ./au/quantity.hh:415:23: error: static assertion failed: Integer division forbidden: use integer_quotient() if you really want it - 415 | static_assert(!uses_integer_division, - | ^~~~~~~~~~~~~~~~~~~~~~ + au/code/au/quantity.hh: In instantiation of 'static constexpr void au::Quantity::warn_if_integer_division() [with OtherUnit = au::UnitProduct >; OtherRep = int; UnitT = au::Meters; RepT = int]': + au/code/au/quantity.hh:325:54: required from here + au/error_examples.cc:77:58: in 'constexpr' expansion of 'au::meters.au::QuantityMaker::operator()(60).au::Quantity::operator/ >, int>(au::miles.au::QuantityMaker::operator/((au::hour, const au::SingularNameFor())).au::QuantityMaker > >::operator()(65))' + au/code/au/quantity.hh:395:53: error: static assertion failed: Integer division forbidden: wrap denominator in `unblock_int_div()` if you really want it + 395 | static_assert(are_units_quantity_equivalent || !uses_integer_division, + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~ ``` **Compiler error (MSVC 2019 x64)** ``` - D:\a\au\au\au.hh(3198): error C2338: Integer division forbidden: use integer_quotient() if you really want it - D:\a\au\au\au.hh(3131): note: see reference to function template instantiation 'void au::Quantity::warn_if_integer_division(void)' being compiled + D:\a\au\au\au.hh(4263): error C2338: Integer division forbidden: wrap denominator in `unblock_int_div()` if you really want it + D:\a\au\au\au.hh(4193): note: see reference to function template instantiation 'void au::Quantity::warn_if_integer_division(void)' being compiled with [ + OtherUnit=au::UnitProduct>, OtherRep=int ] - D:\a\au\au\au.hh(3131): note: see reference to function template instantiation 'void au::Quantity::warn_if_integer_division(void)' being compiled + D:\a\au\au\au.hh(4193): note: see reference to function template instantiation 'void au::Quantity::warn_if_integer_division(void)' being compiled with [ + OtherUnit=au::UnitProduct>, OtherRep=int ] - error_examples.cc(64): note: see reference to function template instantiation 'au::Quantity,au::Hours>,int> au::Quantity::operator />,int>(au::Quantity>,int>) const' being compiled + error_examples.cc(78): note: see reference to function template instantiation 'au::Quantity,au::Hours>,int> au::Quantity::operator />,int>(au::Quantity>,int>) const' being compiled with [ T=au::Meters, @@ -635,17 +783,19 @@ floating point types. **Compiler error (MSVC 2022 x64)** ``` - D:\a\au\au\au.hh(3198): error C2338: static_assert failed: 'Integer division forbidden: use integer_quotient() if you really want it' - D:\a\au\au\au.hh(3131): note: see reference to function template instantiation 'void au::Quantity::warn_if_integer_division(void)' being compiled + D:\a\au\au\au.hh(4263): error C2338: static_assert failed: 'Integer division forbidden: wrap denominator in `unblock_int_div()` if you really want it' + D:\a\au\au\au.hh(4263): note: the template instantiation context (the oldest one first) is + error_examples.cc(78): note: see reference to function template instantiation 'au::Quantity,au::Hours>,int> au::Quantity::operator />,int>(au::Quantity>,int>) const' being compiled with [ - OtherRep=int + T=au::Meters, + B=au::Miles ] - error_examples.cc(64): note: see reference to function template instantiation 'au::Quantity,au::Hours>,int> au::Quantity::operator />,int>(au::Quantity>,int>) const' being compiled + D:\a\au\au\au.hh(4193): note: see reference to function template instantiation 'void au::Quantity::warn_if_integer_division(void)' being compiled with [ - T=au::Meters, - B=au::Miles + OtherUnit=au::UnitProduct>, + OtherRep=int ] ``` @@ -697,14 +847,14 @@ use a smaller target unit. **Compiler error (clang 14)** ``` In file included from au/error_examples.cc:15: - In file included from ./au/au.hh:19: - ./au/math.hh:251:5: error: static_assert failed due to requirement 'make_quantity>(int{1}).in(associated_unit(target_units) * au::Hertz{}) >= threshold || std::is_floating_point::value' "Dangerous inversion risking truncation to 0; must supply explicit Rep if truly desired" + In file included from au/code/au/au.hh:19: + au/code/au/math.hh:278:5: error: static_assert failed due to requirement 'UNITY.in(associated_unit(target_units) * au::Hertz{}) >= threshold || std::is_floating_point::value' "Dangerous inversion risking truncation to 0; must supply explicit Rep if truly desired" static_assert( ^ - ./au/math.hh:267:56: note: in instantiation of function template specialization 'au::inverse_in, au::Hertz, int>' requested here + au/code/au/math.hh:294:56: note: in instantiation of function template specialization 'au::inverse_in, au::Hertz, int>' requested here return make_quantity>(inverse_in(target_units, q)); ^ - au/error_examples.cc:71:5: note: in instantiation of function template specialization 'au::inverse_as, au::Hertz, int>' requested here + au/error_examples.cc:85:5: note: in instantiation of function template specialization 'au::inverse_as, au::Hertz, int>' requested here inverse_as(seconds, hertz(5)); ^ ``` @@ -712,41 +862,41 @@ use a smaller target unit. **Compiler error (clang 11)** ``` In file included from au/error_examples.cc:15: - In file included from ./au/au.hh:19: - ./au/math.hh:251:5: error: static_assert failed due to requirement 'make_quantity>(int{1}).in(associated_unit(target_units) * au::Hertz{}) >= threshold || std::is_floating_point::value' "Dangerous inversion risking truncation to 0; must supply explicit Rep if truly desired" + In file included from au/code/au/au.hh:19: + au/code/au/math.hh:278:5: error: static_assert failed due to requirement 'UNITY.in(associated_unit(target_units) * au::Hertz{}) >= threshold || std::is_floating_point::value' "Dangerous inversion risking truncation to 0; must supply explicit Rep if truly desired" static_assert( ^ - ./au/math.hh:267:56: note: in instantiation of function template specialization 'au::inverse_in, au::Hertz, int>' requested here + au/code/au/math.hh:294:56: note: in instantiation of function template specialization 'au::inverse_in, au::Hertz, int>' requested here return make_quantity>(inverse_in(target_units, q)); ^ - au/error_examples.cc:71:5: note: in instantiation of function template specialization 'au::inverse_as, au::Hertz, int>' requested here + au/error_examples.cc:85:5: note: in instantiation of function template specialization 'au::inverse_as, au::Hertz, int>' requested here inverse_as(seconds, hertz(5)); ^ ``` **Compiler error (gcc 10)** ``` - In file included from ./au/au.hh:19, + In file included from au/code/au/au.hh:19, from au/error_examples.cc:15: - ./au/math.hh: In instantiation of 'constexpr auto au::inverse_in(TargetUnits, au::Quantity) [with TargetUnits = au::QuantityMaker; U = au::Hertz; R = int]': - ./au/math.hh:267:66: required from 'constexpr auto au::inverse_as(TargetUnits, au::Quantity) [with TargetUnits = au::QuantityMaker; U = au::Hertz; R = int]' - au/error_examples.cc:71:33: required from here - ./au/math.hh:252:98: error: static assertion failed: Dangerous inversion risking truncation to 0; must supply explicit Rep if truly desired - 252 | make_quantity>(R{1}).in(associated_unit(target_units) * U{}) >= threshold || - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~ - 253 | std::is_floating_point::value, - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + au/code/au/math.hh: In instantiation of 'constexpr auto au::inverse_in(TargetUnits, au::Quantity) [with TargetUnits = au::QuantityMaker; U = au::Hertz; R = int]': + au/code/au/math.hh:294:66: required from 'constexpr auto au::inverse_as(TargetUnits, au::Quantity) [with TargetUnits = au::QuantityMaker; U = au::Hertz; R = int]' + au/error_examples.cc:85:33: required from here + au/code/au/math.hh:279:71: error: static assertion failed: Dangerous inversion risking truncation to 0; must supply explicit Rep if truly desired + 279 | UNITY.in(associated_unit(target_units) * U{}) >= threshold || + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~ + 280 | std::is_floating_point::value, + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` **Compiler error (MSVC 2019 x64)** ``` - D:\a\au\au\au.hh(4562): error C2338: Dangerous inversion risking truncation to 0; must supply explicit Rep if truly desired - D:\a\au\au\au.hh(4577): note: see reference to function template instantiation 'auto au::inverse_in(TargetUnits,au::Quantity)' being compiled + D:\a\au\au\au.hh(6120): error C2338: Dangerous inversion risking truncation to 0; must supply explicit Rep if truly desired + D:\a\au\au\au.hh(6135): note: see reference to function template instantiation 'auto au::inverse_in(TargetUnits,au::Quantity)' being compiled with [ TargetUnits=au::QuantityMaker ] - error_examples.cc(72): note: see reference to function template instantiation 'auto au::inverse_as,au::Hertz,int>(TargetUnits,au::Quantity)' being compiled + error_examples.cc(86): note: see reference to function template instantiation 'auto au::inverse_as,au::Hertz,int>(TargetUnits,au::Quantity)' being compiled with [ TargetUnits=au::QuantityMaker @@ -755,13 +905,14 @@ use a smaller target unit. **Compiler error (MSVC 2022 x64)** ``` - D:\a\au\au\au.hh(4562): error C2338: static_assert failed: 'Dangerous inversion risking truncation to 0; must supply explicit Rep if truly desired' - D:\a\au\au\au.hh(4577): note: see reference to function template instantiation 'auto au::inverse_in(TargetUnits,au::Quantity)' being compiled + D:\a\au\au\au.hh(6120): error C2338: static_assert failed: 'Dangerous inversion risking truncation to 0; must supply explicit Rep if truly desired' + D:\a\au\au\au.hh(6120): note: the template instantiation context (the oldest one first) is + error_examples.cc(86): note: see reference to function template instantiation 'auto au::inverse_as,au::Hertz,int>(TargetUnits,au::Quantity)' being compiled with [ TargetUnits=au::QuantityMaker ] - error_examples.cc(72): note: see reference to function template instantiation 'auto au::inverse_as,au::Hertz,int>(TargetUnits,au::Quantity)' being compiled + D:\a\au\au\au.hh(6135): note: see reference to function template instantiation 'auto au::inverse_in(TargetUnits,au::Quantity)' being compiled with [ TargetUnits=au::QuantityMaker @@ -819,14 +970,14 @@ casting automatically when possible. **Compiler error (clang 14)** ``` - au/error_examples.cc:79:34: error: deduced conflicting types ('Quantity::Unit, [...]>' vs 'Quantity>::Unit, [...]>') for initializer list element type + au/error_examples.cc:93:34: error: deduced conflicting types ('Quantity::Unit, [...]>' vs 'Quantity>::Unit, [...]>') for initializer list element type for (const auto &frequency : { ^ ``` **Compiler error (clang 11)** ``` - au/error_examples.cc:79:34: error: deduced conflicting types ('Quantity' vs 'Quantity, [...]>') for initializer list element type + au/error_examples.cc:93:34: error: deduced conflicting types ('Quantity' vs 'Quantity, [...]>') for initializer list element type for (const auto &frequency : { ^ ``` @@ -834,19 +985,19 @@ casting automatically when possible. **Compiler error (gcc 10)** ``` au/error_examples.cc: In function 'void au::example_deduced_conflicting_types()': - au/error_examples.cc:82:10: error: unable to deduce 'std::initializer_list&&' from '{au::hertz.au::QuantityMaker::operator()(1.0e+0), au::operator/(1, au::seconds.au::QuantityMaker::operator()(2.0e+0))}' - 82 | }) { + au/error_examples.cc:96:10: error: unable to deduce 'std::initializer_list&&' from '{au::hertz.au::QuantityMaker::operator()(1.0e+0), au::operator/(1, au::seconds.au::QuantityMaker::operator()(2.0e+0))}' + 96 | }) { | ^ - au/error_examples.cc:82:10: note: deduced conflicting types for parameter 'auto' ('au::Quantity' and 'au::Quantity, double>') + au/error_examples.cc:96:10: note: deduced conflicting types for parameter 'auto' ('au::Quantity' and 'au::Quantity, double>') ``` **Compiler error (MSVC 2019 x64)** ``` - error_examples.cc(80): error C3535: cannot deduce type for 'auto &&' from 'initializer list' - error_examples.cc(80): error C2440: 'initializing': cannot convert from 'initializer list' to 'std::initializer_list &&' - error_examples.cc(83): note: Reason: cannot convert from 'initializer list' to 'std::initializer_list' - error_examples.cc(80): note: Element '1': no conversion from 'au::Quantity' to 'int' - error_examples.cc(80): note: Element '2': no conversion from 'au::Quantity,T>' to 'int' + error_examples.cc(94): error C3535: cannot deduce type for 'auto &&' from 'initializer list' + error_examples.cc(94): error C2440: 'initializing': cannot convert from 'initializer list' to 'std::initializer_list &&' + error_examples.cc(97): note: Reason: cannot convert from 'initializer list' to 'std::initializer_list' + error_examples.cc(94): note: Element '1': no conversion from 'au::Quantity' to 'int' + error_examples.cc(94): note: Element '2': no conversion from 'au::Quantity,T>' to 'int' with [ B=au::Seconds, @@ -856,11 +1007,11 @@ casting automatically when possible. **Compiler error (MSVC 2022 x64)** ``` - error_examples.cc(80): error C3535: cannot deduce type for 'auto &&' from 'initializer list' - error_examples.cc(80): error C2440: 'initializing': cannot convert from 'initializer list' to 'std::initializer_list &&' - error_examples.cc(80): note: Reason: cannot convert from 'initializer list' to 'std::initializer_list' - error_examples.cc(80): note: Element '1': no conversion from 'au::Quantity' to 'int' - error_examples.cc(80): note: Element '2': no conversion from 'au::Quantity,T>' to 'int' + error_examples.cc(94): error C3535: cannot deduce type for 'auto &&' from 'initializer list' + error_examples.cc(94): error C2440: 'initializing': cannot convert from 'initializer list' to 'std::initializer_list &&' + error_examples.cc(94): note: Reason: cannot convert from 'initializer list' to 'std::initializer_list' + error_examples.cc(94): note: Element '1': no conversion from 'au::Quantity' to 'int' + error_examples.cc(94): note: Element '2': no conversion from 'au::Quantity,T>' to 'int' with [ B=au::Seconds, @@ -960,37 +1111,39 @@ ordering! **Compiler error (clang 14)** ``` In file included from au/error_examples.cc:15: - In file included from ./au/au.hh:19: - In file included from ./au/math.hh:22: - In file included from ./au/quantity.hh:19: - In file included from ./au/conversion_policy.hh:19: - In file included from ./au/magnitude.hh:19: - ./au/packs.hh:287:5: error: static_assert failed due to requirement 'std::is_same::value' "Broken strict total ordering: distinct input types compare equal" + In file included from au/code/au/au.hh:17: + In file included from au/code/au/chrono_interop.hh:20: + In file included from au/code/au/prefix.hh:18: + In file included from au/code/au/quantity.hh:19: + In file included from au/code/au/apply_magnitude.hh:17: + In file included from au/code/au/apply_rational_magnitude_to_integral.hh:19: + In file included from au/code/au/magnitude.hh:21: + au/code/au/packs.hh:287:5: error: static_assert failed due to requirement 'std::is_same::value' "Broken strict total ordering: distinct input types compare equal" static_assert(std::is_same::value, ^ ~~~~~~~~~~~~~~~~~~~~~~~~~ - ./au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here + au/code/au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here std::conditional_t< ^ - ./au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here - ./au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here - ./au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here - ./au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here - ./au/unit_of_measure.hh:860:40: note: (skipping 8 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all) + au/code/au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here + au/code/au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here + au/code/au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here + au/code/au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here + au/code/au/unit_of_measure.hh:920:40: note: (skipping 8 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all) struct InOrderFor : LexicographicTotalOrdering, au::Quantity>' requested here + au/code/au/quantity.hh:762:7: note: in instantiation of template class 'au::CommonQuantity, au::Quantity>' requested here : au::CommonQuantity, au::Quantity> {}; ^ external/llvm_14_toolchain_llvm/bin/../include/c++/v1/type_traits:2388:25: note: in instantiation of template class 'std::common_type, au::Quantity>' requested here template using common_type_t = typename common_type<_Tp...>::type; ^ - ./au/quantity.hh:582:20: note: in instantiation of template type alias 'common_type_t' requested here + au/code/au/quantity.hh:625:20: note: in instantiation of template type alias 'common_type_t' requested here using C = std::common_type_t; ^ - ./au/quantity.hh:594:20: note: in instantiation of function template specialization 'au::detail::using_common_type, au::Quantity, au::detail::Equal>' requested here + au/code/au/quantity.hh:637:20: note: in instantiation of function template specialization 'au::detail::using_common_type, au::Quantity, au::detail::Equal>' requested here return detail::using_common_type(q1, q2, detail::equal); ^ - au/error_examples.cc:98:25: note: in instantiation of function template specialization 'au::operator==' requested here + au/error_examples.cc:112:25: note: in instantiation of function template specialization 'au::operator==' requested here if (quarterfeet(10) == trinches(10)) { ^ ``` @@ -998,294 +1151,387 @@ ordering! **Compiler error (clang 11)** ``` In file included from au/error_examples.cc:15: - In file included from ./au/au.hh:19: - In file included from ./au/math.hh:22: - In file included from ./au/quantity.hh:19: - In file included from ./au/conversion_policy.hh:19: - In file included from ./au/magnitude.hh:19: - ./au/packs.hh:287:5: error: static_assert failed due to requirement 'std::is_same::value' "Broken strict total ordering: distinct input types compare equal" + In file included from au/code/au/au.hh:17: + In file included from au/code/au/chrono_interop.hh:20: + In file included from au/code/au/prefix.hh:18: + In file included from au/code/au/quantity.hh:19: + In file included from au/code/au/apply_magnitude.hh:17: + In file included from au/code/au/apply_rational_magnitude_to_integral.hh:19: + In file included from au/code/au/magnitude.hh:21: + au/code/au/packs.hh:287:5: error: static_assert failed due to requirement 'std::is_same::value' "Broken strict total ordering: distinct input types compare equal" static_assert(std::is_same::value, ^ ~~~~~~~~~~~~~~~~~~~~~~~~~ - ./au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here + au/code/au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here std::conditional_t< ^ - ./au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here - ./au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here - ./au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here - ./au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here - ./au/unit_of_measure.hh:860:40: note: (skipping 8 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all) + au/code/au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here + au/code/au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here + au/code/au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here + au/code/au/packs.hh:303:5: note: in instantiation of template class 'au::LexicographicTotalOrdering' requested here + au/code/au/unit_of_measure.hh:920:40: note: (skipping 8 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all) struct InOrderFor : LexicographicTotalOrdering, au::Quantity, void>' requested here + au/code/au/quantity.hh:762:7: note: in instantiation of template class 'au::CommonQuantity, au::Quantity, void>' requested here : au::CommonQuantity, au::Quantity> {}; ^ external/llvm_11_toolchain_llvm/bin/../include/c++/v1/type_traits:2462:25: note: in instantiation of template class 'std::__1::common_type, au::Quantity>' requested here template using common_type_t = typename common_type<_Tp...>::type; ^ - ./au/quantity.hh:582:20: note: in instantiation of template type alias 'common_type_t' requested here + au/code/au/quantity.hh:625:20: note: in instantiation of template type alias 'common_type_t' requested here using C = std::common_type_t; ^ - ./au/quantity.hh:594:20: note: in instantiation of function template specialization 'au::detail::using_common_type, au::Quantity, au::detail::Equal>' requested here + au/code/au/quantity.hh:637:20: note: in instantiation of function template specialization 'au::detail::using_common_type, au::Quantity, au::detail::Equal>' requested here return detail::using_common_type(q1, q2, detail::equal); ^ - au/error_examples.cc:98:25: note: in instantiation of function template specialization 'au::operator==' requested here + au/error_examples.cc:112:25: note: in instantiation of function template specialization 'au::operator==' requested here if (quarterfeet(10) == trinches(10)) { ^ ``` **Compiler error (gcc 10)** ``` - In file included from ./au/magnitude.hh:19, - from ./au/conversion_policy.hh:19, - from ./au/quantity.hh:19, - from ./au/math.hh:22, - from ./au/au.hh:19, + In file included from au/code/au/magnitude.hh:21, + from au/code/au/apply_rational_magnitude_to_integral.hh:19, + from au/code/au/apply_magnitude.hh:17, + from au/code/au/quantity.hh:19, + from au/code/au/prefix.hh:18, + from au/code/au/chrono_interop.hh:20, + from au/code/au/au.hh:17, from au/error_examples.cc:15: - ./au/packs.hh: In instantiation of 'struct au::LexicographicTotalOrdering': - ./au/packs.hh:298:8: recursively required from 'struct au::LexicographicTotalOrdering' - ./au/packs.hh:298:8: required from 'struct au::LexicographicTotalOrdering' - ./au/unit_of_measure.hh:860:8: required from 'struct au::InOrderFor' - ./au/unit_of_measure.hh:494:8: required from 'struct au::InOrderFor' - ./au/packs.hh:383:8: required from 'struct au::FlatDedupedTypeList, au::CommonUnit >' - ./au/unit_of_measure.hh:532:8: required from 'struct au::ComputeCommonUnit' - ./au/quantity.hh:705:8: required from 'struct au::CommonQuantity, au::Quantity, void>' - ./au/quantity.hh:718:8: required from 'struct std::common_type, au::Quantity >' + au/code/au/packs.hh: In instantiation of 'struct au::LexicographicTotalOrdering': + au/code/au/packs.hh:298:8: recursively required from 'struct au::LexicographicTotalOrdering' + au/code/au/packs.hh:298:8: required from 'struct au::LexicographicTotalOrdering' + au/code/au/unit_of_measure.hh:920:8: required from 'struct au::InOrderFor' + au/code/au/unit_of_measure.hh:505:8: required from 'struct au::InOrderFor' + au/code/au/packs.hh:383:8: required from 'struct au::FlatDedupedTypeList, au::CommonUnit >' + au/code/au/unit_of_measure.hh:592:8: required from 'struct au::ComputeCommonUnit' + au/code/au/quantity.hh:748:8: required from 'struct au::CommonQuantity, au::Quantity, void>' + au/code/au/quantity.hh:761:8: required from 'struct std::common_type, au::Quantity >' external/sysroot_x86_64//include/c++/10.3.0/type_traits:2562:11: required by substitution of 'template using common_type_t = typename std::common_type::type [with _Tp = {au::Quantity, au::Quantity}]' - ./au/quantity.hh:582:11: required from 'constexpr auto au::detail::using_common_type(T, U, Func) [with T = au::Quantity; U = au::Quantity; Func = au::detail::Equal]' - ./au/quantity.hh:594:37: required from 'constexpr bool au::operator==(au::Quantity, au::Quantity) [with U1 = au::Quarterfeet; U2 = au::Trinches; R1 = int; R2 = int]' - au/error_examples.cc:98:39: required from here - ./au/packs.hh:287:39: error: static assertion failed: Broken strict total ordering: distinct input types compare equal + au/code/au/quantity.hh:625:11: required from 'constexpr auto au::detail::using_common_type(T, U, Func) [with T = au::Quantity; U = au::Quantity; Func = au::detail::Equal]' + au/code/au/quantity.hh:637:37: required from 'constexpr bool au::operator==(au::Quantity, au::Quantity) [with U1 = au::Quarterfeet; U2 = au::Trinches; R1 = int; R2 = int]' + au/error_examples.cc:112:39: required from here + au/code/au/packs.hh:287:39: error: static assertion failed: Broken strict total ordering: distinct input types compare equal 287 | static_assert(std::is_same::value, | ^~~~~ - ./au/packs.hh: In instantiation of 'struct au::LexicographicTotalOrdering': - ./au/packs.hh:298:8: required from 'struct au::LexicographicTotalOrdering' - ./au/unit_of_measure.hh:860:8: [ skipping 8 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ] - ./au/unit_of_measure.hh:444:8: required from 'struct au::HasSameDimension, au::Trinches>' - ./au/stdx/type_traits.hh:38:61: required from 'struct au::stdx::conjunction, au::Trinches>, au::detail::HasSameMagnitude, au::Trinches> >' - ./au/unit_of_measure.hh:459:8: required from 'struct au::AreUnitsQuantityEquivalent, au::Trinches>' - ./au/unit_of_measure.hh:521:8: required from 'struct au::detail::FirstMatchingUnit, au::CommonUnit >' - ./au/unit_of_measure.hh:532:8: required from 'struct au::ComputeCommonUnit' - ./au/quantity.hh:705:8: required from 'struct au::CommonQuantity, au::Quantity, void>' - ./au/quantity.hh:718:8: required from 'struct std::common_type, au::Quantity >' + au/code/au/packs.hh: In instantiation of 'struct au::LexicographicTotalOrdering': + au/code/au/packs.hh:298:8: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ] + au/code/au/unit_of_measure.hh:505:8: required from 'struct au::InOrderFor' + au/code/au/unit_of_measure.hh:554:8: required from 'struct au::detail::IsFirstUnitRedundant' + au/code/au/unit_of_measure.hh:564:8: required from 'struct au::detail::EliminateRedundantUnitsImpl >' + au/code/au/unit_of_measure.hh:592:8: required from 'struct au::ComputeCommonUnit' + au/code/au/quantity.hh:748:8: required from 'struct au::CommonQuantity, au::Quantity, void>' + au/code/au/quantity.hh:761:8: required from 'struct std::common_type, au::Quantity >' external/sysroot_x86_64//include/c++/10.3.0/type_traits:2562:11: required by substitution of 'template using common_type_t = typename std::common_type::type [with _Tp = {au::Quantity, au::Quantity}]' - ./au/quantity.hh:582:11: required from 'constexpr auto au::detail::using_common_type(T, U, Func) [with T = au::Quantity; U = au::Quantity; Func = au::detail::Equal]' - ./au/quantity.hh:594:37: required from 'constexpr bool au::operator==(au::Quantity, au::Quantity) [with U1 = au::Quarterfeet; U2 = au::Trinches; R1 = int; R2 = int]' - au/error_examples.cc:98:39: required from here - ./au/packs.hh:287:39: error: static assertion failed: Broken strict total ordering: distinct input types compare equal - In file included from ./au/conversion_policy.hh:22, - from ./au/quantity.hh:19, - from ./au/math.hh:22, - from ./au/au.hh:19, + au/code/au/quantity.hh:625:11: required from 'constexpr auto au::detail::using_common_type(T, U, Func) [with T = au::Quantity; U = au::Quantity; Func = au::detail::Equal]' + au/code/au/quantity.hh:637:37: required from 'constexpr bool au::operator==(au::Quantity, au::Quantity) [with U1 = au::Quarterfeet; U2 = au::Trinches; R1 = int; R2 = int]' + au/error_examples.cc:112:39: required from here + au/code/au/packs.hh:287:39: error: static assertion failed: Broken strict total ordering: distinct input types compare equal + In file included from au/code/au/conversion_policy.hh:22, + from au/code/au/quantity.hh:20, + from au/code/au/prefix.hh:18, + from au/code/au/chrono_interop.hh:20, + from au/code/au/au.hh:17, from au/error_examples.cc:15: - ./au/unit_of_measure.hh: In instantiation of 'struct au::CommonUnit': - ./au/packs.hh:203:7: required by substitution of 'template using DimMemberT = typename U::Dim [with U = au::CommonUnit]' - ./au/packs.hh:205:8: required from 'struct au::detail::DimImpl >' - ./au/unit_of_measure.hh:444:8: required from 'struct au::HasSameDimension, au::Trinches>' - ./au/stdx/type_traits.hh:38:61: required from 'struct au::stdx::conjunction, au::Trinches>, au::detail::HasSameMagnitude, au::Trinches> >' - ./au/unit_of_measure.hh:459:8: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ] - ./au/unit_of_measure.hh:532:8: required from 'struct au::ComputeCommonUnit' - ./au/quantity.hh:705:8: required from 'struct au::CommonQuantity, au::Quantity, void>' - ./au/quantity.hh:718:8: required from 'struct std::common_type, au::Quantity >' + au/code/au/unit_of_measure.hh: In instantiation of 'struct au::CommonUnit': + au/code/au/packs.hh:203:7: required by substitution of 'template using DimMemberT = typename U::Dim [with U = au::CommonUnit]' + au/code/au/packs.hh:205:8: required from 'struct au::detail::DimImpl >' + au/code/au/unit_of_measure.hh:455:8: required from 'struct au::HasSameDimension, au::Trinches>' + au/code/au/stdx/type_traits.hh:38:59: required from 'struct au::stdx::conjunction, au::Trinches>, au::detail::HasSameMagnitude, au::Trinches> >' + au/code/au/unit_of_measure.hh:470:8: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ] + au/code/au/unit_of_measure.hh:592:8: required from 'struct au::ComputeCommonUnit' + au/code/au/quantity.hh:748:8: required from 'struct au::CommonQuantity, au::Quantity, void>' + au/code/au/quantity.hh:761:8: required from 'struct std::common_type, au::Quantity >' external/sysroot_x86_64//include/c++/10.3.0/type_traits:2562:11: required by substitution of 'template using common_type_t = typename std::common_type::type [with _Tp = {au::Quantity, au::Quantity}]' - ./au/quantity.hh:582:11: required from 'constexpr auto au::detail::using_common_type(T, U, Func) [with T = au::Quantity; U = au::Quantity; Func = au::detail::Equal]' - ./au/quantity.hh:594:37: required from 'constexpr bool au::operator==(au::Quantity, au::Quantity) [with U1 = au::Quarterfeet; U2 = au::Trinches; R1 = int; R2 = int]' - au/error_examples.cc:98:39: required from here - ./au/unit_of_measure.hh:484:70: error: static assertion failed: Elements must be listed in ascending order - 484 | static_assert(AreElementsInOrder>::value, + au/code/au/quantity.hh:625:11: required from 'constexpr auto au::detail::using_common_type(T, U, Func) [with T = au::Quantity; U = au::Quantity; Func = au::detail::Equal]' + au/code/au/quantity.hh:637:37: required from 'constexpr bool au::operator==(au::Quantity, au::Quantity) [with U1 = au::Quarterfeet; U2 = au::Trinches; R1 = int; R2 = int]' + au/error_examples.cc:112:39: required from here + au/code/au/unit_of_measure.hh:495:70: error: static assertion failed: Elements must be listed in ascending order + 495 | static_assert(AreElementsInOrder>::value, | ^~~~~ ``` **Compiler error (MSVC 2019 x64)** ``` - D:\a\au\au\au.hh(1037): error C2338: Broken strict total ordering: distinct input types compare equal - D:\a\au\au\au.hh(1068): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled + D:\a\au\au\au.hh(1392): error C2338: Broken strict total ordering: distinct input types compare equal + D:\a\au\au\au.hh(1423): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled with [ A=au::Quarterfeet, B=au::Trinches ] - D:\a\au\au\au.hh(1068): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled + D:\a\au\au\au.hh(1423): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled with [ A=au::Quarterfeet, B=au::Trinches ] - D:\a\au\au\au.hh(1068): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled + D:\a\au\au\au.hh(1423): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled with [ A=au::Quarterfeet, B=au::Trinches ] - D:\a\au\au\au.hh(1068): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled + D:\a\au\au\au.hh(1423): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled with [ A=au::Quarterfeet, B=au::Trinches ] - D:\a\au\au\au.hh(1068): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled + D:\a\au\au\au.hh(1423): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled with [ A=au::Quarterfeet, B=au::Trinches ] - D:\a\au\au\au.hh(2716): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled + D:\a\au\au\au.hh(3563): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled with [ A=au::Quarterfeet, B=au::Trinches ] - D:\a\au\au\au.hh(2344): note: see reference to class template instantiation 'au::InOrderFor' being compiled + D:\a\au\au\au.hh(3142): note: see reference to class template instantiation 'au::InOrderFor' being compiled with [ A=au::Quarterfeet, B=au::Trinches ] - D:\a\au\au\au.hh(1147): note: see reference to class template instantiation 'au::InOrderFor' being compiled + D:\a\au\au\au.hh(1502): note: see reference to class template instantiation 'au::InOrderFor' being compiled with [ List=au::CommonUnit, T=au::Quarterfeet, H=au::Trinches ] - D:\a\au\au\au.hh(2379): note: see reference to class template instantiation 'au::FlatDedupedTypeList,au::CommonUnit>' being compiled + D:\a\au\au\au.hh(3226): note: see reference to class template instantiation 'au::FlatDedupedTypeList,au::CommonUnit>' being compiled with [ T=au::Quarterfeet ] - D:\a\au\au\au.hh(2379): note: see reference to alias template instantiation 'au::FlatDedupedTypeListT' being compiled - D:\a\au\au\au.hh(2383): note: see reference to alias template instantiation 'au::ComputeCommonUnitImpl' being compiled - D:\a\au\au\au.hh(3491): note: see reference to class template instantiation 'au::ComputeCommonUnit' being compiled + D:\a\au\au\au.hh(3226): note: see reference to alias template instantiation 'au::FlatDedupedTypeListT' being compiled + D:\a\au\au\au.hh(3230): note: see reference to alias template instantiation 'au::ComputeCommonUnitImpl' being compiled + D:\a\au\au\au.hh(4619): note: see reference to class template instantiation 'au::ComputeCommonUnit' being compiled with [ U1=au::Quarterfeet, U2=au::Trinches ] - D:\a\au\au\au.hh(3491): note: see reference to alias template instantiation 'au::CommonUnitT' being compiled - D:\a\au\au\au.hh(3502): note: see reference to class template instantiation 'au::CommonQuantity,au::Quantity,void>' being compiled - D:\a\au\au\au.hh(3365): note: see reference to class template instantiation 'std::common_type' being compiled + D:\a\au\au\au.hh(4619): note: see reference to alias template instantiation 'au::CommonUnitT' being compiled + D:\a\au\au\au.hh(4630): note: see reference to class template instantiation 'au::CommonQuantity,au::Quantity,void>' being compiled + D:\a\au\au\au.hh(4493): note: see reference to class template instantiation 'std::common_type' being compiled with [ T=au::Quantity, U=au::Quantity ] - D:\a\au\au\au.hh(3365): note: see reference to alias template instantiation 'std::common_type_t,U>' being compiled + D:\a\au\au\au.hh(4493): note: see reference to alias template instantiation 'std::common_type_t,U>' being compiled with [ U=au::Quantity ] - D:\a\au\au\au.hh(3377): note: see reference to function template instantiation 'auto au::detail::using_common_type,au::Quantity,au::detail::Equal>(T,U,Func)' being compiled + D:\a\au\au\au.hh(4505): note: see reference to function template instantiation 'auto au::detail::using_common_type,au::Quantity,au::detail::Equal>(T,U,Func)' being compiled with [ T=au::Quantity, U=au::Quantity, Func=au::detail::Equal ] - error_examples.cc(99): note: see reference to function template instantiation 'bool au::operator ==(au::Quantity,au::Quantity)' being compiled - D:\a\au\au\au.hh(2334): error C2338: Elements must be listed in ascending order + error_examples.cc(113): note: see reference to function template instantiation 'bool au::operator ==(au::Quantity,au::Quantity)' being compiled + D:\a\au\au\au.hh(3132): error C2338: Elements must be listed in ascending order + D:\a\au\au\au.hh(1310): note: see reference to class template instantiation 'au::CommonUnit' being compiled + with + [ + T=au::Trinches + ] + D:\a\au\au\au.hh(3133): note: see reference to alias template instantiation 'au::detail::DimMemberT>' being compiled + with + [ + T=au::Trinches + ] + D:\a\au\au\au.hh(3094): note: see reference to class template instantiation 'au::detail::DimImpl' being compiled + with + [ + U1=au::CommonUnit + ] + D:\a\au\au\au.hh(3093): note: see reference to alias template instantiation 'au::detail::DimT>' being compiled + with + [ + T=au::Trinches + ] + D:\a\au\au\au.hh(210): note: see reference to class template instantiation 'au::HasSameDimension' being compiled + with + [ + U1=au::CommonUnit, + U2=au::Trinches + ] + D:\a\au\au\au.hh(3108): note: see reference to class template instantiation 'au::stdx::conjunction,au::detail::HasSameMagnitude>' being compiled + with + [ + U1=au::CommonUnit, + U2=au::Trinches + ] + D:\a\au\au\au.hh(3172): note: see reference to class template instantiation 'au::AreUnitsQuantityEquivalent' being compiled + with + [ + TargetUnit=au::CommonUnit, + H=au::Trinches + ] + D:\a\au\au\au.hh(3230): note: see reference to class template instantiation 'au::detail::FirstMatchingUnit,TargetUnit>' being compiled + with + [ + T=au::Trinches, + TargetUnit=au::CommonUnit + ] ``` **Compiler error (MSVC 2022 x64)** ``` - D:\a\au\au\au.hh(1037): error C2338: static_assert failed: 'Broken strict total ordering: distinct input types compare equal' - D:\a\au\au\au.hh(1053): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled + D:\a\au\au\au.hh(1392): error C2338: static_assert failed: 'Broken strict total ordering: distinct input types compare equal' + D:\a\au\au\au.hh(1392): note: the template instantiation context (the oldest one first) is + error_examples.cc(113): note: see reference to function template instantiation 'bool au::operator ==(au::Quantity,au::Quantity)' being compiled + D:\a\au\au\au.hh(4505): note: see reference to function template instantiation 'auto au::detail::using_common_type,au::Quantity,au::detail::Equal>(T,U,Func)' being compiled with [ - A=au::Quarterfeet, - B=au::Trinches + T=au::Quantity, + U=au::Quantity, + Func=au::detail::Equal ] - D:\a\au\au\au.hh(1053): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled + D:\a\au\au\au.hh(4493): note: see reference to alias template instantiation 'std::common_type_t' being compiled + with + [ + T=au::Quantity, + U=au::Quantity + ] + C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.41.34120\include\type_traits(1334): note: see reference to class template instantiation 'std::common_type' being compiled + with + [ + T=au::Quantity, + U=au::Quantity + ] + D:\a\au\au\au.hh(4630): note: see reference to class template instantiation 'au::CommonQuantity,au::Quantity,void>' being compiled + D:\a\au\au\au.hh(4619): note: see reference to alias template instantiation 'au::CommonUnitT' being compiled + with + [ + U1=au::Quarterfeet, + U2=au::Trinches + ] + D:\a\au\au\au.hh(2806): note: see reference to class template instantiation 'au::ComputeCommonUnit' being compiled + with + [ + U1=au::Quarterfeet, + U2=au::Trinches + ] + D:\a\au\au\au.hh(3230): note: see reference to alias template instantiation 'au::ComputeCommonUnitImpl' being compiled + with + [ + U1=au::Quarterfeet, + U2=au::Trinches + ] + D:\a\au\au\au.hh(3226): note: see reference to alias template instantiation 'au::FlatDedupedTypeListT' being compiled + with + [ + U1=au::Quarterfeet, + U2=au::Trinches + ] + D:\a\au\au\au.hh(1213): note: see reference to class template instantiation 'au::FlatDedupedTypeList,au::CommonUnit>' being compiled + with + [ + T=au::Quarterfeet + ] + D:\a\au\au\au.hh(1496): note: see reference to class template instantiation 'au::InOrderFor' being compiled + with + [ + List=au::CommonUnit, + T=au::Quarterfeet, + H=au::Trinches + ] + D:\a\au\au\au.hh(3142): note: see reference to class template instantiation 'au::InOrderFor' being compiled with [ A=au::Quarterfeet, B=au::Trinches ] - D:\a\au\au\au.hh(1053): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled + D:\a\au\au\au.hh(3557): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled with [ A=au::Quarterfeet, B=au::Trinches ] - D:\a\au\au\au.hh(1053): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled + D:\a\au\au\au.hh(1408): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled with [ A=au::Quarterfeet, B=au::Trinches ] - D:\a\au\au\au.hh(1053): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled + D:\a\au\au\au.hh(1408): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled with [ A=au::Quarterfeet, B=au::Trinches ] - D:\a\au\au\au.hh(2710): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled + D:\a\au\au\au.hh(1408): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled with [ A=au::Quarterfeet, B=au::Trinches ] - D:\a\au\au\au.hh(2344): note: see reference to class template instantiation 'au::InOrderFor' being compiled + D:\a\au\au\au.hh(1408): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled with [ A=au::Quarterfeet, B=au::Trinches ] - D:\a\au\au\au.hh(1147): note: see reference to class template instantiation 'au::InOrderFor' being compiled + D:\a\au\au\au.hh(1408): note: see reference to class template instantiation 'au::LexicographicTotalOrdering' being compiled with [ - List=au::CommonUnit, - T=au::Quarterfeet, - H=au::Trinches + A=au::Quarterfeet, + B=au::Trinches ] - D:\a\au\au\au.hh(2379): note: see reference to class template instantiation 'au::FlatDedupedTypeList,au::CommonUnit>' being compiled + D:\a\au\au\au.hh(3132): error C2338: static_assert failed: 'Elements must be listed in ascending order' + D:\a\au\au\au.hh(3132): note: the template instantiation context (the oldest one first) is + D:\a\au\au\au.hh(3230): note: see reference to class template instantiation 'au::detail::FirstMatchingUnit,TargetUnit>' being compiled with [ - T=au::Quarterfeet + T=au::Trinches, + TargetUnit=au::CommonUnit ] - D:\a\au\au\au.hh(2379): note: see reference to alias template instantiation 'au::FlatDedupedTypeListT' being compiled + D:\a\au\au\au.hh(3170): note: see reference to class template instantiation 'au::AreUnitsQuantityEquivalent' being compiled with [ - U1=au::Quarterfeet, - U2=au::Trinches + TargetUnit=au::CommonUnit, + H=au::Trinches ] - D:\a\au\au\au.hh(2383): note: see reference to alias template instantiation 'au::ComputeCommonUnitImpl' being compiled + D:\a\au\au\au.hh(3108): note: see reference to class template instantiation 'au::stdx::conjunction,au::detail::HasSameMagnitude>' being compiled with [ - U1=au::Quarterfeet, + U1=au::CommonUnit, U2=au::Trinches ] - D:\a\au\au\au.hh(3491): note: see reference to class template instantiation 'au::ComputeCommonUnit' being compiled + D:\a\au\au\au.hh(210): note: see reference to class template instantiation 'au::HasSameDimension' being compiled with [ - U1=au::Quarterfeet, + U1=au::CommonUnit, U2=au::Trinches ] - D:\a\au\au\au.hh(3491): note: see reference to alias template instantiation 'au::CommonUnitT' being compiled + D:\a\au\au\au.hh(3093): note: see reference to alias template instantiation 'au::detail::DimT' being compiled with [ - U1=au::Quarterfeet, - U2=au::Trinches + U1=au::CommonUnit ] - D:\a\au\au\au.hh(3502): note: see reference to class template instantiation 'au::CommonQuantity,au::Quantity,void>' being compiled - D:\a\au\au\au.hh(3365): note: see reference to class template instantiation 'std::common_type' being compiled + D:\a\au\au\au.hh(1312): note: see reference to class template instantiation 'au::detail::DimImpl' being compiled with [ - T=au::Quantity, - U=au::Quantity + U1=au::CommonUnit ] - D:\a\au\au\au.hh(3365): note: see reference to alias template instantiation 'std::common_type_t' being compiled + D:\a\au\au\au.hh(1310): note: see reference to alias template instantiation 'au::detail::DimMemberT' being compiled with [ - T=au::Quantity, - U=au::Quantity + U=au::CommonUnit ] - D:\a\au\au\au.hh(3377): note: see reference to function template instantiation 'auto au::detail::using_common_type,au::Quantity,au::detail::Equal>(T,U,Func)' being compiled + D:\a\au\au\au.hh(1308): note: see reference to class template instantiation 'au::CommonUnit' being compiled with [ - T=au::Quantity, - U=au::Quantity, - Func=au::detail::Equal + T=au::Trinches ] - error_examples.cc(99): note: see reference to function template instantiation 'bool au::operator ==(au::Quantity,au::Quantity)' being compiled - D:\a\au\au\au.hh(2334): error C2338: static_assert failed: 'Elements must be listed in ascending order' ```