From 331924612e7cc91569194ceeede28e182369498b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Wed, 13 Apr 2022 14:14:01 +0200 Subject: [PATCH] Remove duplication by using templates --- src/types.cpp | 27 +++++++-------------------- unitTests/test_types.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/types.cpp b/src/types.cpp index 1bffafd9..91d586ca 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -211,7 +211,8 @@ std::ostream& operator<<(std::ostream& os, const Rational& r) { return os << r.first << "/" << r.second; } -std::istream& operator>>(std::istream& is, Rational& r) { +template +std::istream& fromStreamToRational(std::istream& is, T& r) { // http://dev.exiv2.org/boards/3/topics/1912?r=1915 if (std::tolower(is.peek()) == 'f') { char F = 0; @@ -232,30 +233,16 @@ std::istream& operator>>(std::istream& is, Rational& r) { return is; } +std::istream& operator>>(std::istream& is, Rational& r) { + return fromStreamToRational(is, r); +} + std::ostream& operator<<(std::ostream& os, const URational& r) { return os << r.first << "/" << r.second; } std::istream& operator>>(std::istream& is, URational& r) { - // http://dev.exiv2.org/boards/3/topics/1912?r=1915 - /// \todo This implementation seems to be duplicated for the Rational type. Try to remove duplication - if (std::tolower(is.peek()) == 'f') { - char F = 0; - float f = 0.F; - is >> F >> f; - f = 2.0F * std::log(f) / std::log(2.0F); - r = Exiv2::floatToRationalCast(f); - } else { - uint32_t nominator = 0; - uint32_t denominator = 0; - char c('\0'); - is >> nominator >> c >> denominator; - if (c != '/') - is.setstate(std::ios::failbit); - if (is) - r = {nominator, denominator}; - } - return is; + return fromStreamToRational(is, r); } uint16_t getUShort(const byte* buf, ByteOrder byteOrder) { diff --git a/unitTests/test_types.cpp b/unitTests/test_types.cpp index dba9e04f..2ef75cdf 100644 --- a/unitTests/test_types.cpp +++ b/unitTests/test_types.cpp @@ -143,3 +143,33 @@ TEST(Rational, floatToRationalCast) { ASSERT_EQ(minus_inf.first, -1); ASSERT_EQ(minus_inf.second, 0); } + +TEST(Rational, toStream) { + Rational r = {1,2}; + std::stringstream str; + str << r; + ASSERT_EQ("1/2", str.str()); +} + +TEST(Rational, readRationalFromStream) { + Rational r; + std::istringstream input("1/2"); + input >> r; + ASSERT_EQ(1, r.first); + ASSERT_EQ(2, r.second); +} + +TEST(URational, toStream) { + URational r = {1,2}; + std::stringstream str; + str << r; + ASSERT_EQ("1/2", str.str()); +} + +TEST(URational, readRationalFromStream) { + URational r; + std::istringstream input("1/2"); + input >> r; + ASSERT_EQ(1, r.first); + ASSERT_EQ(2, r.second); +}