node.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
  2. #define NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
  3. #if defined(_MSC_VER) || \
  4. (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
  5. (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
  6. #pragma once
  7. #endif
  8. #include "yaml-cpp/dll.h"
  9. #include "yaml-cpp/emitterstyle.h"
  10. #include "yaml-cpp/node/detail/node_ref.h"
  11. #include "yaml-cpp/node/ptr.h"
  12. #include "yaml-cpp/node/type.h"
  13. #include <set>
  14. namespace YAML {
  15. namespace detail {
  16. class node {
  17. public:
  18. node() : m_pRef(new node_ref), m_dependencies{} {}
  19. node(const node&) = delete;
  20. node& operator=(const node&) = delete;
  21. bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; }
  22. const node_ref* ref() const { return m_pRef.get(); }
  23. bool is_defined() const { return m_pRef->is_defined(); }
  24. const Mark& mark() const { return m_pRef->mark(); }
  25. NodeType::value type() const { return m_pRef->type(); }
  26. const std::string& scalar() const { return m_pRef->scalar(); }
  27. const std::string& tag() const { return m_pRef->tag(); }
  28. EmitterStyle::value style() const { return m_pRef->style(); }
  29. template <typename T>
  30. bool equals(const T& rhs, shared_memory_holder pMemory);
  31. bool equals(const char* rhs, shared_memory_holder pMemory);
  32. void mark_defined() {
  33. if (is_defined())
  34. return;
  35. m_pRef->mark_defined();
  36. for (node* dependency : m_dependencies)
  37. dependency->mark_defined();
  38. m_dependencies.clear();
  39. }
  40. void add_dependency(node& rhs) {
  41. if (is_defined())
  42. rhs.mark_defined();
  43. else
  44. m_dependencies.insert(&rhs);
  45. }
  46. void set_ref(const node& rhs) {
  47. if (rhs.is_defined())
  48. mark_defined();
  49. m_pRef = rhs.m_pRef;
  50. }
  51. void set_data(const node& rhs) {
  52. if (rhs.is_defined())
  53. mark_defined();
  54. m_pRef->set_data(*rhs.m_pRef);
  55. }
  56. void set_mark(const Mark& mark) { m_pRef->set_mark(mark); }
  57. void set_type(NodeType::value type) {
  58. if (type != NodeType::Undefined)
  59. mark_defined();
  60. m_pRef->set_type(type);
  61. }
  62. void set_null() {
  63. mark_defined();
  64. m_pRef->set_null();
  65. }
  66. void set_scalar(const std::string& scalar) {
  67. mark_defined();
  68. m_pRef->set_scalar(scalar);
  69. }
  70. void set_tag(const std::string& tag) {
  71. mark_defined();
  72. m_pRef->set_tag(tag);
  73. }
  74. // style
  75. void set_style(EmitterStyle::value style) {
  76. mark_defined();
  77. m_pRef->set_style(style);
  78. }
  79. // size/iterator
  80. std::size_t size() const { return m_pRef->size(); }
  81. const_node_iterator begin() const {
  82. return static_cast<const node_ref&>(*m_pRef).begin();
  83. }
  84. node_iterator begin() { return m_pRef->begin(); }
  85. const_node_iterator end() const {
  86. return static_cast<const node_ref&>(*m_pRef).end();
  87. }
  88. node_iterator end() { return m_pRef->end(); }
  89. // sequence
  90. void push_back(node& input, shared_memory_holder pMemory) {
  91. m_pRef->push_back(input, pMemory);
  92. input.add_dependency(*this);
  93. }
  94. void insert(node& key, node& value, shared_memory_holder pMemory) {
  95. m_pRef->insert(key, value, pMemory);
  96. key.add_dependency(*this);
  97. value.add_dependency(*this);
  98. }
  99. // indexing
  100. template <typename Key>
  101. node* get(const Key& key, shared_memory_holder pMemory) const {
  102. // NOTE: this returns a non-const node so that the top-level Node can wrap
  103. // it, and returns a pointer so that it can be NULL (if there is no such
  104. // key).
  105. return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
  106. }
  107. template <typename Key>
  108. node& get(const Key& key, shared_memory_holder pMemory) {
  109. node& value = m_pRef->get(key, pMemory);
  110. value.add_dependency(*this);
  111. return value;
  112. }
  113. template <typename Key>
  114. bool remove(const Key& key, shared_memory_holder pMemory) {
  115. return m_pRef->remove(key, pMemory);
  116. }
  117. node* get(node& key, shared_memory_holder pMemory) const {
  118. // NOTE: this returns a non-const node so that the top-level Node can wrap
  119. // it, and returns a pointer so that it can be NULL (if there is no such
  120. // key).
  121. return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
  122. }
  123. node& get(node& key, shared_memory_holder pMemory) {
  124. node& value = m_pRef->get(key, pMemory);
  125. key.add_dependency(*this);
  126. value.add_dependency(*this);
  127. return value;
  128. }
  129. bool remove(node& key, shared_memory_holder pMemory) {
  130. return m_pRef->remove(key, pMemory);
  131. }
  132. // map
  133. template <typename Key, typename Value>
  134. void force_insert(const Key& key, const Value& value,
  135. shared_memory_holder pMemory) {
  136. m_pRef->force_insert(key, value, pMemory);
  137. }
  138. private:
  139. shared_node_ref m_pRef;
  140. using nodes = std::set<node*>;
  141. nodes m_dependencies;
  142. };
  143. } // namespace detail
  144. } // namespace YAML
  145. #endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66