From e1aacef7a26eee437168705ca8c53d9b057a4baf Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Thu, 5 Jan 2017 20:21:20 +1100 Subject: [PATCH] stream: use scoped manipulators --- json/tree.cpp | 11 +++--- pascal.cpp | 4 ++- stream.cpp | 43 ++++++++++++++++++++++++ stream.hpp | 91 +++++++++++++++++++++++++++++++------------------- tools/hash.cpp | 3 +- 5 files changed, 111 insertions(+), 41 deletions(-) diff --git a/json/tree.cpp b/json/tree.cpp index cd752469..770511cb 100644 --- a/json/tree.cpp +++ b/json/tree.cpp @@ -24,11 +24,14 @@ #include "../io.hpp" #include "../maths.hpp" #include "../preprocessor.hpp" +#include "../stream.hpp" #include #include #include + +/////////////////////////////////////////////////////////////////////////////// using json::tree::node; using json::tree::object; using json::tree::array; @@ -838,12 +841,12 @@ json::tree::number::clone (void) const std::ostream& json::tree::number::write (std::ostream &os) const { - auto old = os.precision (); + util::stream::scoped::precision p (os); switch (m_repr) { - case REAL: return os << std::numeric_limits::digits10 << m_value.r << std::setprecision (old); - case SINT: return os << std::numeric_limits::digits10 << m_value.s << std::setprecision (old); - case UINT: return os << std::numeric_limits::digits10 << m_value.u << std::setprecision (old); + case REAL: return os << std::setprecision (std::numeric_limits::digits10) << m_value.r; + case SINT: return os << std::setprecision (std::numeric_limits::digits10) << m_value.s; + case UINT: return os << std::setprecision (std::numeric_limits::digits10) << m_value.u; } unreachable (); diff --git a/pascal.cpp b/pascal.cpp index 4ac5af3b..2dd171c1 100644 --- a/pascal.cpp +++ b/pascal.cpp @@ -139,7 +139,9 @@ template std::ostream& util::operator<< (std::ostream &os, parray p) { - os << "[" << p.size () << ", " << std::hex << p.data () << std::dec << "]"; + auto size = p.size (); + uintptr_t ptr = reinterpret_cast (p.data ()); + os << "[" << size << ", " << std::hex << ptr << std::dec << "]"; return os; } diff --git a/stream.cpp b/stream.cpp index 89e19160..f1e5fb2d 100644 --- a/stream.cpp +++ b/stream.cpp @@ -21,7 +21,50 @@ using util::stream::null_ostream; using util::stream::bits; + +/////////////////////////////////////////////////////////////////////////////// +util::stream::scoped::flags::flags (std::ios_base &_ios): + m_ios (_ios), + m_state (_ios.flags ()) +{ ; } + + //----------------------------------------------------------------------------- +util::stream::scoped::flags::~flags () +{ + m_ios.flags (m_state); +} + + +/////////////////////////////////////////////////////////////////////////////// +util::stream::scoped::precision::precision (std::ios_base &_ios): + m_ios (_ios), + m_state (_ios.precision ()) +{ ; } + + +//----------------------------------------------------------------------------- +util::stream::scoped::precision::~precision () +{ + m_ios.precision (m_state); +} + + +/////////////////////////////////////////////////////////////////////////////// +util::stream::scoped::width::width (std::ios_base &_ios): + m_ios (_ios), + m_state (_ios.width ()) +{ ; } + + +//----------------------------------------------------------------------------- +util::stream::scoped::width::~width () +{ + m_ios.width (m_state); +} + + +/////////////////////////////////////////////////////////////////////////////// std::ostream& null_ostream::put (char) { diff --git a/stream.hpp b/stream.hpp index 4de72a5d..b438b2de 100644 --- a/stream.hpp +++ b/stream.hpp @@ -18,48 +18,69 @@ #define __UTIL_STREAM_HPP #include +#include -namespace util { - namespace stream { - /////////////////////////////////////////////////////////////////////// - class null_streambuf : public std::basic_streambuf { - public: - virtual ~null_streambuf () { ; } - }; +namespace util::stream { + namespace scoped { + #define SCOPED(NAME,TYPE) \ + class NAME { \ + public: \ + NAME (std::ios_base&); \ + ~NAME (); \ + \ + private: \ + std::ios_base &m_ios; \ + TYPE m_state; \ + } + + SCOPED(flags, std::ios_base::fmtflags); + SCOPED(precision, std::streamsize); + SCOPED(width, std::streamsize); + + #undef SCOPED + }; - /////////////////////////////////////////////////////////////////////// - class null_ostream : public std::basic_ostream { - public: - virtual ~null_ostream () { ; } - - std::ostream & put (char c); - std::ostream & write (const char *s, std::streamsize n); - - std::streampos tellp (void); - std::ostream & seekp (std::streampos pos); - std::ostream & seekp (std::streamoff off, - std::ios_base::seekdir dir); - - std::ostream & flush (void); - - bool good (void) const; - bool bad (void) const; - bool eof (void) const; - bool fail (void) const; - }; + /////////////////////////////////////////////////////////////////////////// + class null_streambuf : public std::basic_streambuf { + public: + virtual ~null_streambuf () { ; } + }; - /////////////////////////////////////////////////////////////////////// - struct bits { - bits (uintmax_t value, unsigned count); + /////////////////////////////////////////////////////////////////////////// + class null_ostream : public std::basic_ostream { + public: + virtual ~null_ostream () { ; } - uintmax_t value; - unsigned count; - }; + std::ostream & put (char c); + std::ostream & write (const char *s, std::streamsize n); - std::ostream& operator<< (std::ostream&, bits); - } + std::streampos tellp (void); + std::ostream & seekp (std::streampos pos); + std::ostream & seekp (std::streamoff off, + std::ios_base::seekdir dir); + + std::ostream & flush (void); + + bool good (void) const; + bool bad (void) const; + bool eof (void) const; + bool fail (void) const; + }; + + + /////////////////////////////////////////////////////////////////////////// + struct bits { + bits (uintmax_t value, unsigned count); + + uintmax_t value; + unsigned count; + }; + + + //--------------------------------------------------------------------- + std::ostream& operator<< (std::ostream&, bits); } diff --git a/tools/hash.cpp b/tools/hash.cpp index 1176b321..91c92556 100644 --- a/tools/hash.cpp +++ b/tools/hash.cpp @@ -20,6 +20,7 @@ #include #include "io.hpp" +#include "stream.hpp" #include "hash/simple.hpp" @@ -62,12 +63,12 @@ template std::ostream& print_digest (std::ostream &os, std::array digest) { + util::stream::scoped::flags f (os); os << std::hex; for (auto c: digest) os << +(c >> 4) << +(c & 0x0F); - os << std::dec; return os; }