#pragma once
#include "BuildSettings.h"
#include <ios>
#include <istream>
#include <ostream>
#include <sstream>
#include <streambuf>
OPENMPT_NAMESPACE_BEGIN
namespace mpt
{
#ifdef MPT_COMPILER_QUIRK_MSVC_STRINGSTREAM
class stringbuf
: public std::stringbuf
{
public:
stringbuf(std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
: std::stringbuf(mode)
{
return;
}
stringbuf(const std::string &str, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
: std::stringbuf(str, mode)
{
return;
}
public:
virtual pos_type seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out)
{
pos_type result = std::stringbuf::seekoff(off, way, which);
if(result == pos_type(-1))
{
if((which & std::ios_base::in) || (which & std::ios_base::out))
{
if(off == 0)
{
result = 0;
}
}
}
return result;
}
virtual pos_type seekpos(pos_type ptr, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
{
pos_type result = std::stringbuf::seekpos(ptr, mode);
if(result == pos_type(-1))
{
if((mode & std::ios_base::in) || (mode & std::ios_base::out))
{
if(static_cast<std::streamoff>(ptr) == 0)
{
result = 0;
}
}
}
return result;
}
};
class istringstream
: public std::basic_istream<char>
{
private:
mpt::stringbuf buf;
public:
istringstream(std::ios_base::openmode mode = std::ios_base::in)
: std::basic_istream<char>(&buf)
, buf(mode | std::ios_base::in)
{
}
istringstream(const std::string &str, std::ios_base::openmode mode = std::ios_base::in)
: std::basic_istream<char>(&buf)
, buf(str, mode | std::ios_base::in)
{
}
~istringstream()
{
}
public:
mpt::stringbuf *rdbuf() const { return const_cast<mpt::stringbuf*>(&buf); }
std::string str() const { return buf.str(); }
void str(const std::string &str) { buf.str(str); }
};
class ostringstream
: public std::basic_ostream<char>
{
private:
mpt::stringbuf buf;
public:
ostringstream(std::ios_base::openmode mode = std::ios_base::out)
: std::basic_ostream<char>(&buf)
, buf(mode | std::ios_base::out)
{
}
ostringstream(const std::string &str, std::ios_base::openmode mode = std::ios_base::out)
: std::basic_ostream<char>(&buf)
, buf(str, mode | std::ios_base::out)
{
}
~ostringstream()
{
}
public:
mpt::stringbuf *rdbuf() const { return const_cast<mpt::stringbuf*>(&buf); }
std::string str() const { return buf.str(); }
void str(const std::string &str) { buf.str(str); }
};
class stringstream
: public std::basic_iostream<char>
{
private:
mpt::stringbuf buf;
public:
stringstream(std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
: std::basic_iostream<char>(&buf)
, buf(mode | std::ios_base::in | std::ios_base::out)
{
}
stringstream(const std::string &str, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
: std::basic_iostream<char>(&buf)
, buf(str, mode | std::ios_base::in | std::ios_base::out)
{
}
~stringstream()
{
}
public:
mpt::stringbuf *rdbuf() const { return const_cast<mpt::stringbuf*>(&buf); }
std::string str() const { return buf.str(); }
void str(const std::string &str) { buf.str(str); }
};
#else
typedef std::stringbuf stringbuf;
typedef std::istringstream istringstream;
typedef std::ostringstream ostringstream;
typedef std::stringstream stringstream;
#endif
}
OPENMPT_NAMESPACE_END