node.h 5.0 KB

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