stream: use scoped manipulators

This commit is contained in:
Danny Robson 2017-01-05 20:21:20 +11:00
parent 96f3bc14e6
commit e1aacef7a2
5 changed files with 111 additions and 41 deletions

View File

@ -24,11 +24,14 @@
#include "../io.hpp" #include "../io.hpp"
#include "../maths.hpp" #include "../maths.hpp"
#include "../preprocessor.hpp" #include "../preprocessor.hpp"
#include "../stream.hpp"
#include <algorithm> #include <algorithm>
#include <cstdlib> #include <cstdlib>
#include <iomanip> #include <iomanip>
///////////////////////////////////////////////////////////////////////////////
using json::tree::node; using json::tree::node;
using json::tree::object; using json::tree::object;
using json::tree::array; using json::tree::array;
@ -838,12 +841,12 @@ json::tree::number::clone (void) const
std::ostream& std::ostream&
json::tree::number::write (std::ostream &os) const json::tree::number::write (std::ostream &os) const
{ {
auto old = os.precision (); util::stream::scoped::precision p (os);
switch (m_repr) { switch (m_repr) {
case REAL: return os << std::numeric_limits<real_t>::digits10 << m_value.r << std::setprecision (old); case REAL: return os << std::setprecision (std::numeric_limits<real_t>::digits10) << m_value.r;
case SINT: return os << std::numeric_limits<sint_t>::digits10 << m_value.s << std::setprecision (old); case SINT: return os << std::setprecision (std::numeric_limits<sint_t>::digits10) << m_value.s;
case UINT: return os << std::numeric_limits<uint_t>::digits10 << m_value.u << std::setprecision (old); case UINT: return os << std::setprecision (std::numeric_limits<uint_t>::digits10) << m_value.u;
} }
unreachable (); unreachable ();

View File

@ -139,7 +139,9 @@ template <typename T>
std::ostream& std::ostream&
util::operator<< (std::ostream &os, parray<T> p) util::operator<< (std::ostream &os, parray<T> p)
{ {
os << "[" << p.size () << ", " << std::hex << p.data () << std::dec << "]"; auto size = p.size ();
uintptr_t ptr = reinterpret_cast<uintptr_t> (p.data ());
os << "[" << size << ", " << std::hex << ptr << std::dec << "]";
return os; return os;
} }

View File

@ -21,7 +21,50 @@
using util::stream::null_ostream; using util::stream::null_ostream;
using util::stream::bits; 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& std::ostream&
null_ostream::put (char) null_ostream::put (char)
{ {

View File

@ -18,48 +18,69 @@
#define __UTIL_STREAM_HPP #define __UTIL_STREAM_HPP
#include <ostream> #include <ostream>
#include <ios>
namespace util { namespace util::stream {
namespace stream { namespace scoped {
/////////////////////////////////////////////////////////////////////// #define SCOPED(NAME,TYPE) \
class null_streambuf : public std::basic_streambuf<char> { class NAME { \
public: public: \
virtual ~null_streambuf () { ; } 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<char> { class null_streambuf : public std::basic_streambuf<char> {
public: public:
virtual ~null_ostream () { ; } virtual ~null_streambuf () { ; }
};
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;
};
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
struct bits { class null_ostream : public std::basic_ostream<char> {
bits (uintmax_t value, unsigned count); public:
virtual ~null_ostream () { ; }
uintmax_t value; std::ostream & put (char c);
unsigned count; 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);
} }

View File

@ -20,6 +20,7 @@
#include <cstring> #include <cstring>
#include "io.hpp" #include "io.hpp"
#include "stream.hpp"
#include "hash/simple.hpp" #include "hash/simple.hpp"
@ -62,12 +63,12 @@ template <size_t S>
std::ostream& std::ostream&
print_digest (std::ostream &os, std::array<uint8_t,S> digest) print_digest (std::ostream &os, std::array<uint8_t,S> digest)
{ {
util::stream::scoped::flags f (os);
os << std::hex; os << std::hex;
for (auto c: digest) for (auto c: digest)
os << +(c >> 4) << +(c & 0x0F); os << +(c >> 4) << +(c & 0x0F);
os << std::dec;
return os; return os;
} }