A common use case is to transform each Node once even when *1 &1 DAG sharing exists in the input. This needs an 'already processed' set, which, using only is() would be quadratic in this use case. hashable ids (exposing the underlying pointer used by is) makes it linear time. For performance, part of node/detail/node.h is effectively exposed - the fact that it has a shared_ptr<node_ref> as its first member. Alternatively the implementation of id() could be made non-inline so the full definition of detail::node could be used.
173 lines
4.3 KiB
C++
173 lines
4.3 KiB
C++
#ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
|
#define NODE_NODE_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 <stdexcept>
|
|
#include <cassert>
|
|
#include "yaml-cpp/dll.h"
|
|
#include "yaml-cpp/emitterstyle.h"
|
|
#include "yaml-cpp/mark.h"
|
|
#include "yaml-cpp/node/detail/bool_type.h"
|
|
#include "yaml-cpp/node/detail/iterator_fwd.h"
|
|
#include "yaml-cpp/node/ptr.h"
|
|
#include "yaml-cpp/node/type.h"
|
|
|
|
namespace YAML {
|
|
namespace detail {
|
|
class node;
|
|
class node_data;
|
|
class node_ref;
|
|
struct iterator_value;
|
|
} // namespace detail
|
|
} // namespace YAML
|
|
|
|
namespace YAML {
|
|
|
|
|
|
class YAML_CPP_API Node {
|
|
public:
|
|
friend class NodeBuilder;
|
|
friend class NodeEvents;
|
|
friend struct detail::iterator_value;
|
|
friend class detail::node;
|
|
friend class detail::node_data;
|
|
template <typename>
|
|
friend class detail::iterator_base;
|
|
template <typename T, typename S>
|
|
friend struct as_if;
|
|
|
|
typedef YAML::iterator iterator;
|
|
typedef YAML::const_iterator const_iterator;
|
|
|
|
Node();
|
|
explicit Node(NodeType::value type);
|
|
template <typename T>
|
|
explicit Node(const T& rhs);
|
|
explicit Node(const detail::iterator_value& rhs);
|
|
Node(const Node& rhs);
|
|
~Node();
|
|
|
|
YAML::Mark Mark() const;
|
|
NodeType::value Type() const;
|
|
bool IsDefined() const;
|
|
bool IsNull() const { return Type() == NodeType::Null; }
|
|
bool IsScalar() const { return Type() == NodeType::Scalar; }
|
|
bool IsSequence() const { return Type() == NodeType::Sequence; }
|
|
bool IsMap() const { return Type() == NodeType::Map; }
|
|
|
|
// bool conversions
|
|
YAML_CPP_OPERATOR_BOOL()
|
|
bool operator!() const { return !IsDefined(); }
|
|
|
|
// access
|
|
template <typename T>
|
|
T as() const;
|
|
template <typename T, typename S>
|
|
T as(const S& fallback) const;
|
|
const std::string& Scalar() const;
|
|
|
|
const std::string& Tag() const;
|
|
void SetTag(const std::string& tag);
|
|
|
|
// style
|
|
// WARNING: This API might change in future releases.
|
|
EmitterStyle::value Style() const;
|
|
void SetStyle(EmitterStyle::value style);
|
|
|
|
/// for defined nodes, a.id() == b.id() iff a.is(b)
|
|
/// (not part of standard yaml-cpp-0.5 api yet
|
|
void const* id() const {
|
|
assert(IsDefined());
|
|
// node_ref_id is first base of detail::node
|
|
return ref_id(m_pNode)->id();
|
|
}
|
|
|
|
/// requires IsDefined for this and rhs (unlike 'is')
|
|
bool operator==(const Node& rhs) const {
|
|
assert(IsDefined());
|
|
assert(rhs.IsDefined());
|
|
return id() == rhs.id();
|
|
}
|
|
|
|
/// (not part of standard yaml-cpp-0.5 api yet
|
|
friend inline std::size_t hash_value(Node const& self) {
|
|
return self.hash();
|
|
}
|
|
/// (not part of standard yaml-cpp-0.5 api yet
|
|
std::size_t hash() const {
|
|
assert(m_isValid);
|
|
return (std::size_t)id() >> (sizeof(std::shared_ptr<void>) >= 8 ? 3 : 2);
|
|
}
|
|
|
|
bool is(const Node& rhs) const;
|
|
|
|
// assignment
|
|
template <typename T>
|
|
Node& operator=(const T& rhs);
|
|
Node& operator=(const Node& rhs);
|
|
void reset(const Node& rhs = Node());
|
|
|
|
// size/iterator
|
|
std::size_t size() const;
|
|
|
|
const_iterator begin() const;
|
|
iterator begin();
|
|
|
|
const_iterator end() const;
|
|
iterator end();
|
|
|
|
// sequence
|
|
template <typename T>
|
|
void push_back(const T& rhs);
|
|
void push_back(const Node& rhs);
|
|
|
|
// indexing
|
|
template <typename Key>
|
|
const Node operator[](const Key& key) const;
|
|
template <typename Key>
|
|
Node operator[](const Key& key);
|
|
template <typename Key>
|
|
bool remove(const Key& key);
|
|
|
|
const Node operator[](const Node& key) const;
|
|
Node operator[](const Node& key);
|
|
bool remove(const Node& key);
|
|
|
|
// map
|
|
template <typename Key, typename Value>
|
|
void force_insert(const Key& key, const Value& value);
|
|
|
|
private:
|
|
enum Zombie { ZombieNode };
|
|
explicit Node(Zombie);
|
|
explicit Node(detail::node& node, detail::shared_memory_holder pMemory);
|
|
|
|
void EnsureNodeExists() const;
|
|
|
|
template <typename T>
|
|
void Assign(const T& rhs);
|
|
void Assign(const char* rhs);
|
|
void Assign(char* rhs);
|
|
|
|
void AssignData(const Node& rhs);
|
|
void AssignNode(const Node& rhs);
|
|
|
|
private:
|
|
bool m_isValid;
|
|
mutable detail::shared_memory_holder m_pMemory;
|
|
mutable detail::node* m_pNode;
|
|
};
|
|
|
|
YAML_CPP_API Node Clone(const Node& node);
|
|
|
|
template <typename T>
|
|
struct convert;
|
|
}
|
|
|
|
#endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|