Add string_stream
This commit is contained in:
parent
59314b6d95
commit
c4f2b74e99
142
include/mtl/string_stream.hpp
Normal file
142
include/mtl/string_stream.hpp
Normal file
@ -0,0 +1,142 @@
|
||||
#pragma once
|
||||
|
||||
#include "mtl/stream.hpp"
|
||||
#include "mtl/string.hpp"
|
||||
|
||||
namespace mtl {
|
||||
|
||||
/**
|
||||
* \brief Basic string builder
|
||||
*
|
||||
* Mimics std::stringstream basic functionality. Does not provide thorough
|
||||
* formatting options, only decimal/hexadecimal switching. If more extensive
|
||||
* formatting is needed, use mtl::string_streamx instead.
|
||||
*
|
||||
* Variables are piped to the stream using operator<<. The string is buffered
|
||||
* until flush is called, mtl::flush is piped, or mtl::endl is piped.
|
||||
*/
|
||||
class string_stream {
|
||||
istring& m_str;
|
||||
bool m_hex = false;
|
||||
|
||||
public:
|
||||
string_stream(istring& str) : m_str(str) {}
|
||||
|
||||
/**
|
||||
* \brief Flushes the buffer to the underlying output sequence and
|
||||
* clears the buffer
|
||||
*
|
||||
* By default simply clears the buffer, but can be overriden to
|
||||
* provide more functionality. This function is called internally when
|
||||
* mtl::flush and mtl::endl are piped to the stream. The derived
|
||||
* class must be sure to clear the buffer when finished.
|
||||
*/
|
||||
virtual void flush() {
|
||||
m_str.clear();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
m_str.clear();
|
||||
}
|
||||
|
||||
string_stream& operator<<(const string_view& str) {
|
||||
m_str.append(str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string_stream& operator<<(char ch) {
|
||||
m_str += ch;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Appends the signed integer x
|
||||
*
|
||||
* Writes the integer in decimal if the stream was piped mtl::dec,
|
||||
* hexidecimal if the stream was piped mtl::hex. Defaults to mtl::dec.
|
||||
*
|
||||
* The template does not need to check that the integer is a boolean
|
||||
* because booleans are not signed.
|
||||
*/
|
||||
template <typename T, std::enable_if_t<std::is_signed_v<T>, bool> = true>
|
||||
string_stream& operator<<(T x) {
|
||||
string<16> str;
|
||||
m_str.append(to_string(x, str, m_hex));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Appends the unsigned integer x
|
||||
*
|
||||
* Writes the integer in decimal if the stream was piped mtl::dec,
|
||||
* hexidecimal if the stream was piped mtl::hex. Defaults to mtl::dec.
|
||||
*
|
||||
* The template must check that the integer is not a boolean because
|
||||
* std::is_unsigned counts booleans as unsigned integers.
|
||||
*/
|
||||
template <typename T, std::enable_if_t<std::is_unsigned_v<T> && !std::is_same_v<T, bool>, bool> = true>
|
||||
string_stream& operator<<(T x) {
|
||||
string<16> str;
|
||||
m_str.append(to_string(x, str, m_hex));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Appends the boolean x
|
||||
*
|
||||
* Writes the boolean as either "true" or "false".
|
||||
*
|
||||
* This function needs to be templated otherwise non-boolean arguments
|
||||
* might be implicitly converted to boolean. Ex. const char* would be
|
||||
* implicitly converted to boolean instead of mtl::string_view.
|
||||
*/
|
||||
template <typename T, std::enable_if_t<std::is_same_v<T, bool>, bool> = true>
|
||||
string_stream& operator<<(T x) {
|
||||
m_str.append(x ? "true" : "false");
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Appends the address of the pointer addr
|
||||
*
|
||||
* Always writes the address is hexidecimal format. Does not pad the
|
||||
* value to the address width.
|
||||
*
|
||||
* The template must check that the pointer is not a character pointer
|
||||
* otherwise C strings will not be converted to a mtl::string_view and
|
||||
* the address of the string will be printed instead.
|
||||
*/
|
||||
template <typename T, std::enable_if_t<std::is_pointer_v<T>
|
||||
&& !std::is_same_v<T, char*>
|
||||
&& !std::is_same_v<T, const char*>, bool> = true>
|
||||
string_stream& operator<<(T addr) {
|
||||
string<16> str;
|
||||
m_str.append(to_string(addr, str));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
string_stream& operator<<(_flush) {
|
||||
flush();
|
||||
return *this;
|
||||
}
|
||||
string_stream& operator<<(_endl) {
|
||||
m_str += '\n';
|
||||
flush();
|
||||
return *this;
|
||||
}
|
||||
|
||||
string_stream& operator<<(_dec) {
|
||||
m_hex = false;
|
||||
return *this;
|
||||
}
|
||||
string_stream& operator<<(_hex) {
|
||||
m_hex = true;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mtl
|
||||
Loading…
x
Reference in New Issue
Block a user