Closed chiphogg closed 2 months ago
Here are the example changes to tests, for posterity.
TEST(Quantity, OfQuantityMakesNiceErrorMessage) {
radians(radians);
radians(radians(3.14));
meters(meters_pt(15));
meters_pt(meters_pt(51));
meters_pt(meters(51));
}
In file included from au/code/au/au_test.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:17:
au/code/au/quantity.hh:287:68: error: invalid operands to binary expression ('au::QuantityMaker<au::Radians>' and 'au::QuantityMaker<au::Radians>')
friend constexpr Quantity<UnitT, decltype(std::declval<RepT>() + std::declval<RepT>())>
~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~
au/code/au/quantity.hh:489:33: note: in instantiation of template class 'au::Quantity<au::Radians, au::QuantityMaker<au::Radians>>' requested here
constexpr Quantity<Unit, T> operator()(T value) const {
^
au/code/au/au_test.cc:94:12: note: in instantiation of function template specialization 'au::QuantityMaker<au::Radians>::operator()<au::QuantityMaker<au::Radians>>' requested here
radians(radians);
^
au/code/au/zero.hh:55:23: note: candidate function not viable: no known conversion from 'au::QuantityMaker<au::Radians>' to 'au::Zero' for 1st argument
inline constexpr Zero operator+(Zero, Zero) { return ZERO; }
^
au/code/au/quantity.hh:623:16: note: candidate template ignored: could not match 'Quantity' against 'QuantityMaker'
constexpr auto operator+(Quantity<U1, R1> q1, Quantity<U2, R2> q2) {
^
au/code/au/quantity.hh:633:16: note: candidate template ignored: could not match 'Quantity' against 'QuantityMaker'
constexpr auto operator+(Quantity<U, R> q1, QLike q2) -> decltype(q1 + as_quantity(q2)) {
^
au/code/au/quantity.hh:667:16: note: candidate template ignored: could not match 'Quantity' against 'QuantityMaker'
constexpr auto operator+(QLike q1, Quantity<U, R> q2) -> decltype(as_quantity(q1) + q2) {
^
au/code/au/quantity_point.hh:395:16: note: candidate template ignored: could not match 'QuantityPoint' against 'QuantityMaker'
constexpr auto operator+(QuantityPoint<UnitP, RepP> p, Quantity<UnitQ, RepQ> q) {
^
au/code/au/quantity_point.hh:400:16: note: candidate template ignored: could not match 'Quantity' against 'QuantityMaker'
constexpr auto operator+(Quantity<UnitQ, RepQ> q, QuantityPoint<UnitP, RepP> p) {
^
In file included from au/code/au/au_test.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:17:
au/code/au/quantity.hh:291:68: error: invalid operands to binary expression ('au::QuantityMaker<au::Radians>' and 'au::QuantityMaker<au::Radians>')
friend constexpr Quantity<UnitT, decltype(std::declval<RepT>() - std::declval<RepT>())>
~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~
au/code/au/zero.hh:56:23: note: candidate function not viable: no known conversion from 'au::QuantityMaker<au::Radians>' to 'au::Zero' for 1st argument
inline constexpr Zero operator-(Zero, Zero) { return ZERO; }
^
au/code/au/quantity.hh:627:16: note: candidate template ignored: could not match 'Quantity' against 'QuantityMaker'
constexpr auto operator-(Quantity<U1, R1> q1, Quantity<U2, R2> q2) {
^
au/code/au/quantity.hh:637:16: note: candidate template ignored: could not match 'Quantity' against 'QuantityMaker'
constexpr auto operator-(Quantity<U, R> q1, QLike q2) -> decltype(q1 - as_quantity(q2)) {
^
au/code/au/quantity.hh:671:16: note: candidate template ignored: could not match 'Quantity' against 'QuantityMaker'
constexpr auto operator-(QLike q1, Quantity<U, R> q2) -> decltype(as_quantity(q1) - q2) {
^
au/code/au/quantity_point.hh:405:16: note: candidate template ignored: could not match 'QuantityPoint' against 'QuantityMaker'
constexpr auto operator-(QuantityPoint<UnitP, R1> p, Quantity<UnitQ, RepQ> q) {
^
au/code/au/quantity_point.hh:410:16: note: candidate template ignored: could not match 'QuantityPoint' against 'QuantityMaker'
constexpr auto operator-(QuantityPoint<U1, R1> p1, QuantityPoint<U2, R2> p2) {
^
In file included from au/code/au/au_test.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:17:
au/code/au/quantity.hh:287:68: error: invalid operands to binary expression ('au::QuantityPoint<au::Meters, int>' and 'au::QuantityPoint<au::Meters, int>')
friend constexpr Quantity<UnitT, decltype(std::declval<RepT>() + std::declval<RepT>())>
~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~
au/code/au/quantity.hh:489:33: note: in instantiation of template class 'au::Quantity<au::Meters, au::QuantityPoint<au::Meters, int>>' requested here
constexpr Quantity<Unit, T> operator()(T value) const {
^
au/code/au/au_test.cc:96:11: note: in instantiation of function template specialization 'au::QuantityMaker<au::Meters>::operator()<au::QuantityPoint<au::Meters, int>>' requested here
meters(meters_pt(15));
^
au/code/au/quantity_point.hh:250:27: note: candidate function not viable: no known conversion from 'au::QuantityPoint<au::Meters, int>' to 'au::QuantityPoint<au::Meters, int>::Diff' (aka 'Quantity<au::Meters, int>') for 1st argument
constexpr friend auto operator+(Diff d, QuantityPoint p) { return QuantityPoint{d + p.x_}; }
^
au/code/au/quantity_point.hh:251:27: note: candidate function not viable: no known conversion from 'au::QuantityPoint<au::Meters, int>' to 'au::QuantityPoint<au::Meters, int>::Diff' (aka 'Quantity<au::Meters, int>') for 2nd argument
constexpr friend auto operator+(QuantityPoint p, Diff d) { return QuantityPoint{p.x_ + d}; }
^
au/code/au/zero.hh:55:23: note: candidate function not viable: no known conversion from 'au::QuantityPoint<au::Meters, int>' to 'au::Zero' for 1st argument
inline constexpr Zero operator+(Zero, Zero) { return ZERO; }
^
au/code/au/quantity.hh:623:16: note: candidate template ignored: could not match 'Quantity' against 'QuantityPoint'
constexpr auto operator+(Quantity<U1, R1> q1, Quantity<U2, R2> q2) {
^
au/code/au/quantity.hh:633:16: note: candidate template ignored: could not match 'Quantity' against 'QuantityPoint'
constexpr auto operator+(Quantity<U, R> q1, QLike q2) -> decltype(q1 + as_quantity(q2)) {
^
au/code/au/quantity.hh:667:16: note: candidate template ignored: could not match 'Quantity' against 'QuantityPoint'
constexpr auto operator+(QLike q1, Quantity<U, R> q2) -> decltype(as_quantity(q1) + q2) {
^
au/code/au/quantity_point.hh:395:16: note: candidate template ignored: could not match 'Quantity' against 'QuantityPoint'
constexpr auto operator+(QuantityPoint<UnitP, RepP> p, Quantity<UnitQ, RepQ> q) {
^
au/code/au/quantity_point.hh:400:16: note: candidate template ignored: could not match 'Quantity' against 'QuantityPoint'
constexpr auto operator+(Quantity<UnitQ, RepQ> q, QuantityPoint<UnitP, RepP> p) {
^
au/code/au/quantity_point.hh:80:88: error: invalid operands to binary expression ('au::Quantity<au::Meters, au::QuantityPoint<au::Meters, int>>' and 'au::Zero')
decltype(std::declval<typename QuantityPoint<OtherUnit, OtherRep>::Diff>() +
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
au/code/au/quantity_point.hh:91:24: note: in instantiation of function template specialization 'au::QuantityPoint<au::Meters, au::QuantityPoint<au::Meters, int>>::should_enable_implicit_construction_from<au::Meters, au::QuantityPoint<au::Meters, int>>' requested here
QuantityPoint::should_enable_implicit_construction_from<OtherUnit, OtherRep>()>;
^
au/code/au/quantity_point.hh:107:33: note: in instantiation of template type alias 'EnableIfImplicitOkIs' requested here
typename Enable = EnableIfImplicitOkIs<true, OtherUnit, OtherRep>>
^
au/code/au/quantity_point.hh:108:15: note: in instantiation of default argument for 'QuantityPoint<au::Meters, au::QuantityPoint<au::Meters, int>>' required here
constexpr QuantityPoint(QuantityPoint<OtherUnit, OtherRep> other) // NOLINT(runtime/explicit)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
au/code/au/quantity_point.hh:287:16: note: while substituting deduced template arguments into function template 'QuantityPoint' [with OtherUnit = au::Meters, OtherRep = au::QuantityPoint<au::Meters, int>, Enable = (no value)]
return QuantityPoint<Unit, T>{make_quantity<Unit>(value)};
^
au/code/au/au_test.cc:97:14: note: in instantiation of function template specialization 'au::QuantityPointMaker<au::Meters>::operator()<au::QuantityPoint<au::Meters, int>>' requested here
meters_pt(meters_pt(51));
^
au/code/au/zero.hh:55:23: note: candidate function not viable: no known conversion from 'au::Quantity<au::Meters, au::QuantityPoint<au::Meters, int>>' to 'au::Zero' for 1st argument
inline constexpr Zero operator+(Zero, Zero) { return ZERO; }
^
au/code/au/quantity_point.hh:250:27: note: candidate function not viable: no known conversion from 'Quantity<[...], au::QuantityPoint<au::Meters, int>>' to 'Quantity<[...], au::QuantityPoint<au::Meters, int>::Rep>' for 1st argument
constexpr friend auto operator+(Diff d, QuantityPoint p) { return QuantityPoint{d + p.x_}; }
^
au/code/au/quantity_point.hh:251:27: note: candidate function not viable: no known conversion from 'au::Quantity<au::Meters, au::QuantityPoint<au::Meters, int>>' to 'au::QuantityPoint<au::Meters, int>' for 1st argument
constexpr friend auto operator+(QuantityPoint p, Diff d) { return QuantityPoint{p.x_ + d}; }
^
au/code/au/quantity.hh:623:16: note: candidate template ignored: could not match 'Quantity<U2, R2>' against 'au::Zero'
constexpr auto operator+(Quantity<U1, R1> q1, Quantity<U2, R2> q2) {
^
au/code/au/quantity.hh:633:16: note: candidate template ignored: substitution failure [with U = au::Meters, R = au::QuantityPoint<au::Meters, int>, QLike = au::Zero]: no matching function for call to 'as_quantity'
constexpr auto operator+(Quantity<U, R> q1, QLike q2) -> decltype(q1 + as_quantity(q2)) {
^ ~~~~~~~~~~~
au/code/au/quantity.hh:667:16: note: candidate template ignored: could not match 'Quantity<U, R>' against 'au::Zero'
constexpr auto operator+(QLike q1, Quantity<U, R> q2) -> decltype(as_quantity(q1) + q2) {
^
au/code/au/quantity_point.hh:395:16: note: candidate template ignored: could not match 'QuantityPoint' against 'Quantity'
constexpr auto operator+(QuantityPoint<UnitP, RepP> p, Quantity<UnitQ, RepQ> q) {
^
au/code/au/quantity_point.hh:400:16: note: candidate template ignored: could not match 'QuantityPoint<UnitP, RepP>' against 'au::Zero'
constexpr auto operator+(Quantity<UnitQ, RepQ> q, QuantityPoint<UnitP, RepP> p) {
^
au/code/au/quantity.hh:371:24: note: candidate function not viable: requires 0 arguments, but 2 were provided
constexpr Quantity operator+() const { return {+value_}; }
^
In file included from au/code/au/au_test.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:17:
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/stdx/utility.hh:100:65: error: calling a private constructor of class 'au::Quantity<au::Meters, int>'
constexpr bool operator()(T t, U u) { return t < 0 ? true : std::make_unsigned_t<T>(t) < u; }
^
au/code/au/stdx/utility.hh:46:12: note: in instantiation of member function 'au::stdx::CmpLessImpl<int, au::Quantity<au::Meters, int>>::operator()' requested here
return CmpLessImpl<T, U>{}(t, u);
^
au/code/au/stdx/utility.hh:64:13: note: in instantiation of function template specialization 'au::stdx::cmp_less<int, au::Quantity<au::Meters, int>>' requested here
return !cmp_less(t, u);
^
au/code/au/stdx/utility.hh:70:12: note: in instantiation of function template specialization 'au::stdx::cmp_greater_equal<int, au::Quantity<au::Meters, int>>' requested here
return cmp_greater_equal(t, std::numeric_limits<R>::min()) &&
^
au/code/au/conversion_policy.hh:47:37: note: in instantiation of function template specialization 'au::stdx::in_range<au::Quantity<au::Meters, int>, int>' requested here
stdx::bool_constant<stdx::in_range<Rep>(OVERFLOW_THRESHOLD)>,
^
au/code/au/stdx/type_traits.hh:36:25: note: in instantiation of template class 'au::detail::CanScaleThresholdWithoutOverflow<au::Quantity<au::Meters, int>, au::Magnitude<>>' requested here
struct conjunction<B> : B {};
^
au/code/au/stdx/type_traits.hh:38:32: note: (skipping 10 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
struct conjunction<B, Bn...> : std::conditional_t<bool(B::value), conjunction<Bn...>, B> {};
^
au/code/au/quantity.hh:122:15: note: in instantiation of default argument for 'Quantity<au::Meters, int>' required here
constexpr Quantity(Quantity<OtherUnit, OtherRep> other) // NOLINT(runtime/explicit)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
au/code/au/quantity.hh:490:16: note: while substituting deduced template arguments into function template 'Quantity' [with OtherUnit = au::Meters, OtherRep = int, Enable = (no value)]
return {value};
^
au/code/au/quantity.hh:40:12: note: in instantiation of function template specialization 'au::QuantityMaker<au::Meters>::operator()<au::Quantity<au::Meters, int>>' requested here
return QuantityMaker<UnitT>{}(value);
^
au/code/au/quantity_point.hh:287:39: note: in instantiation of function template specialization 'au::make_quantity<au::Meters, au::Quantity<au::Meters, int>>' requested here
return QuantityPoint<Unit, T>{make_quantity<Unit>(value)};
^
au/code/au/au_test.cc:98:14: note: in instantiation of function template specialization 'au::QuantityPointMaker<au::Meters>::operator()<au::Quantity<au::Meters, int>>' requested here
meters_pt(meters(51));
^
au/code/au/quantity.hh:400:15: note: declared private here
constexpr Quantity(Rep value) : value_{value} {}
^
In file included from au/code/au/au_test.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:17:
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/stdx/utility.hh:105:70: error: calling a private constructor of class 'au::Quantity<au::Meters, int>'
constexpr bool operator()(T t, U u) { return u < 0 ? false : t < std::make_unsigned_t<U>(u); }
^
au/code/au/stdx/utility.hh:46:12: note: in instantiation of member function 'au::stdx::CmpLessImpl<au::Quantity<au::Meters, int>, int>::operator()' requested here
return CmpLessImpl<T, U>{}(t, u);
^
au/code/au/stdx/utility.hh:52:12: note: in instantiation of function template specialization 'au::stdx::cmp_less<au::Quantity<au::Meters, int>, int>' requested here
return cmp_less(u, t);
^
au/code/au/stdx/utility.hh:58:13: note: in instantiation of function template specialization 'au::stdx::cmp_greater<int, au::Quantity<au::Meters, int>>' requested here
return !cmp_greater(t, u);
^
au/code/au/stdx/utility.hh:71:12: note: in instantiation of function template specialization 'au::stdx::cmp_less_equal<int, au::Quantity<au::Meters, int>>' requested here
cmp_less_equal(t, std::numeric_limits<R>::max());
^
au/code/au/conversion_policy.hh:47:37: note: in instantiation of function template specialization 'au::stdx::in_range<au::Quantity<au::Meters, int>, int>' requested here
stdx::bool_constant<stdx::in_range<Rep>(OVERFLOW_THRESHOLD)>,
^
au/code/au/stdx/type_traits.hh:36:25: note: (skipping 11 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
struct conjunction<B> : B {};
^
au/code/au/quantity.hh:122:15: note: in instantiation of default argument for 'Quantity<au::Meters, int>' required here
constexpr Quantity(Quantity<OtherUnit, OtherRep> other) // NOLINT(runtime/explicit)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
au/code/au/quantity.hh:490:16: note: while substituting deduced template arguments into function template 'Quantity' [with OtherUnit = au::Meters, OtherRep = int, Enable = (no value)]
return {value};
^
au/code/au/quantity.hh:40:12: note: in instantiation of function template specialization 'au::QuantityMaker<au::Meters>::operator()<au::Quantity<au::Meters, int>>' requested here
return QuantityMaker<UnitT>{}(value);
^
au/code/au/quantity_point.hh:287:39: note: in instantiation of function template specialization 'au::make_quantity<au::Meters, au::Quantity<au::Meters, int>>' requested here
return QuantityPoint<Unit, T>{make_quantity<Unit>(value)};
^
au/code/au/au_test.cc:98:14: note: in instantiation of function template specialization 'au::QuantityPointMaker<au::Meters>::operator()<au::Quantity<au::Meters, int>>' requested here
meters_pt(meters(51));
^
au/code/au/quantity.hh:400:15: note: declared private here
constexpr Quantity(Rep value) : value_{value} {}
^
In file included from au/code/au/au_test.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:17:
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:
au/code/au/magnitude.hh:519:43: error: calling a private constructor of class 'au::Quantity<au::Meters, int>'
return {MagRepresentationOutcome::OK, static_cast<T>(1)};
^
au/code/au/magnitude.hh:534:29: note: in instantiation of function template specialization 'au::detail::get_value_result<au::Quantity<au::Meters, int>>' requested here
constexpr auto result = get_value_result<T>(m);
^
au/code/au/conversion_policy.hh:34:50: note: in instantiation of function template specialization 'au::get_value<au::Quantity<au::Meters, int>>' requested here
return std::numeric_limits<Rep>::max() / get_value<Rep>(m) >= value;
^
au/code/au/conversion_policy.hh:48:31: note: in instantiation of function template specialization 'au::can_scale_without_overflow<au::Quantity<au::Meters, int>>' requested here
stdx::bool_constant<can_scale_without_overflow<Rep>(ScaleFactor{}, OVERFLOW_THRESHOLD)>> {
^
au/code/au/stdx/type_traits.hh:36:25: note: in instantiation of template class 'au::detail::CanScaleThresholdWithoutOverflow<au::Quantity<au::Meters, int>, au::Magnitude<>>' requested here
struct conjunction<B> : B {};
^
au/code/au/stdx/type_traits.hh:38:32: note: in instantiation of template class 'au::stdx::conjunction<au::detail::CanScaleThresholdWithoutOverflow<au::Quantity<au::Meters, int>, au::Magnitude<>>>' requested here
struct conjunction<B, Bn...> : std::conditional_t<bool(B::value), conjunction<Bn...>, B> {};
^
au/code/au/stdx/type_traits.hh:38:32: note: (skipping 9 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
au/code/au/quantity.hh:122:15: note: in instantiation of default argument for 'Quantity<au::Meters, int>' required here
constexpr Quantity(Quantity<OtherUnit, OtherRep> other) // NOLINT(runtime/explicit)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
au/code/au/quantity.hh:490:16: note: while substituting deduced template arguments into function template 'Quantity' [with OtherUnit = au::Meters, OtherRep = int, Enable = (no value)]
return {value};
^
au/code/au/quantity.hh:40:12: note: in instantiation of function template specialization 'au::QuantityMaker<au::Meters>::operator()<au::Quantity<au::Meters, int>>' requested here
return QuantityMaker<UnitT>{}(value);
^
au/code/au/quantity_point.hh:287:39: note: in instantiation of function template specialization 'au::make_quantity<au::Meters, au::Quantity<au::Meters, int>>' requested here
return QuantityPoint<Unit, T>{make_quantity<Unit>(value)};
^
au/code/au/au_test.cc:98:14: note: in instantiation of function template specialization 'au::QuantityPointMaker<au::Meters>::operator()<au::Quantity<au::Meters, int>>' requested here
meters_pt(meters(51));
^
au/code/au/quantity.hh:400:15: note: declared private here
constexpr Quantity(Rep value) : value_{value} {}
^
In file included from au/code/au/au_test.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:17:
In file included from au/code/au/quantity.hh:20:
au/code/au/conversion_policy.hh:34:16: error: calling a private constructor of class 'au::Quantity<au::Meters, int>'
return std::numeric_limits<Rep>::max() / get_value<Rep>(m) >= value;
^
au/code/au/conversion_policy.hh:48:31: note: in instantiation of function template specialization 'au::can_scale_without_overflow<au::Quantity<au::Meters, int>>' requested here
stdx::bool_constant<can_scale_without_overflow<Rep>(ScaleFactor{}, OVERFLOW_THRESHOLD)>> {
^
au/code/au/stdx/type_traits.hh:36:25: note: in instantiation of template class 'au::detail::CanScaleThresholdWithoutOverflow<au::Quantity<au::Meters, int>, au::Magnitude<>>' requested here
struct conjunction<B> : B {};
^
au/code/au/stdx/type_traits.hh:38:32: note: in instantiation of template class 'au::stdx::conjunction<au::detail::CanScaleThresholdWithoutOverflow<au::Quantity<au::Meters, int>, au::Magnitude<>>>' requested here
struct conjunction<B, Bn...> : std::conditional_t<bool(B::value), conjunction<Bn...>, B> {};
^
au/code/au/stdx/type_traits.hh:38:32: note: in instantiation of template class 'au::stdx::conjunction<au::IsInteger<au::Magnitude<>>, au::detail::CanScaleThresholdWithoutOverflow<au::Quantity<au::Meters, int>, au::Magnitude<>>>' requested here
au/code/au/stdx/type_traits.hh:44:25: note: in instantiation of template class 'au::stdx::conjunction<std::is_integral<int>, au::IsInteger<au::Magnitude<>>, au::detail::CanScaleThresholdWithoutOverflow<au::Quantity<au::Meters, int>, au::Magnitude<>>>' requested here
struct disjunction<B> : B {};
^
au/code/au/stdx/type_traits.hh:46:32: note: (skipping 7 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
struct disjunction<B, Bn...> : std::conditional_t<bool(B::value), B, disjunction<Bn...>> {};
^
au/code/au/quantity.hh:122:15: note: in instantiation of default argument for 'Quantity<au::Meters, int>' required here
constexpr Quantity(Quantity<OtherUnit, OtherRep> other) // NOLINT(runtime/explicit)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
au/code/au/quantity.hh:490:16: note: while substituting deduced template arguments into function template 'Quantity' [with OtherUnit = au::Meters, OtherRep = int, Enable = (no value)]
return {value};
^
au/code/au/quantity.hh:40:12: note: in instantiation of function template specialization 'au::QuantityMaker<au::Meters>::operator()<au::Quantity<au::Meters, int>>' requested here
return QuantityMaker<UnitT>{}(value);
^
au/code/au/quantity_point.hh:287:39: note: in instantiation of function template specialization 'au::make_quantity<au::Meters, au::Quantity<au::Meters, int>>' requested here
return QuantityPoint<Unit, T>{make_quantity<Unit>(value)};
^
au/code/au/au_test.cc:98:14: note: in instantiation of function template specialization 'au::QuantityPointMaker<au::Meters>::operator()<au::Quantity<au::Meters, int>>' requested here
meters_pt(meters(51));
^
au/code/au/quantity.hh:400:15: note: declared private here
constexpr Quantity(Rep value) : value_{value} {}
^
In file included from au/code/au/au_test.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:17:
In file included from au/code/au/quantity.hh:20:
au/code/au/conversion_policy.hh:48:78: error: calling a private constructor of class 'au::Quantity<au::Meters, int>'
stdx::bool_constant<can_scale_without_overflow<Rep>(ScaleFactor{}, OVERFLOW_THRESHOLD)>> {
^
au/code/au/stdx/type_traits.hh:36:25: note: in instantiation of template class 'au::detail::CanScaleThresholdWithoutOverflow<au::Quantity<au::Meters, int>, au::Magnitude<>>' requested here
struct conjunction<B> : B {};
^
au/code/au/stdx/type_traits.hh:38:32: note: in instantiation of template class 'au::stdx::conjunction<au::detail::CanScaleThresholdWithoutOverflow<au::Quantity<au::Meters, int>, au::Magnitude<>>>' requested here
struct conjunction<B, Bn...> : std::conditional_t<bool(B::value), conjunction<Bn...>, B> {};
^
au/code/au/stdx/type_traits.hh:38:32: note: in instantiation of template class 'au::stdx::conjunction<au::IsInteger<au::Magnitude<>>, au::detail::CanScaleThresholdWithoutOverflow<au::Quantity<au::Meters, int>, au::Magnitude<>>>' requested here
au/code/au/stdx/type_traits.hh:44:25: note: in instantiation of template class 'au::stdx::conjunction<std::is_integral<int>, au::IsInteger<au::Magnitude<>>, au::detail::CanScaleThresholdWithoutOverflow<au::Quantity<au::Meters, int>, au::Magnitude<>>>' requested here
struct disjunction<B> : B {};
^
au/code/au/stdx/type_traits.hh:46:32: note: in instantiation of template class 'au::stdx::disjunction<au::stdx::conjunction<std::is_integral<int>, au::IsInteger<au::Magnitude<>>, au::detail::CanScaleThresholdWithoutOverflow<au::Quantity<au::Meters, int>, au::Magnitude<>>>>' requested here
struct disjunction<B, Bn...> : std::conditional_t<bool(B::value), B, disjunction<Bn...>> {};
^
au/code/au/conversion_policy.hh:56:7: note: (skipping 6 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
: stdx::disjunction<
^
au/code/au/quantity.hh:122:15: note: in instantiation of default argument for 'Quantity<au::Meters, int>' required here
constexpr Quantity(Quantity<OtherUnit, OtherRep> other) // NOLINT(runtime/explicit)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
au/code/au/quantity.hh:490:16: note: while substituting deduced template arguments into function template 'Quantity' [with OtherUnit = au::Meters, OtherRep = int, Enable = (no value)]
return {value};
^
au/code/au/quantity.hh:40:12: note: in instantiation of function template specialization 'au::QuantityMaker<au::Meters>::operator()<au::Quantity<au::Meters, int>>' requested here
return QuantityMaker<UnitT>{}(value);
^
au/code/au/quantity_point.hh:287:39: note: in instantiation of function template specialization 'au::make_quantity<au::Meters, au::Quantity<au::Meters, int>>' requested here
return QuantityPoint<Unit, T>{make_quantity<Unit>(value)};
^
au/code/au/au_test.cc:98:14: note: in instantiation of function template specialization 'au::QuantityPointMaker<au::Meters>::operator()<au::Quantity<au::Meters, int>>' requested here
meters_pt(meters(51));
^
au/code/au/quantity.hh:400:15: note: declared private here
constexpr Quantity(Rep value) : value_{value} {}
^
9 errors generated.
In file included from au/code/au/au_test.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:17:
au/code/au/quantity.hh:119:5: error: static_assert failed due to requirement 'IsValidRep<au::QuantityMaker<au::Radians>>::value' "Rep must meet our requirements for a rep"
static_assert(IsValidRep<Rep>::value, "Rep must meet our requirements for a rep");
^ ~~~~~~~~~~~~~~~~~~~~~~
au/code/au/quantity.hh:498:33: note: in instantiation of template class 'au::Quantity<au::Radians, au::QuantityMaker<au::Radians>>' requested here
constexpr Quantity<Unit, T> operator()(T value) const {
^
au/code/au/au_test.cc:94:12: note: in instantiation of function template specialization 'au::QuantityMaker<au::Radians>::operator()<au::QuantityMaker<au::Radians>>' requested here
radians(radians);
^
In file included from au/code/au/au_test.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:17:
au/code/au/quantity.hh:505: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/code/au/au_test.cc:95:12: note: in instantiation of function template specialization 'au::QuantityMaker<au::Radians>::operator()<au::Radians, double>' requested here
radians(radians(3.14));
^
In file included from au/code/au/au_test.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:17:
au/code/au/quantity.hh:511:9: error: static_assert failed due to requirement 'is_not_a_quantity_point' "Input to QuantityMaker is a QuantityPoint"
static_assert(is_not_a_quantity_point, "Input to QuantityMaker is a QuantityPoint");
^ ~~~~~~~~~~~~~~~~~~~~~~~
au/code/au/au_test.cc:96:11: note: in instantiation of function template specialization 'au::QuantityMaker<au::Meters>::operator()<au::Meters, int>' requested here
meters(meters_pt(15));
^
In file included from au/code/au/au_test.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:
au/code/au/quantity_point.hh:299: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/code/au/au_test.cc:97:14: note: in instantiation of function template specialization 'au::QuantityPointMaker<au::Meters>::operator()<au::Meters, int>' requested here
meters_pt(meters_pt(51));
^
In file included from au/code/au/au_test.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:
au/code/au/quantity_point.hh:293:9: error: static_assert failed due to requirement 'is_not_a_quantity' "Input to QuantityPointMaker is a Quantity"
static_assert(is_not_a_quantity, "Input to QuantityPointMaker is a Quantity");
^ ~~~~~~~~~~~~~~~~~
au/code/au/au_test.cc:98:14: note: in instantiation of function template specialization 'au::QuantityPointMaker<au::Meters>::operator()<au::Meters, int>' requested here
meters_pt(meters(51));
^
5 errors generated.
This covers situations where somebody calls a
QuantityMaker
, orQuantityPointMaker
, on a value that isn't a valid rep. (One of the most common use cases is when the value is already a core Au type, aQuantity
orQuantityMaker
, and the call is redundant.The first approach is a blanket approach: we start enforcing the "valid rep" definition that we had previously added. This already makes the error messages a lot nicer and shorter.
We then go further for the most common use case of redundant maker calls. By adding templated overloads to each maker for
Quantity
andQuantityPoint
, we can directly tell users what they did wrong. In order to implement these overloads, we needed anAlwaysFalse
utliity, which we added along with unit tests.Helps #288. We will follow up to close this out by updating the troubleshooting guide.