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' ```