| #ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 | |
| #define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 | |
| #if defined(_MSC_VER) || \ | |
| (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ | |
| (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 | |
| #pragma once | |
| #endif | |
| #include <cmath> | |
| #include <cstddef> | |
| #include <cstring> | |
| #include <limits> | |
| #include <memory> | |
| #include <sstream> | |
| #include <string> | |
| #include <type_traits> | |
| #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) | |
| #include <string_view> | |
| #endif | |
| #include "yaml-cpp/binary.h" | |
| #include "yaml-cpp/dll.h" | |
| #include "yaml-cpp/emitterdef.h" | |
| #include "yaml-cpp/emittermanip.h" | |
| #include "yaml-cpp/null.h" | |
| #include "yaml-cpp/ostream_wrapper.h" | |
| #include "yaml-cpp/fptostring.h" | |
| namespace YAML { | |
| class Binary; | |
| struct _Null; | |
| } // namespace YAML | |
| namespace YAML { | |
| class EmitterState; | |
| class YAML_CPP_API Emitter { | |
| public: | |
| Emitter(); | |
| explicit Emitter(std::ostream& stream); | |
| Emitter(const Emitter&) = delete; | |
| Emitter& operator=(const Emitter&) = delete; | |
| ~Emitter(); | |
| // output | |
| const char* c_str() const; | |
| std::size_t size() const; | |
| // state checking | |
| bool good() const; | |
| const std::string GetLastError() const; | |
| // global setters | |
| bool SetOutputCharset(EMITTER_MANIP value); | |
| bool SetStringFormat(EMITTER_MANIP value); | |
| bool SetBoolFormat(EMITTER_MANIP value); | |
| bool SetNullFormat(EMITTER_MANIP value); | |
| bool SetIntBase(EMITTER_MANIP value); | |
| bool SetSeqFormat(EMITTER_MANIP value); | |
| bool SetMapFormat(EMITTER_MANIP value); | |
| bool SetIndent(std::size_t n); | |
| bool SetPreCommentIndent(std::size_t n); | |
| bool SetPostCommentIndent(std::size_t n); | |
| bool SetFloatPrecision(std::size_t n); | |
| bool SetDoublePrecision(std::size_t n); | |
| void RestoreGlobalModifiedSettings(); | |
| // local setters | |
| Emitter& SetLocalValue(EMITTER_MANIP value); | |
| Emitter& SetLocalIndent(const _Indent& indent); | |
| Emitter& SetLocalPrecision(const _Precision& precision); | |
| // overloads of write | |
| Emitter& Write(const char* str, std::size_t size); | |
| Emitter& Write(const std::string& str); | |
| Emitter& Write(bool b); | |
| Emitter& Write(char ch); | |
| Emitter& Write(const _Alias& alias); | |
| Emitter& Write(const _Anchor& anchor); | |
| Emitter& Write(const _Tag& tag); | |
| Emitter& Write(const _Comment& comment); | |
| Emitter& Write(const _Null& n); | |
| Emitter& Write(const Binary& binary); | |
| template <typename T> | |
| Emitter& WriteIntegralType(T value); | |
| template <typename T> | |
| Emitter& WriteStreamable(T value); | |
| private: | |
| template <typename T> | |
| void SetStreamablePrecision(std::stringstream&) {} | |
| std::size_t GetFloatPrecision() const; | |
| std::size_t GetDoublePrecision() const; | |
| void PrepareIntegralStream(std::stringstream& stream) const; | |
| void StartedScalar(); | |
| private: | |
| void EmitBeginDoc(); | |
| void EmitEndDoc(); | |
| void EmitBeginSeq(); | |
| void EmitEndSeq(); | |
| void EmitBeginMap(); | |
| void EmitEndMap(); | |
| void EmitNewline(); | |
| void EmitKindTag(); | |
| void EmitTag(bool verbatim, const _Tag& tag); | |
| void PrepareNode(EmitterNodeType::value child); | |
| void PrepareTopNode(EmitterNodeType::value child); | |
| void FlowSeqPrepareNode(EmitterNodeType::value child); | |
| void BlockSeqPrepareNode(EmitterNodeType::value child); | |
| void FlowMapPrepareNode(EmitterNodeType::value child); | |
| void FlowMapPrepareLongKey(EmitterNodeType::value child); | |
| void FlowMapPrepareLongKeyValue(EmitterNodeType::value child); | |
| void FlowMapPrepareSimpleKey(EmitterNodeType::value child); | |
| void FlowMapPrepareSimpleKeyValue(EmitterNodeType::value child); | |
| void BlockMapPrepareNode(EmitterNodeType::value child); | |
| void BlockMapPrepareLongKey(EmitterNodeType::value child); | |
| void BlockMapPrepareLongKeyValue(EmitterNodeType::value child); | |
| void BlockMapPrepareSimpleKey(EmitterNodeType::value child); | |
| void BlockMapPrepareSimpleKeyValue(EmitterNodeType::value child); | |
| void SpaceOrIndentTo(bool requireSpace, std::size_t indent); | |
| const char* ComputeFullBoolName(bool b) const; | |
| const char* ComputeNullName() const; | |
| bool CanEmitNewline() const; | |
| private: | |
| std::unique_ptr<EmitterState> m_pState; | |
| ostream_wrapper m_stream; | |
| }; | |
| template <typename T> | |
| inline Emitter& Emitter::WriteIntegralType(T value) { | |
| if (!good()) | |
| return *this; | |
| PrepareNode(EmitterNodeType::Scalar); | |
| std::stringstream stream; | |
| stream.imbue(std::locale::classic()); | |
| PrepareIntegralStream(stream); | |
| stream << value; | |
| m_stream << stream.str(); | |
| StartedScalar(); | |
| return *this; | |
| } | |
| template <typename T> | |
| inline Emitter& Emitter::WriteStreamable(T value) { | |
| if (!good()) | |
| return *this; | |
| PrepareNode(EmitterNodeType::Scalar); | |
| std::stringstream stream; | |
| stream.imbue(std::locale::classic()); | |
| SetStreamablePrecision<T>(stream); | |
| bool special = false; | |
| if (std::is_floating_point<T>::value) { | |
| if ((std::numeric_limits<T>::has_quiet_NaN || | |
| std::numeric_limits<T>::has_signaling_NaN) && | |
| std::isnan(value)) { | |
| special = true; | |
| stream << ".nan"; | |
| } else if (std::numeric_limits<T>::has_infinity && std::isinf(value)) { | |
| special = true; | |
| if (std::signbit(value)) { | |
| stream << "-.inf"; | |
| } else { | |
| stream << ".inf"; | |
| } | |
| } | |
| } | |
| if (!special) { | |
| stream << FpToString(value, stream.precision()); | |
| } | |
| m_stream << stream.str(); | |
| StartedScalar(); | |
| return *this; | |
| } | |
| template <> | |
| inline void Emitter::SetStreamablePrecision<float>(std::stringstream& stream) { | |
| stream.precision(static_cast<std::streamsize>(GetFloatPrecision())); | |
| } | |
| template <> | |
| inline void Emitter::SetStreamablePrecision<double>(std::stringstream& stream) { | |
| stream.precision(static_cast<std::streamsize>(GetDoublePrecision())); | |
| } | |
| // overloads of insertion | |
| #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) | |
| inline Emitter& operator<<(Emitter& emitter, const std::string_view& v) { | |
| return emitter.Write(v.data(), v.size()); | |
| } | |
| #endif | |
| inline Emitter& operator<<(Emitter& emitter, const std::string& v) { | |
| return emitter.Write(v.data(), v.size()); | |
| } | |
| inline Emitter& operator<<(Emitter& emitter, bool v) { | |
| return emitter.Write(v); | |
| } | |
| inline Emitter& operator<<(Emitter& emitter, char v) { | |
| return emitter.Write(v); | |
| } | |
| inline Emitter& operator<<(Emitter& emitter, unsigned char v) { | |
| return emitter.Write(static_cast<char>(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 Binary& b) { | |
| return emitter.Write(b); | |
| } | |
| inline Emitter& operator<<(Emitter& emitter, const char* v) { | |
| return emitter.Write(v, std::strlen(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, long long v) { | |
| return emitter.WriteIntegralType(v); | |
| } | |
| inline Emitter& operator<<(Emitter& emitter, unsigned long 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); | |
| } | |
| inline Emitter& operator<<(Emitter& emitter, EMITTER_MANIP value) { | |
| return emitter.SetLocalValue(value); | |
| } | |
| inline Emitter& operator<<(Emitter& emitter, _Indent indent) { | |
| return emitter.SetLocalIndent(indent); | |
| } | |
| inline Emitter& operator<<(Emitter& emitter, _Precision precision) { | |
| return emitter.SetLocalPrecision(precision); | |
| } | |
| } // namespace YAML | |
| #endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 |