Added float/double precision setters

This commit is contained in:
beder
2012-01-11 14:34:04 -06:00
parent 537063f907
commit 8f948b8f37
6 changed files with 118 additions and 2 deletions

View File

@@ -43,10 +43,13 @@ namespace YAML
bool SetIndent(unsigned n); bool SetIndent(unsigned n);
bool SetPreCommentIndent(unsigned n); bool SetPreCommentIndent(unsigned n);
bool SetPostCommentIndent(unsigned n); bool SetPostCommentIndent(unsigned n);
bool SetFloatPrecision(unsigned n);
bool SetDoublePrecision(unsigned n);
// local setters // local setters
Emitter& SetLocalValue(EMITTER_MANIP value); Emitter& SetLocalValue(EMITTER_MANIP value);
Emitter& SetLocalIndent(const _Indent& indent); Emitter& SetLocalIndent(const _Indent& indent);
Emitter& SetLocalPrecision(const _Precision& precision);
// overloads of write // overloads of write
Emitter& Write(const std::string& str); Emitter& Write(const std::string& str);
@@ -71,6 +74,10 @@ namespace YAML
void PostWriteIntegralType(const std::stringstream& str); void PostWriteIntegralType(const std::stringstream& str);
void PostWriteStreamable(const std::stringstream& str); void PostWriteStreamable(const std::stringstream& str);
template<typename T> void SetStreamablePrecision(std::stringstream&) {}
unsigned GetFloatPrecision() const;
unsigned GetDoublePrecision() const;
private: private:
void PreAtomicWrite(); void PreAtomicWrite();
bool GotoNextPreAtomicState(); bool GotoNextPreAtomicState();
@@ -118,11 +125,24 @@ namespace YAML
std::stringstream str; std::stringstream str;
PreWriteStreamable(str); PreWriteStreamable(str);
SetStreamablePrecision<T>(str);
str << value; str << value;
PostWriteStreamable(str); PostWriteStreamable(str);
return *this; return *this;
} }
template<>
inline void Emitter::SetStreamablePrecision<float>(std::stringstream& str)
{
str.precision(GetFloatPrecision());
}
template<>
inline void Emitter::SetStreamablePrecision<double>(std::stringstream& str)
{
str.precision(GetDoublePrecision());
}
// overloads of insertion // overloads of insertion
inline Emitter& operator << (Emitter& emitter, const std::string& 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, bool v) { return emitter.Write(v); }
@@ -156,6 +176,10 @@ namespace YAML
inline Emitter& operator << (Emitter& emitter, _Indent indent) { inline Emitter& operator << (Emitter& emitter, _Indent indent) {
return emitter.SetLocalIndent(indent); return emitter.SetLocalIndent(indent);
} }
inline Emitter& operator << (Emitter& emitter, _Precision precision) {
return emitter.SetLocalPrecision(precision);
}
} }
#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -135,6 +135,25 @@ namespace YAML
inline _Binary Binary(const unsigned char *data, std::size_t size) { inline _Binary Binary(const unsigned char *data, std::size_t size) {
return _Binary(data, size); return _Binary(data, size);
} }
struct _Precision {
_Precision(int floatPrecision_, int doublePrecision_): floatPrecision(floatPrecision_), doublePrecision(doublePrecision_) {}
int floatPrecision;
int doublePrecision;
};
inline _Precision FloatPrecision(unsigned n) {
return _Precision(n, -1);
}
inline _Precision DoublePrecision(unsigned n) {
return _Precision(-1, n);
}
inline _Precision Precision(unsigned n) {
return _Precision(n, n);
}
} }
#endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -94,6 +94,16 @@ namespace YAML
return m_pState->SetPostCommentIndent(n, GLOBAL); return m_pState->SetPostCommentIndent(n, GLOBAL);
} }
bool Emitter::SetFloatPrecision(unsigned n)
{
return m_pState->SetFloatPrecision(n, GLOBAL);
}
bool Emitter::SetDoublePrecision(unsigned n)
{
return m_pState->SetDoublePrecision(n, GLOBAL);
}
// SetLocalValue // SetLocalValue
// . Either start/end a group, or set a modifier locally // . Either start/end a group, or set a modifier locally
Emitter& Emitter::SetLocalValue(EMITTER_MANIP value) Emitter& Emitter::SetLocalValue(EMITTER_MANIP value)
@@ -145,6 +155,15 @@ namespace YAML
return *this; return *this;
} }
Emitter& Emitter::SetLocalPrecision(const _Precision& precision)
{
if(precision.floatPrecision >= 0)
m_pState->SetFloatPrecision(precision.floatPrecision, LOCAL);
if(precision.doublePrecision >= 0)
m_pState->SetDoublePrecision(precision.doublePrecision, LOCAL);
return *this;
}
// GotoNextPreAtomicState // GotoNextPreAtomicState
// . Runs the state machine, emitting if necessary, and returns 'true' if done (i.e., ready to emit an atom) // . Runs the state machine, emitting if necessary, and returns 'true' if done (i.e., ready to emit an atom)
bool Emitter::GotoNextPreAtomicState() bool Emitter::GotoNextPreAtomicState()
@@ -661,11 +680,20 @@ namespace YAML
} }
} }
void Emitter::PreWriteStreamable(std::stringstream& str) void Emitter::PreWriteStreamable(std::stringstream&)
{ {
PreAtomicWrite(); PreAtomicWrite();
EmitSeparationIfNecessary(); EmitSeparationIfNecessary();
str.precision(15); }
unsigned Emitter::GetFloatPrecision() const
{
return m_pState->GetFloatPrecision();
}
unsigned Emitter::GetDoublePrecision() const
{
return m_pState->GetDoublePrecision();
} }
void Emitter::PostWriteIntegralType(const std::stringstream& str) void Emitter::PostWriteIntegralType(const std::stringstream& str)

View File

@@ -1,5 +1,6 @@
#include "emitterstate.h" #include "emitterstate.h"
#include "yaml-cpp/exceptions.h" #include "yaml-cpp/exceptions.h"
#include <limits>
namespace YAML namespace YAML
{ {
@@ -21,6 +22,8 @@ namespace YAML
m_seqFmt.set(Block); m_seqFmt.set(Block);
m_mapFmt.set(Block); m_mapFmt.set(Block);
m_mapKeyFmt.set(Auto); m_mapKeyFmt.set(Auto);
m_floatPrecision.set(6);
m_doublePrecision.set(15);
} }
EmitterState::~EmitterState() EmitterState::~EmitterState()
@@ -261,5 +264,21 @@ namespace YAML
return false; return false;
} }
} }
bool EmitterState::SetFloatPrecision(unsigned value, FMT_SCOPE scope)
{
if(value > std::numeric_limits<float>::digits10)
return false;
_Set(m_floatPrecision, value, scope);
return true;
}
bool EmitterState::SetDoublePrecision(unsigned value, FMT_SCOPE scope)
{
if(value > std::numeric_limits<double>::digits10)
return false;
_Set(m_doublePrecision, value, scope);
return true;
}
} }

View File

@@ -146,6 +146,11 @@ namespace YAML
bool SetMapKeyFormat(EMITTER_MANIP value, FMT_SCOPE scope); bool SetMapKeyFormat(EMITTER_MANIP value, FMT_SCOPE scope);
EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); } EMITTER_MANIP GetMapKeyFormat() const { return m_mapKeyFmt.get(); }
bool SetFloatPrecision(unsigned value, FMT_SCOPE scope);
unsigned GetFloatPrecision() const { return m_floatPrecision.get(); }
bool SetDoublePrecision(unsigned value, FMT_SCOPE scope);
unsigned GetDoublePrecision() const { return m_doublePrecision.get(); }
private: private:
template <typename T> template <typename T>
void _Set(Setting<T>& fmt, T value, FMT_SCOPE scope); void _Set(Setting<T>& fmt, T value, FMT_SCOPE scope);
@@ -169,6 +174,8 @@ namespace YAML
Setting<EMITTER_MANIP> m_seqFmt; Setting<EMITTER_MANIP> m_seqFmt;
Setting<EMITTER_MANIP> m_mapFmt; Setting<EMITTER_MANIP> m_mapFmt;
Setting<EMITTER_MANIP> m_mapKeyFmt; Setting<EMITTER_MANIP> m_mapKeyFmt;
Setting<unsigned> m_floatPrecision;
Setting<unsigned> m_doublePrecision;
SettingChanges m_modifiedSettings; SettingChanges m_modifiedSettings;
SettingChanges m_globalModifiedSettings; SettingChanges m_globalModifiedSettings;

View File

@@ -875,6 +875,23 @@ namespace Test
desiredOutput = "- a\n- \":\"\n- \"\\x10\"\n- \"\\n\"\n- \" \"\n- \"\\t\""; desiredOutput = "- a\n- \":\"\n- \"\\x10\"\n- \"\\n\"\n- \" \"\n- \"\\t\"";
} }
void DefaultPrecision(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginSeq;
out << 1.234f;
out << 3.14159265358979;
out << YAML::EndSeq;
desiredOutput = "- 1.234\n- 3.14159265358979";
}
void SetPrecision(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginSeq;
out << YAML::FloatPrecision(3) << 1.234f;
out << YAML::DoublePrecision(6) << 3.14159265358979;
out << YAML::EndSeq;
desiredOutput = "- 1.23\n- 3.14159";
}
//////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////
// incorrect emitting // incorrect emitting
@@ -1094,6 +1111,8 @@ namespace Test
RunEmitterTest(&Emitter::ImplicitDocStart, "implicit doc start", passed, total); RunEmitterTest(&Emitter::ImplicitDocStart, "implicit doc start", passed, total);
RunEmitterTest(&Emitter::EmptyString, "empty string", passed, total); RunEmitterTest(&Emitter::EmptyString, "empty string", passed, total);
RunEmitterTest(&Emitter::SingleChar, "single char", passed, total); RunEmitterTest(&Emitter::SingleChar, "single char", passed, total);
RunEmitterTest(&Emitter::DefaultPrecision, "default precision", passed, total);
RunEmitterTest(&Emitter::SetPrecision, "set precision", 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);