Operator << fix.

This commit is contained in:
John Ralls 2018-03-08 12:47:26 -08:00
parent 79dd7d69d0
commit c3180ab374
3 changed files with 24 additions and 6 deletions

View File

@ -1303,6 +1303,18 @@ main(int argc, char ** argv)
} }
#endif #endif
std::ostream&
operator<<(std::ostream& s, GncNumeric n)
{
std::basic_ostringstream<wchar_t> ss;
ss.imbue(s.getloc());
ss << n;
std::wstring_convert<std::codecvt_utf8<wchar_t>> make_utf8;
s << make_utf8.to_bytes(ss.str());
return s;
}
const char* gnc_numeric_errorCode_to_string(GNCNumericErrorCode error_code) const char* gnc_numeric_errorCode_to_string(GNCNumericErrorCode error_code)
{ {
switch (error_code) switch (error_code)

View File

@ -27,6 +27,7 @@
#include <iostream> #include <iostream>
#include <locale> #include <locale>
#include <typeinfo> // For std::bad_cast exception #include <typeinfo> // For std::bad_cast exception
#include <codecvt> // UTF-8 <--> UTF16 conversion
#include "gnc-rational-rounding.hpp" #include "gnc-rational-rounding.hpp"
class GncRational; class GncRational;
@ -339,6 +340,7 @@ inline GncNumeric operator/(int64_t a, GncNumeric b)
* decimal if the denominator is a multiple of 10, otherwise as * decimal if the denominator is a multiple of 10, otherwise as
* "numerator/denominator". * "numerator/denominator".
*/ */
std::ostream& operator<<(std::ostream&, GncNumeric);
/* Implementation adapted from "The C++ Standard Library, Second Edition" by /* Implementation adapted from "The C++ Standard Library, Second Edition" by
* Nicolai M. Josuttis, Addison-Wesley, 2012, ISBN 978-0-321-62321-8. * Nicolai M. Josuttis, Addison-Wesley, 2012, ISBN 978-0-321-62321-8.
@ -349,10 +351,10 @@ std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>&
std::basic_ostringstream<charT, traits> ss; std::basic_ostringstream<charT, traits> ss;
std::locale loc = s.getloc(); std::locale loc = s.getloc();
ss.imbue(loc); ss.imbue(loc);
char dec_pt = '.'; auto dec_pt = static_cast<charT>('.');
try try
{ {
dec_pt = std::use_facet<std::numpunct<char>>(loc).decimal_point(); dec_pt = std::use_facet<std::numpunct<charT>>(loc).decimal_point();
} }
catch(const std::bad_cast& err) {} //Don't do anything, num_sep is already set. catch(const std::bad_cast& err) {} //Don't do anything, num_sep is already set.
@ -369,7 +371,6 @@ std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>&
return s; return s;
} }
/** /**
* std::stream input operator. * std::stream input operator.
* *
@ -386,7 +387,7 @@ std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>&
template <typename charT, typename traits> template <typename charT, typename traits>
std::basic_istream<charT, traits>& operator>>(std::basic_istream<charT, traits>& s, GncNumeric& n) std::basic_istream<charT, traits>& operator>>(std::basic_istream<charT, traits>& s, GncNumeric& n)
{ {
std::string instr; std::basic_string<charT, traits> instr;
s >> instr; s >> instr;
if (s) if (s)
n = GncNumeric(instr, true); n = GncNumeric(instr, true);

View File

@ -213,10 +213,15 @@ TEST(gncnumeric_stream, output_stream)
EXPECT_EQ("123/456", output.str()); EXPECT_EQ("123/456", output.str());
try try
{ {
output.imbue(std::locale("fr_FR.utf8")); auto loc = std::locale("fr_FR.utf8");
auto thou_sep = std::use_facet<std::numpunct<wchar_t>>(loc).thousands_sep();
output.imbue(loc);
output.str(""); output.str("");
output << simple_int; output << simple_int;
EXPECT_EQ("123 456", output.str()); if (thou_sep == L' ')
EXPECT_EQ("123 456", output.str());
else
EXPECT_EQ("123\xe2\x80\xaf""456", output.str());
} }
catch (std::runtime_error) catch (std::runtime_error)
{ {