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