Skip to content

Commit

Permalink
Correctly stream out quantities with a char Rep (#218)
Browse files Browse the repository at this point in the history
Quantities that have a `char` `Rep` will have the resulting raw number
streamed as a `char`.  Given that a Quantity is a number, users would
expect that a the value would be streamed as the integral number, not
interpreted as a character code.
  • Loading branch information
hoffbrinkle committed Feb 6, 2024
1 parent 4ab84ce commit 5c65e4f
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 1 deletion.
7 changes: 6 additions & 1 deletion au/io.hh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ namespace au {
// Streaming output support for Quantity types.
template <typename U, typename R>
std::ostream &operator<<(std::ostream &out, const Quantity<U, R> &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;
}

Expand Down
10 changes: 10 additions & 0 deletions au/io_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#include "au/io.hh"

#include <cstdint>

#include "au/prefix.hh"
#include "au/quantity.hh"
#include "gtest/gtest.h"
Expand Down Expand Up @@ -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<int8_t, signed char>::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)");
Expand Down

0 comments on commit 5c65e4f

Please sign in to comment.