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 "../maths.hpp"
#include "../preprocessor.hpp"
#include "../stream.hpp"
#include <algorithm>
#include <cstdlib>
#include <iomanip>
///////////////////////////////////////////////////////////////////////////////
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<real_t>::digits10 << m_value.r << std::setprecision (old);
case SINT: return os << std::numeric_limits<sint_t>::digits10 << m_value.s << std::setprecision (old);
case UINT: return os << std::numeric_limits<uint_t>::digits10 << m_value.u << std::setprecision (old);
case REAL: return os << std::setprecision (std::numeric_limits<real_t>::digits10) << m_value.r;
case SINT: return os << std::setprecision (std::numeric_limits<sint_t>::digits10) << m_value.s;
case UINT: return os << std::setprecision (std::numeric_limits<uint_t>::digits10) << m_value.u;
}
unreachable ();

View File

@ -139,7 +139,9 @@ template <typename T>
std::ostream&
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;
}

View File

@ -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)
{

View File

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

View File

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