mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 12:41:17 +00:00
Refactored emitter operator << overloads to not template them, so it's easier to overload for pointer types
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
#include "null.h"
|
#include "null.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
@@ -45,29 +46,23 @@ namespace YAML
|
|||||||
|
|
||||||
// overloads of write
|
// overloads of write
|
||||||
Emitter& Write(const std::string& str);
|
Emitter& Write(const std::string& str);
|
||||||
Emitter& Write(const char *str);
|
|
||||||
Emitter& Write(int value) { return WriteIntegralType(value); }
|
|
||||||
Emitter& Write(unsigned int value) { return WriteIntegralType(value); }
|
|
||||||
Emitter& Write(short value) { return WriteIntegralType(value); }
|
|
||||||
Emitter& Write(unsigned short value) { return WriteIntegralType(value); }
|
|
||||||
Emitter& Write(long value) { return WriteIntegralType(value); }
|
|
||||||
Emitter& Write(unsigned long value) { return WriteIntegralType(value); }
|
|
||||||
Emitter& Write(bool b);
|
Emitter& Write(bool b);
|
||||||
Emitter& Write(float f);
|
|
||||||
Emitter& Write(double d);
|
|
||||||
Emitter& Write(const _Alias& alias);
|
Emitter& Write(const _Alias& alias);
|
||||||
Emitter& Write(const _Anchor& anchor);
|
Emitter& Write(const _Anchor& anchor);
|
||||||
Emitter& Write(const _Tag& tag);
|
Emitter& Write(const _Tag& tag);
|
||||||
Emitter& Write(const _Comment& comment);
|
Emitter& Write(const _Comment& comment);
|
||||||
Emitter& Write(const _Null& null);
|
Emitter& Write(const _Null& null);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Emitter& WriteIntegralType(T value);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Emitter& WriteStreamable(T value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void PreWriteIntegralType(std::stringstream& str);
|
void PreWriteIntegralType(std::stringstream& str);
|
||||||
void PostWriteIntegralType(const std::stringstream& str);
|
void PostWriteIntegralType(const std::stringstream& str);
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Emitter& WriteIntegralType(T value);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum ATOMIC_TYPE { AT_SCALAR, AT_SEQ, AT_BLOCK_SEQ, AT_FLOW_SEQ, AT_MAP, AT_BLOCK_MAP, AT_FLOW_MAP };
|
enum ATOMIC_TYPE { AT_SCALAR, AT_SEQ, AT_BLOCK_SEQ, AT_FLOW_SEQ, AT_MAP, AT_BLOCK_MAP, AT_FLOW_MAP };
|
||||||
|
|
||||||
@@ -100,19 +95,49 @@ namespace YAML
|
|||||||
PostWriteIntegralType(str);
|
PostWriteIntegralType(str);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline Emitter& Emitter::WriteStreamable(T value)
|
||||||
|
{
|
||||||
|
if(!good())
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
PreAtomicWrite();
|
||||||
|
EmitSeparationIfNecessary();
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
str << value;
|
||||||
|
m_stream << str.str();
|
||||||
|
|
||||||
|
PostAtomicWrite();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
// overloads of insertion
|
// overloads of insertion
|
||||||
template <typename T>
|
inline Emitter& operator << (Emitter& emitter, const std::string& v) { return emitter.Write(v); }
|
||||||
inline Emitter& operator << (Emitter& emitter, T v) {
|
inline Emitter& operator << (Emitter& emitter, bool v) { return emitter.Write(v); }
|
||||||
return emitter.Write(v);
|
inline Emitter& operator << (Emitter& emitter, const _Alias& v) { return emitter.Write(v); }
|
||||||
}
|
inline Emitter& operator << (Emitter& emitter, const _Anchor& v) { return emitter.Write(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, const _Tag& v) { return emitter.Write(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, const _Comment& v) { return emitter.Write(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, const _Null& v) { return emitter.Write(v); }
|
||||||
|
|
||||||
|
inline Emitter& operator << (Emitter& emitter, const char *v) { return emitter.Write(std::string(v)); }
|
||||||
|
|
||||||
|
inline Emitter& operator << (Emitter& emitter, int v) { return emitter.WriteIntegralType(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, unsigned int v) { return emitter.WriteIntegralType(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, short v) { return emitter.WriteIntegralType(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, unsigned short v) { return emitter.WriteIntegralType(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, long v) { return emitter.WriteIntegralType(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, unsigned long v) { return emitter.WriteIntegralType(v); }
|
||||||
|
|
||||||
|
inline Emitter& operator << (Emitter& emitter, float v) { return emitter.WriteStreamable(v); }
|
||||||
|
inline Emitter& operator << (Emitter& emitter, double v) { return emitter.WriteStreamable(v); }
|
||||||
|
|
||||||
template <>
|
|
||||||
inline Emitter& operator << (Emitter& emitter, EMITTER_MANIP value) {
|
inline Emitter& operator << (Emitter& emitter, EMITTER_MANIP value) {
|
||||||
return emitter.SetLocalValue(value);
|
return emitter.SetLocalValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
inline Emitter& operator << (Emitter& emitter, _Indent indent) {
|
inline Emitter& operator << (Emitter& emitter, _Indent indent) {
|
||||||
return emitter.SetLocalIndent(indent);
|
return emitter.SetLocalIndent(indent);
|
||||||
}
|
}
|
||||||
|
@@ -549,14 +549,6 @@ namespace YAML
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Emitter& Emitter::Write(const char *str)
|
|
||||||
{
|
|
||||||
if(!good())
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
return Write(std::string(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Emitter::PreWriteIntegralType(std::stringstream& str)
|
void Emitter::PreWriteIntegralType(std::stringstream& str)
|
||||||
{
|
{
|
||||||
PreAtomicWrite();
|
PreAtomicWrite();
|
||||||
@@ -623,38 +615,6 @@ namespace YAML
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Emitter& Emitter::Write(float f)
|
|
||||||
{
|
|
||||||
if(!good())
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
PreAtomicWrite();
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
|
|
||||||
std::stringstream str;
|
|
||||||
str << f;
|
|
||||||
m_stream << str.str();
|
|
||||||
|
|
||||||
PostAtomicWrite();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Emitter& Emitter::Write(double d)
|
|
||||||
{
|
|
||||||
if(!good())
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
PreAtomicWrite();
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
|
|
||||||
std::stringstream str;
|
|
||||||
str << d;
|
|
||||||
m_stream << str.str();
|
|
||||||
|
|
||||||
PostAtomicWrite();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Emitter& Emitter::Write(const _Alias& alias)
|
Emitter& Emitter::Write(const _Alias& alias)
|
||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
|
@@ -558,6 +558,74 @@ namespace Test
|
|||||||
desiredOutput = "--- \"\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2\"";
|
desiredOutput = "--- \"\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Foo {
|
||||||
|
Foo(): x(0) {}
|
||||||
|
Foo(int x_, const std::string& bar_): x(x_), bar(bar_) {}
|
||||||
|
|
||||||
|
int x;
|
||||||
|
std::string bar;
|
||||||
|
};
|
||||||
|
|
||||||
|
YAML::Emitter& operator << (YAML::Emitter& out, const Foo& foo) {
|
||||||
|
out << YAML::BeginMap;
|
||||||
|
out << YAML::Key << "x" << YAML::Value << foo.x;
|
||||||
|
out << YAML::Key << "bar" << YAML::Value << foo.bar;
|
||||||
|
out << YAML::EndMap;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserType(YAML::Emitter& out, std::string& desiredOutput)
|
||||||
|
{
|
||||||
|
out << YAML::BeginSeq;
|
||||||
|
out << Foo(5, "hello");
|
||||||
|
out << Foo(3, "goodbye");
|
||||||
|
out << YAML::EndSeq;
|
||||||
|
|
||||||
|
desiredOutput = "---\n-\n x: 5\n bar: hello\n-\n x: 3\n bar: goodbye";
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserTypeInContainer(YAML::Emitter& out, std::string& desiredOutput)
|
||||||
|
{
|
||||||
|
std::vector<Foo> fv;
|
||||||
|
fv.push_back(Foo(5, "hello"));
|
||||||
|
fv.push_back(Foo(3, "goodbye"));
|
||||||
|
out << fv;
|
||||||
|
|
||||||
|
desiredOutput = "---\n-\n x: 5\n bar: hello\n-\n x: 3\n bar: goodbye";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
YAML::Emitter& operator << (YAML::Emitter& out, const T *v) {
|
||||||
|
if(v)
|
||||||
|
out << *v;
|
||||||
|
else
|
||||||
|
out << YAML::Null;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointerToInt(YAML::Emitter& out, std::string& desiredOutput)
|
||||||
|
{
|
||||||
|
int foo = 5;
|
||||||
|
int *bar = &foo;
|
||||||
|
int *baz = 0;
|
||||||
|
out << YAML::BeginSeq;
|
||||||
|
out << bar << baz;
|
||||||
|
out << YAML::EndSeq;
|
||||||
|
|
||||||
|
desiredOutput = "---\n- 5\n- ~";
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointerToUserType(YAML::Emitter& out, std::string& desiredOutput)
|
||||||
|
{
|
||||||
|
Foo foo(5, "hello");
|
||||||
|
Foo *bar = &foo;
|
||||||
|
Foo *baz = 0;
|
||||||
|
out << YAML::BeginSeq;
|
||||||
|
out << bar << baz;
|
||||||
|
out << YAML::EndSeq;
|
||||||
|
|
||||||
|
desiredOutput = "---\n-\n x: 5\n bar: hello\n- ~";
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// incorrect emitting
|
// incorrect emitting
|
||||||
@@ -733,6 +801,10 @@ namespace Test
|
|||||||
RunEmitterTest(&Emitter::EscapedUnicode, "escaped unicode", passed, total);
|
RunEmitterTest(&Emitter::EscapedUnicode, "escaped unicode", passed, total);
|
||||||
RunEmitterTest(&Emitter::Unicode, "unicode", passed, total);
|
RunEmitterTest(&Emitter::Unicode, "unicode", passed, total);
|
||||||
RunEmitterTest(&Emitter::DoubleQuotedUnicode, "double quoted unicode", passed, total);
|
RunEmitterTest(&Emitter::DoubleQuotedUnicode, "double quoted unicode", passed, total);
|
||||||
|
RunEmitterTest(&Emitter::UserType, "user type", passed, total);
|
||||||
|
RunEmitterTest(&Emitter::UserTypeInContainer, "user type in container", passed, total);
|
||||||
|
RunEmitterTest(&Emitter::PointerToInt, "pointer to int", passed, total);
|
||||||
|
RunEmitterTest(&Emitter::PointerToUserType, "pointer to user type", passed, total);
|
||||||
|
|
||||||
RunEmitterErrorTest(&Emitter::ExtraEndSeq, "extra EndSeq", passed, total);
|
RunEmitterErrorTest(&Emitter::ExtraEndSeq, "extra EndSeq", passed, total);
|
||||||
RunEmitterErrorTest(&Emitter::ExtraEndMap, "extra EndMap", passed, total);
|
RunEmitterErrorTest(&Emitter::ExtraEndMap, "extra EndMap", passed, total);
|
||||||
|
Reference in New Issue
Block a user