mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-08 12:21: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 <memory>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
@@ -45,29 +46,23 @@ namespace YAML
|
||||
|
||||
// overloads of write
|
||||
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(float f);
|
||||
Emitter& Write(double d);
|
||||
Emitter& Write(const _Alias& alias);
|
||||
Emitter& Write(const _Anchor& anchor);
|
||||
Emitter& Write(const _Tag& tag);
|
||||
Emitter& Write(const _Comment& comment);
|
||||
Emitter& Write(const _Null& null);
|
||||
|
||||
template <typename T>
|
||||
Emitter& WriteIntegralType(T value);
|
||||
|
||||
template <typename T>
|
||||
Emitter& WriteStreamable(T value);
|
||||
|
||||
private:
|
||||
void PreWriteIntegralType(std::stringstream& str);
|
||||
void PostWriteIntegralType(const std::stringstream& str);
|
||||
|
||||
template <typename T>
|
||||
Emitter& WriteIntegralType(T value);
|
||||
|
||||
private:
|
||||
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);
|
||||
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
|
||||
template <typename T>
|
||||
inline Emitter& operator << (Emitter& emitter, T v) {
|
||||
return emitter.Write(v);
|
||||
}
|
||||
inline Emitter& operator << (Emitter& emitter, const std::string& v) { return emitter.Write(v); }
|
||||
inline Emitter& operator << (Emitter& emitter, bool 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) {
|
||||
return emitter.SetLocalValue(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline Emitter& operator << (Emitter& emitter, _Indent indent) {
|
||||
return emitter.SetLocalIndent(indent);
|
||||
}
|
||||
|
@@ -549,14 +549,6 @@ namespace YAML
|
||||
return *this;
|
||||
}
|
||||
|
||||
Emitter& Emitter::Write(const char *str)
|
||||
{
|
||||
if(!good())
|
||||
return *this;
|
||||
|
||||
return Write(std::string(str));
|
||||
}
|
||||
|
||||
void Emitter::PreWriteIntegralType(std::stringstream& str)
|
||||
{
|
||||
PreAtomicWrite();
|
||||
@@ -623,38 +615,6 @@ namespace YAML
|
||||
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)
|
||||
{
|
||||
if(!good())
|
||||
|
@@ -558,6 +558,74 @@ namespace Test
|
||||
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
|
||||
@@ -733,6 +801,10 @@ namespace Test
|
||||
RunEmitterTest(&Emitter::EscapedUnicode, "escaped unicode", passed, total);
|
||||
RunEmitterTest(&Emitter::Unicode, "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::ExtraEndMap, "extra EndMap", passed, total);
|
||||
|
Reference in New Issue
Block a user