diff --git a/au/io.hh b/au/io.hh index 29570746..f52464ff 100644 --- a/au/io.hh +++ b/au/io.hh @@ -25,7 +25,12 @@ namespace au { // Streaming output support for Quantity types. template std::ostream &operator<<(std::ostream &out, const Quantity &q) { - out << q.in(U{}) << " " << unit_label(U{}); + // In the case that the Rep is a type that resolves to 'char' (e.g. int8_t), + // the << operator will match the implementation that takes a character + // literal. Using the unary + operator will trigger an integer promotion on + // the operand, which will then match an appropriate << operator that will + // output the integer representation. + out << +q.in(U{}) << " " << unit_label(U{}); return out; } diff --git a/au/io_test.cc b/au/io_test.cc index 00da12ef..c434da5a 100644 --- a/au/io_test.cc +++ b/au/io_test.cc @@ -14,6 +14,8 @@ #include "au/io.hh" +#include + #include "au/prefix.hh" #include "au/quantity.hh" #include "gtest/gtest.h" @@ -61,6 +63,14 @@ TEST(StreamingOutput, PrintsValueAndUnitLabel) { EXPECT_EQ(stream_to_string((feet / milli(second))(1.25)), "1.25 ft / ms"); } +TEST(StreamingOutput, PrintValueRepChar) { + // If the Rep resolves to a char, we sill want the number '65' to be output, + // not the character literal that corresponds to 65 ('A'). + static_assert(std::is_same::value, + "Expected 'int8_t' to resolve to 'char'"); + EXPECT_EQ(stream_to_string(feet(int8_t{65})), "65 ft"); +} + TEST(StreamingOutput, DistinguishesPointFromQuantityByAtSign) { EXPECT_EQ(stream_to_string(celsius_qty(20)), "20 deg C"); EXPECT_EQ(stream_to_string(celsius_pt(20)), "@(20 deg C)");