Compare commits
9
Commits
travis
...
yaml-cpp-0.6.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a3624205e | ||
|
|
968e0c1f02 | ||
|
|
b218787b98 | ||
|
|
db0bda7087 | ||
|
|
6cdf363625 | ||
|
|
d638508d33 | ||
|
|
90350662c9 | ||
|
|
e0e01d53c2 | ||
|
|
0122697561 |
+27
-24
@@ -9,13 +9,7 @@ include(CheckCXXCompilerFlag)
|
||||
###
|
||||
### Project settings
|
||||
###
|
||||
project(YAML_CPP)
|
||||
|
||||
set(YAML_CPP_VERSION_MAJOR "0")
|
||||
set(YAML_CPP_VERSION_MINOR "6")
|
||||
set(YAML_CPP_VERSION_PATCH "2")
|
||||
set(YAML_CPP_VERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}.${YAML_CPP_VERSION_PATCH}")
|
||||
|
||||
project(YAML_CPP VERSION 0.6.3)
|
||||
|
||||
###
|
||||
### Project options
|
||||
@@ -30,20 +24,20 @@ option(YAML_CPP_INSTALL "Enable generation of install target" ON)
|
||||
# --> General
|
||||
# see http://www.cmake.org/cmake/help/cmake2.6docs.html#variable:BUILD_SHARED_LIBS
|
||||
# http://www.cmake.org/cmake/help/cmake2.6docs.html#command:add_library
|
||||
option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
|
||||
|
||||
# Set minimum C++ to 2011 standards
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
option(YAML_BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
|
||||
|
||||
# --> Apple
|
||||
option(APPLE_UNIVERSAL_BIN "Apple: Build universal binary" OFF)
|
||||
if(APPLE)
|
||||
option(YAML_APPLE_UNIVERSAL_BIN "Apple: Build universal binary" OFF)
|
||||
endif()
|
||||
|
||||
# --> Microsoft Visual C++
|
||||
# see http://msdn.microsoft.com/en-us/library/aa278396(v=VS.60).aspx
|
||||
# http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=VS.71).aspx
|
||||
option(MSVC_SHARED_RT "MSVC: Build with shared runtime libs (/MD)" ON)
|
||||
option(MSVC_STHREADED_RT "MSVC: Build with single-threaded static runtime libs (/ML until VS .NET 2003)" OFF)
|
||||
if(MSVC)
|
||||
option(YAML_MSVC_SHARED_RT "MSVC: Build with shared runtime libs (/MD)" ON)
|
||||
option(YAML_MSVC_STHREADED_RT "MSVC: Build with single-threaded static runtime libs (/ML until VS .NET 2003)" OFF)
|
||||
endif()
|
||||
|
||||
###
|
||||
### Sources, headers, directories and libs
|
||||
@@ -116,14 +110,14 @@ endif()
|
||||
set(yaml_c_flags ${CMAKE_C_FLAGS})
|
||||
set(yaml_cxx_flags ${CMAKE_CXX_FLAGS})
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
if(YAML_BUILD_SHARED_LIBS)
|
||||
set(LABEL_SUFFIX "shared")
|
||||
else()
|
||||
set(LABEL_SUFFIX "static")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
if(APPLE_UNIVERSAL_BIN)
|
||||
if(YAML_APPLE_UNIVERSAL_BIN)
|
||||
set(CMAKE_OSX_ARCHITECTURES ppc;i386)
|
||||
endif()
|
||||
endif()
|
||||
@@ -134,7 +128,7 @@ if(IPHONE)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
if(YAML_BUILD_SHARED_LIBS)
|
||||
add_definitions(-D${PROJECT_NAME}_DLL) # use or build Windows DLL
|
||||
endif()
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
@@ -161,7 +155,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR
|
||||
#
|
||||
set(GCC_EXTRA_OPTIONS "")
|
||||
#
|
||||
if(BUILD_SHARED_LIBS)
|
||||
if(YAML_BUILD_SHARED_LIBS)
|
||||
set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} -fPIC")
|
||||
endif()
|
||||
#
|
||||
@@ -196,8 +190,8 @@ if(MSVC)
|
||||
set(LIB_RT_SUFFIX "md") # CMake defaults to /MD for MSVC
|
||||
set(LIB_RT_OPTION "/MD")
|
||||
#
|
||||
if(NOT MSVC_SHARED_RT) # User wants to have static runtime libraries (/MT, /ML)
|
||||
if(MSVC_STHREADED_RT) # User wants to have old single-threaded static runtime libraries
|
||||
if(NOT YAML_MSVC_SHARED_RT) # User wants to have static runtime libraries (/MT, /ML)
|
||||
if(YAML_MSVC_STHREADED_RT) # User wants to have old single-threaded static runtime libraries
|
||||
set(LIB_RT_SUFFIX "ml")
|
||||
set(LIB_RT_OPTION "/ML")
|
||||
if(NOT ${MSVC_VERSION} LESS 1400)
|
||||
@@ -227,7 +221,7 @@ if(MSVC)
|
||||
set(CMAKE_STATIC_LIBRARY_PREFIX "lib") # to distinguish static libraries from DLL import libs
|
||||
|
||||
# c) Correct suffixes for static libraries
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
if(NOT YAML_BUILD_SHARED_LIBS)
|
||||
### General stuff
|
||||
set(LIB_TARGET_SUFFIX "${LIB_SUFFIX}${LIB_RT_SUFFIX}")
|
||||
endif()
|
||||
@@ -258,7 +252,11 @@ set(_INSTALL_DESTINATIONS
|
||||
###
|
||||
### Library
|
||||
###
|
||||
add_library(yaml-cpp ${library_sources})
|
||||
if(YAML_BUILD_SHARED_LIBS)
|
||||
add_library(yaml-cpp SHARED ${library_sources})
|
||||
else()
|
||||
add_library(yaml-cpp STATIC ${library_sources})
|
||||
endif()
|
||||
|
||||
if (NOT CMAKE_VERSION VERSION_LESS 2.8.12)
|
||||
target_include_directories(yaml-cpp
|
||||
@@ -267,6 +265,11 @@ if (NOT CMAKE_VERSION VERSION_LESS 2.8.12)
|
||||
PRIVATE $<BUILD_INTERFACE:${YAML_CPP_SOURCE_DIR}/src>)
|
||||
endif()
|
||||
|
||||
set_target_properties(yaml-cpp PROPERTIES
|
||||
CXX_STANDARD 11
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
)
|
||||
|
||||
set_target_properties(yaml-cpp PROPERTIES
|
||||
COMPILE_FLAGS "${yaml_c_flags} ${yaml_cxx_flags}"
|
||||
)
|
||||
@@ -284,7 +287,7 @@ if(IPHONE)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
if(NOT YAML_BUILD_SHARED_LIBS)
|
||||
# correct library names
|
||||
set_target_properties(yaml-cpp PROPERTIES
|
||||
DEBUG_POSTFIX "${LIB_TARGET_SUFFIX}d"
|
||||
|
||||
@@ -26,7 +26,7 @@ cd build
|
||||
3. Run CMake. The basic syntax is:
|
||||
|
||||
```
|
||||
cmake [-G generator] [-DBUILD_SHARED_LIBS=ON|OFF] ..
|
||||
cmake [-G generator] [-DYAML_BUILD_SHARED_LIBS=ON|OFF] ..
|
||||
```
|
||||
|
||||
* The `generator` is whatever type of build system you'd like to use. To see a full list of generators on your platform, just run `cmake` (with no arguments). For example:
|
||||
@@ -34,7 +34,7 @@ cmake [-G generator] [-DBUILD_SHARED_LIBS=ON|OFF] ..
|
||||
* On OS X, you might use "Xcode" to generate an Xcode project
|
||||
* On a UNIX-y system, simply omit the option to generate a makefile
|
||||
|
||||
* yaml-cpp defaults to building a static library, but you may build a shared library by specifying `-DBUILD_SHARED_LIBS=ON`.
|
||||
* yaml-cpp defaults to building a static library, but you may build a shared library by specifying `-DYAML_BUILD_SHARED_LIBS=ON`.
|
||||
|
||||
* For more options on customizing the build, see the [CMakeLists.txt](https://github.com/jbeder/yaml-cpp/blob/master/CMakeLists.txt) file.
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ class YAML_CPP_API Binary {
|
||||
rhs.clear();
|
||||
rhs.resize(m_unownedSize);
|
||||
std::copy(m_unownedData, m_unownedData + m_unownedSize, rhs.begin());
|
||||
m_unownedData = 0;
|
||||
m_unownedData = nullptr;
|
||||
m_unownedSize = 0;
|
||||
} else {
|
||||
m_data.swap(rhs);
|
||||
|
||||
@@ -7,10 +7,13 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "yaml-cpp/binary.h"
|
||||
#include "yaml-cpp/dll.h"
|
||||
@@ -153,7 +156,28 @@ inline Emitter& Emitter::WriteStreamable(T value) {
|
||||
|
||||
std::stringstream stream;
|
||||
SetStreamablePrecision<T>(stream);
|
||||
stream << value;
|
||||
|
||||
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) {
|
||||
if (value == std::numeric_limits<T>::infinity()) {
|
||||
special = true;
|
||||
stream << ".inf";
|
||||
} else if (value == -std::numeric_limits<T>::infinity()) {
|
||||
special = true;
|
||||
stream << "-.inf";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!special) {
|
||||
stream << value;
|
||||
}
|
||||
m_stream << stream.str();
|
||||
|
||||
StartedScalar();
|
||||
|
||||
@@ -114,6 +114,35 @@ inline const std::string KEY_NOT_FOUND_WITH_KEY(
|
||||
stream << KEY_NOT_FOUND << ": " << key;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const std::string BAD_SUBSCRIPT_WITH_KEY(
|
||||
const T&, typename disable_if<is_numeric<T>>::type* = nullptr) {
|
||||
return BAD_SUBSCRIPT;
|
||||
}
|
||||
|
||||
inline const std::string BAD_SUBSCRIPT_WITH_KEY(const std::string& key) {
|
||||
std::stringstream stream;
|
||||
stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")";
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const std::string BAD_SUBSCRIPT_WITH_KEY(
|
||||
const T& key, typename enable_if<is_numeric<T>>::type* = nullptr) {
|
||||
std::stringstream stream;
|
||||
stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")";
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
inline const std::string INVALID_NODE_WITH_KEY(const std::string& key) {
|
||||
std::stringstream stream;
|
||||
if (key.empty()) {
|
||||
return INVALID_NODE;
|
||||
}
|
||||
stream << "invalid node; first invalid key: \"" << key << "\"";
|
||||
return stream.str();
|
||||
}
|
||||
}
|
||||
|
||||
class YAML_CPP_API Exception : public std::runtime_error {
|
||||
@@ -131,7 +160,7 @@ class YAML_CPP_API Exception : public std::runtime_error {
|
||||
static const std::string build_what(const Mark& mark,
|
||||
const std::string& msg) {
|
||||
if (mark.is_null()) {
|
||||
return msg.c_str();
|
||||
return msg;
|
||||
}
|
||||
|
||||
std::stringstream output;
|
||||
@@ -194,8 +223,9 @@ inline TypedKeyNotFound<T> MakeTypedKeyNotFound(const Mark& mark,
|
||||
|
||||
class YAML_CPP_API InvalidNode : public RepresentationException {
|
||||
public:
|
||||
InvalidNode()
|
||||
: RepresentationException(Mark::null_mark(), ErrorMsg::INVALID_NODE) {}
|
||||
InvalidNode(std::string key)
|
||||
: RepresentationException(Mark::null_mark(),
|
||||
ErrorMsg::INVALID_NODE_WITH_KEY(key)) {}
|
||||
InvalidNode(const InvalidNode&) = default;
|
||||
virtual ~InvalidNode() YAML_CPP_NOEXCEPT;
|
||||
};
|
||||
@@ -224,8 +254,10 @@ class YAML_CPP_API BadDereference : public RepresentationException {
|
||||
|
||||
class YAML_CPP_API BadSubscript : public RepresentationException {
|
||||
public:
|
||||
BadSubscript()
|
||||
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_SUBSCRIPT) {}
|
||||
template <typename Key>
|
||||
BadSubscript(const Key& key)
|
||||
: RepresentationException(Mark::null_mark(),
|
||||
ErrorMsg::BAD_SUBSCRIPT_WITH_KEY(key)) {}
|
||||
BadSubscript(const BadSubscript&) = default;
|
||||
virtual ~BadSubscript() YAML_CPP_NOEXCEPT;
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ template <typename Key, typename Enable = void>
|
||||
struct get_idx {
|
||||
static node* get(const std::vector<node*>& /* sequence */,
|
||||
const Key& /* key */, shared_memory_holder /* pMemory */) {
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@ struct get_idx<Key,
|
||||
!std::is_same<Key, bool>::value>::type> {
|
||||
static node* get(const std::vector<node*>& sequence, const Key& key,
|
||||
shared_memory_holder /* pMemory */) {
|
||||
return key < sequence.size() ? sequence[key] : 0;
|
||||
return key < sequence.size() ? sequence[key] : nullptr;
|
||||
}
|
||||
|
||||
static node* get(std::vector<node*>& sequence, const Key& key,
|
||||
@@ -46,13 +46,13 @@ struct get_idx<Key, typename std::enable_if<std::is_signed<Key>::value>::type> {
|
||||
shared_memory_holder pMemory) {
|
||||
return key >= 0 ? get_idx<std::size_t>::get(
|
||||
sequence, static_cast<std::size_t>(key), pMemory)
|
||||
: 0;
|
||||
: nullptr;
|
||||
}
|
||||
static node* get(std::vector<node*>& sequence, const Key& key,
|
||||
shared_memory_holder pMemory) {
|
||||
return key >= 0 ? get_idx<std::size_t>::get(
|
||||
sequence, static_cast<std::size_t>(key), pMemory)
|
||||
: 0;
|
||||
: nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -109,13 +109,13 @@ inline node* node_data::get(const Key& key,
|
||||
break;
|
||||
case NodeType::Undefined:
|
||||
case NodeType::Null:
|
||||
return NULL;
|
||||
return nullptr;
|
||||
case NodeType::Sequence:
|
||||
if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory))
|
||||
return pNode;
|
||||
return NULL;
|
||||
return nullptr;
|
||||
case NodeType::Scalar:
|
||||
throw BadSubscript();
|
||||
throw BadSubscript(key);
|
||||
}
|
||||
|
||||
for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
|
||||
@@ -124,7 +124,7 @@ inline node* node_data::get(const Key& key,
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename Key>
|
||||
@@ -143,7 +143,7 @@ inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
|
||||
convert_to_map(pMemory);
|
||||
break;
|
||||
case NodeType::Scalar:
|
||||
throw BadSubscript();
|
||||
throw BadSubscript(key);
|
||||
}
|
||||
|
||||
for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
|
||||
|
||||
@@ -26,9 +26,9 @@ template <typename V>
|
||||
struct node_iterator_value : public std::pair<V*, V*> {
|
||||
typedef std::pair<V*, V*> kv;
|
||||
|
||||
node_iterator_value() : kv(), pNode(0) {}
|
||||
node_iterator_value() : kv(), pNode(nullptr) {}
|
||||
explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {}
|
||||
explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(0) {}
|
||||
explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(nullptr) {}
|
||||
|
||||
V& operator*() const { return *pNode; }
|
||||
V& operator->() const { return *pNode; }
|
||||
|
||||
@@ -12,13 +12,16 @@
|
||||
#include "yaml-cpp/node/detail/node.h"
|
||||
#include "yaml-cpp/node/iterator.h"
|
||||
#include "yaml-cpp/node/node.h"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace YAML {
|
||||
inline Node::Node() : m_isValid(true), m_pMemory(nullptr), m_pNode(nullptr) {}
|
||||
inline Node::Node()
|
||||
: m_isValid(true), m_invalidKey{}, m_pMemory(nullptr), m_pNode(nullptr) {}
|
||||
|
||||
inline Node::Node(NodeType::value type)
|
||||
: m_isValid(true),
|
||||
m_invalidKey{},
|
||||
m_pMemory(new detail::memory_holder),
|
||||
m_pNode(&m_pMemory->create_node()) {
|
||||
m_pNode->set_type(type);
|
||||
@@ -27,6 +30,7 @@ inline Node::Node(NodeType::value type)
|
||||
template <typename T>
|
||||
inline Node::Node(const T& rhs)
|
||||
: m_isValid(true),
|
||||
m_invalidKey{},
|
||||
m_pMemory(new detail::memory_holder),
|
||||
m_pNode(&m_pMemory->create_node()) {
|
||||
Assign(rhs);
|
||||
@@ -34,24 +38,30 @@ inline Node::Node(const T& rhs)
|
||||
|
||||
inline Node::Node(const detail::iterator_value& rhs)
|
||||
: m_isValid(rhs.m_isValid),
|
||||
m_invalidKey(rhs.m_invalidKey),
|
||||
m_pMemory(rhs.m_pMemory),
|
||||
m_pNode(rhs.m_pNode) {}
|
||||
|
||||
inline Node::Node(const Node& rhs)
|
||||
: m_isValid(rhs.m_isValid),
|
||||
m_invalidKey(rhs.m_invalidKey),
|
||||
m_pMemory(rhs.m_pMemory),
|
||||
m_pNode(rhs.m_pNode) {}
|
||||
|
||||
inline Node::Node(Zombie) : m_isValid(false), m_pMemory{}, m_pNode(nullptr) {}
|
||||
inline Node::Node(Zombie)
|
||||
: m_isValid(false), m_invalidKey{}, m_pMemory{}, m_pNode(nullptr) {}
|
||||
|
||||
inline Node::Node(Zombie, const std::string& key)
|
||||
: m_isValid(false), m_invalidKey(key), m_pMemory{}, m_pNode(nullptr) {}
|
||||
|
||||
inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory)
|
||||
: m_isValid(true), m_pMemory(pMemory), m_pNode(&node) {}
|
||||
: m_isValid(true), m_invalidKey{}, m_pMemory(pMemory), m_pNode(&node) {}
|
||||
|
||||
inline Node::~Node() {}
|
||||
|
||||
inline void Node::EnsureNodeExists() const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
if (!m_pNode) {
|
||||
m_pMemory.reset(new detail::memory_holder);
|
||||
m_pNode = &m_pMemory->create_node();
|
||||
@@ -68,14 +78,14 @@ inline bool Node::IsDefined() const {
|
||||
|
||||
inline Mark Node::Mark() const {
|
||||
if (!m_isValid) {
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
}
|
||||
return m_pNode ? m_pNode->mark() : Mark::null_mark();
|
||||
}
|
||||
|
||||
inline NodeType::value Node::Type() const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
return m_pNode ? m_pNode->type() : NodeType::Null;
|
||||
}
|
||||
|
||||
@@ -142,7 +152,7 @@ struct as_if<std::string, void> {
|
||||
template <typename T>
|
||||
inline T Node::as() const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
return as_if<T, void>(*this)();
|
||||
}
|
||||
|
||||
@@ -155,32 +165,32 @@ inline T Node::as(const S& fallback) const {
|
||||
|
||||
inline const std::string& Node::Scalar() const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar();
|
||||
}
|
||||
|
||||
inline const std::string& Node::Tag() const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar();
|
||||
}
|
||||
|
||||
inline void Node::SetTag(const std::string& tag) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
m_pNode->set_tag(tag);
|
||||
}
|
||||
|
||||
inline EmitterStyle::value Node::Style() const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
return m_pNode ? m_pNode->style() : EmitterStyle::Default;
|
||||
}
|
||||
|
||||
inline void Node::SetStyle(EmitterStyle::value style) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
m_pNode->set_style(style);
|
||||
}
|
||||
@@ -188,7 +198,7 @@ inline void Node::SetStyle(EmitterStyle::value style) {
|
||||
// assignment
|
||||
inline bool Node::is(const Node& rhs) const {
|
||||
if (!m_isValid || !rhs.m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
if (!m_pNode || !rhs.m_pNode)
|
||||
return false;
|
||||
return m_pNode->is(*rhs.m_pNode);
|
||||
@@ -197,14 +207,14 @@ inline bool Node::is(const Node& rhs) const {
|
||||
template <typename T>
|
||||
inline Node& Node::operator=(const T& rhs) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
Assign(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Node& Node::operator=(const Node& rhs) {
|
||||
if (!m_isValid || !rhs.m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
if (is(rhs))
|
||||
return *this;
|
||||
AssignNode(rhs);
|
||||
@@ -213,7 +223,7 @@ inline Node& Node::operator=(const Node& rhs) {
|
||||
|
||||
inline void Node::reset(const YAML::Node& rhs) {
|
||||
if (!m_isValid || !rhs.m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
m_pMemory = rhs.m_pMemory;
|
||||
m_pNode = rhs.m_pNode;
|
||||
}
|
||||
@@ -221,35 +231,35 @@ inline void Node::reset(const YAML::Node& rhs) {
|
||||
template <typename T>
|
||||
inline void Node::Assign(const T& rhs) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
AssignData(convert<T>::encode(rhs));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void Node::Assign(const std::string& rhs) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
m_pNode->set_scalar(rhs);
|
||||
}
|
||||
|
||||
inline void Node::Assign(const char* rhs) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
m_pNode->set_scalar(rhs);
|
||||
}
|
||||
|
||||
inline void Node::Assign(char* rhs) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
m_pNode->set_scalar(rhs);
|
||||
}
|
||||
|
||||
inline void Node::AssignData(const Node& rhs) {
|
||||
if (!m_isValid || !rhs.m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
rhs.EnsureNodeExists();
|
||||
|
||||
@@ -259,7 +269,7 @@ inline void Node::AssignData(const Node& rhs) {
|
||||
|
||||
inline void Node::AssignNode(const Node& rhs) {
|
||||
if (!m_isValid || !rhs.m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
rhs.EnsureNodeExists();
|
||||
|
||||
if (!m_pNode) {
|
||||
@@ -276,7 +286,7 @@ inline void Node::AssignNode(const Node& rhs) {
|
||||
// size/iterator
|
||||
inline std::size_t Node::size() const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
return m_pNode ? m_pNode->size() : 0;
|
||||
}
|
||||
|
||||
@@ -309,13 +319,13 @@ inline iterator Node::end() {
|
||||
template <typename T>
|
||||
inline void Node::push_back(const T& rhs) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
push_back(Node(rhs));
|
||||
}
|
||||
|
||||
inline void Node::push_back(const Node& rhs) {
|
||||
if (!m_isValid || !rhs.m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
rhs.EnsureNodeExists();
|
||||
|
||||
@@ -368,16 +378,21 @@ inline typename to_value_t<T>::return_type to_value(const T& t) {
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template<typename Key>
|
||||
std::string key_to_string(const Key& key) {
|
||||
return streamable_to_string<Key, is_streamable<std::stringstream, Key>::value>().impl(key);
|
||||
}
|
||||
|
||||
// indexing
|
||||
template <typename Key>
|
||||
inline const Node Node::operator[](const Key& key) const {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
detail::node* value = static_cast<const detail::node&>(*m_pNode).get(
|
||||
detail::to_value(key), m_pMemory);
|
||||
if (!value) {
|
||||
return Node(ZombieNode);
|
||||
return Node(ZombieNode, key_to_string(key));
|
||||
}
|
||||
return Node(*value, m_pMemory);
|
||||
}
|
||||
@@ -385,7 +400,7 @@ inline const Node Node::operator[](const Key& key) const {
|
||||
template <typename Key>
|
||||
inline Node Node::operator[](const Key& key) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory);
|
||||
return Node(value, m_pMemory);
|
||||
@@ -394,28 +409,28 @@ inline Node Node::operator[](const Key& key) {
|
||||
template <typename Key>
|
||||
inline bool Node::remove(const Key& key) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
return m_pNode->remove(detail::to_value(key), m_pMemory);
|
||||
}
|
||||
|
||||
inline const Node Node::operator[](const Node& key) const {
|
||||
if (!m_isValid || !key.m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
key.EnsureNodeExists();
|
||||
m_pMemory->merge(*key.m_pMemory);
|
||||
detail::node* value =
|
||||
static_cast<const detail::node&>(*m_pNode).get(*key.m_pNode, m_pMemory);
|
||||
if (!value) {
|
||||
return Node(ZombieNode);
|
||||
return Node(ZombieNode, key_to_string(key));
|
||||
}
|
||||
return Node(*value, m_pMemory);
|
||||
}
|
||||
|
||||
inline Node Node::operator[](const Node& key) {
|
||||
if (!m_isValid || !key.m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
key.EnsureNodeExists();
|
||||
m_pMemory->merge(*key.m_pMemory);
|
||||
@@ -425,7 +440,7 @@ inline Node Node::operator[](const Node& key) {
|
||||
|
||||
inline bool Node::remove(const Node& key) {
|
||||
if (!m_isValid || !key.m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
key.EnsureNodeExists();
|
||||
return m_pNode->remove(*key.m_pNode, m_pMemory);
|
||||
@@ -435,7 +450,7 @@ inline bool Node::remove(const Node& key) {
|
||||
template <typename Key, typename Value>
|
||||
inline void Node::force_insert(const Key& key, const Value& value) {
|
||||
if (!m_isValid)
|
||||
throw InvalidNode();
|
||||
throw InvalidNode(m_invalidKey);
|
||||
EnsureNodeExists();
|
||||
m_pNode->force_insert(detail::to_value(key), detail::to_value(value),
|
||||
m_pMemory);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#endif
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include "yaml-cpp/dll.h"
|
||||
#include "yaml-cpp/emitterstyle.h"
|
||||
@@ -116,6 +117,7 @@ class YAML_CPP_API Node {
|
||||
private:
|
||||
enum Zombie { ZombieNode };
|
||||
explicit Node(Zombie);
|
||||
explicit Node(Zombie, const std::string&);
|
||||
explicit Node(detail::node& node, detail::shared_memory_holder pMemory);
|
||||
|
||||
void EnsureNodeExists() const;
|
||||
@@ -130,6 +132,8 @@ class YAML_CPP_API Node {
|
||||
|
||||
private:
|
||||
bool m_isValid;
|
||||
// String representation of invalid key, if the node is invalid.
|
||||
std::string m_invalidKey;
|
||||
mutable detail::shared_memory_holder m_pMemory;
|
||||
mutable detail::node* m_pNode;
|
||||
};
|
||||
|
||||
@@ -30,7 +30,7 @@ class YAML_CPP_API ostream_wrapper {
|
||||
|
||||
const char* str() const {
|
||||
if (m_pStream) {
|
||||
return 0;
|
||||
return nullptr;
|
||||
} else {
|
||||
m_buffer[m_pos] = '\0';
|
||||
return &m_buffer[0];
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML {
|
||||
template <typename>
|
||||
struct is_numeric {
|
||||
@@ -100,4 +105,31 @@ template <class Cond, class T = void>
|
||||
struct disable_if : public disable_if_c<Cond::value, T> {};
|
||||
}
|
||||
|
||||
template <typename S, typename T>
|
||||
struct is_streamable {
|
||||
template <typename SS, typename TT>
|
||||
static auto test(int)
|
||||
-> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
|
||||
|
||||
template <typename, typename>
|
||||
static auto test(...) -> std::false_type;
|
||||
|
||||
static const bool value = decltype(test<S, T>(0))::value;
|
||||
};
|
||||
|
||||
template<typename Key, bool Streamable>
|
||||
struct streamable_to_string {
|
||||
static std::string impl(const Key& key) {
|
||||
std::stringstream ss;
|
||||
ss << key;
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Key>
|
||||
struct streamable_to_string<Key, false> {
|
||||
static std::string impl(const Key&) {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
+2
-2
@@ -196,7 +196,7 @@ void node_data::insert(node& key, node& value, shared_memory_holder pMemory) {
|
||||
convert_to_map(pMemory);
|
||||
break;
|
||||
case NodeType::Scalar:
|
||||
throw BadSubscript();
|
||||
throw BadSubscript(key);
|
||||
}
|
||||
|
||||
insert_map_pair(key, value);
|
||||
@@ -226,7 +226,7 @@ node& node_data::get(node& key, shared_memory_holder pMemory) {
|
||||
convert_to_map(pMemory);
|
||||
break;
|
||||
case NodeType::Scalar:
|
||||
throw BadSubscript();
|
||||
throw BadSubscript(key);
|
||||
}
|
||||
|
||||
for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
|
||||
|
||||
@@ -51,6 +51,11 @@ add_executable(run-tests
|
||||
${test_headers}
|
||||
)
|
||||
|
||||
set_target_properties(run-tests PROPERTIES
|
||||
CXX_STANDARD 11
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
)
|
||||
|
||||
add_dependencies(run-tests googletest_project)
|
||||
|
||||
set_target_properties(run-tests PROPERTIES
|
||||
|
||||
@@ -253,8 +253,9 @@ TEST_F(EmitterTest, ScalarFormat) {
|
||||
out << DoubleQuoted << "explicit double-quoted scalar";
|
||||
out << "auto-detected\ndouble-quoted scalar";
|
||||
out << "a non-\"auto-detected\" double-quoted scalar";
|
||||
out << Literal << "literal scalar\nthat may span\nmany, many\nlines "
|
||||
"and have \"whatever\" crazy\tsymbols that we like";
|
||||
out << Literal
|
||||
<< "literal scalar\nthat may span\nmany, many\nlines "
|
||||
"and have \"whatever\" crazy\tsymbols that we like";
|
||||
out << EndSeq;
|
||||
|
||||
ExpectEmit(
|
||||
@@ -526,9 +527,10 @@ TEST_F(EmitterTest, SimpleComment) {
|
||||
|
||||
TEST_F(EmitterTest, MultiLineComment) {
|
||||
out << BeginSeq;
|
||||
out << "item 1" << Comment(
|
||||
"really really long\ncomment that couldn't "
|
||||
"possibly\nfit on one line");
|
||||
out << "item 1"
|
||||
<< Comment(
|
||||
"really really long\ncomment that couldn't "
|
||||
"possibly\nfit on one line");
|
||||
out << "item 2";
|
||||
out << EndSeq;
|
||||
|
||||
@@ -984,6 +986,45 @@ TEST_F(EmitterTest, ValueOfBackslash) {
|
||||
ExpectEmit("foo: \"\\\\\"");
|
||||
}
|
||||
|
||||
TEST_F(EmitterTest, Infinity) {
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Key << "foo" << YAML::Value
|
||||
<< std::numeric_limits<float>::infinity();
|
||||
out << YAML::Key << "bar" << YAML::Value
|
||||
<< std::numeric_limits<double>::infinity();
|
||||
out << YAML::EndMap;
|
||||
|
||||
ExpectEmit(
|
||||
"foo: .inf\n"
|
||||
"bar: .inf");
|
||||
}
|
||||
|
||||
TEST_F(EmitterTest, NegInfinity) {
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Key << "foo" << YAML::Value
|
||||
<< -std::numeric_limits<float>::infinity();
|
||||
out << YAML::Key << "bar" << YAML::Value
|
||||
<< -std::numeric_limits<double>::infinity();
|
||||
out << YAML::EndMap;
|
||||
|
||||
ExpectEmit(
|
||||
"foo: -.inf\n"
|
||||
"bar: -.inf");
|
||||
}
|
||||
|
||||
TEST_F(EmitterTest, NaN) {
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Key << "foo" << YAML::Value
|
||||
<< std::numeric_limits<float>::quiet_NaN();
|
||||
out << YAML::Key << "bar" << YAML::Value
|
||||
<< std::numeric_limits<double>::quiet_NaN();
|
||||
out << YAML::EndMap;
|
||||
|
||||
ExpectEmit(
|
||||
"foo: .nan\n"
|
||||
"bar: .nan");
|
||||
}
|
||||
|
||||
class EmitterErrorTest : public ::testing::Test {
|
||||
protected:
|
||||
void ExpectEmitError(const std::string& expectedError) {
|
||||
@@ -1034,5 +1075,5 @@ TEST_F(EmitterErrorTest, InvalidAlias) {
|
||||
|
||||
ExpectEmitError(ErrorMsg::INVALID_ALIAS);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
} // namespace YAML
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "yaml-cpp/yaml.h" // IWYU pragma: keep
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#define EXPECT_THROW_EXCEPTION(exception_type, statement, message) \
|
||||
ASSERT_THROW(statement, exception_type); \
|
||||
try { \
|
||||
statement; \
|
||||
} catch (const exception_type& e) { \
|
||||
EXPECT_EQ(e.msg, message); \
|
||||
}
|
||||
|
||||
namespace YAML {
|
||||
namespace {
|
||||
|
||||
TEST(ErrorMessageTest, BadSubscriptErrorMessage) {
|
||||
const char *example_yaml = "first:\n"
|
||||
" second: 1\n"
|
||||
" third: 2\n";
|
||||
|
||||
Node doc = Load(example_yaml);
|
||||
|
||||
// Test that printable key is part of error message
|
||||
EXPECT_THROW_EXCEPTION(YAML::BadSubscript, doc["first"]["second"]["fourth"],
|
||||
"operator[] call on a scalar (key: \"fourth\")");
|
||||
|
||||
EXPECT_THROW_EXCEPTION(YAML::BadSubscript, doc["first"]["second"][37],
|
||||
"operator[] call on a scalar (key: \"37\")");
|
||||
|
||||
|
||||
// Non-printable key is not included in error message
|
||||
EXPECT_THROW_EXCEPTION(YAML::BadSubscript,
|
||||
doc["first"]["second"][std::vector<int>()],
|
||||
"operator[] call on a scalar");
|
||||
|
||||
EXPECT_THROW_EXCEPTION(YAML::BadSubscript, doc["first"]["second"][Node()],
|
||||
"operator[] call on a scalar");
|
||||
}
|
||||
|
||||
TEST(ErrorMessageTest, Ex9_1_InvalidNodeErrorMessage) {
|
||||
const char *example_yaml = "first:\n"
|
||||
" second: 1\n"
|
||||
" third: 2\n";
|
||||
|
||||
const Node doc = Load(example_yaml);
|
||||
|
||||
// Test that printable key is part of error message
|
||||
EXPECT_THROW_EXCEPTION(YAML::InvalidNode, doc["first"]["fourth"].as<int>(),
|
||||
"invalid node; first invalid key: \"fourth\"");
|
||||
|
||||
EXPECT_THROW_EXCEPTION(YAML::InvalidNode, doc["first"][37].as<int>(),
|
||||
"invalid node; first invalid key: \"37\"");
|
||||
|
||||
// Non-printable key is not included in error message
|
||||
EXPECT_THROW_EXCEPTION(YAML::InvalidNode,
|
||||
doc["first"][std::vector<int>()].as<int>(),
|
||||
"invalid node; this may result from using a map "
|
||||
"iterator as a sequence iterator, or vice-versa");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,25 @@ cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
add_sources(parse.cpp)
|
||||
add_executable(parse parse.cpp)
|
||||
set_target_properties(parse PROPERTIES
|
||||
CXX_STANDARD 11
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
)
|
||||
target_link_libraries(parse yaml-cpp)
|
||||
|
||||
add_sources(sandbox.cpp)
|
||||
add_executable(sandbox sandbox.cpp)
|
||||
set_target_properties(sandbox PROPERTIES
|
||||
CXX_STANDARD 11
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
)
|
||||
target_link_libraries(sandbox yaml-cpp)
|
||||
|
||||
add_sources(read.cpp)
|
||||
add_executable(read read.cpp)
|
||||
set_target_properties(read PROPERTIES
|
||||
CXX_STANDARD 11
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
)
|
||||
target_link_libraries(read yaml-cpp)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user