178 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			178 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								#ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
							 | 
						||
| 
								 | 
							
								#define NODE_DETAIL_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 "yaml-cpp/dll.h"
							 | 
						||
| 
								 | 
							
								#include "yaml-cpp/emitterstyle.h"
							 | 
						||
| 
								 | 
							
								#include "yaml-cpp/node/detail/node_ref.h"
							 | 
						||
| 
								 | 
							
								#include "yaml-cpp/node/ptr.h"
							 | 
						||
| 
								 | 
							
								#include "yaml-cpp/node/type.h"
							 | 
						||
| 
								 | 
							
								#include <set>
							 | 
						||
| 
								 | 
							
								#include <atomic>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace YAML {
							 | 
						||
| 
								 | 
							
								namespace detail {
							 | 
						||
| 
								 | 
							
								class node {
							 | 
						||
| 
								 | 
							
								 private:
							 | 
						||
| 
								 | 
							
								  struct less {
							 | 
						||
| 
								 | 
							
								    bool operator ()(const node* l, const node* r) const {return l->m_index < r->m_index;}
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 public:
							 | 
						||
| 
								 | 
							
								  node() : m_pRef(new node_ref), m_dependencies{}, m_index{} {}
							 | 
						||
| 
								 | 
							
								  node(const node&) = delete;
							 | 
						||
| 
								 | 
							
								  node& operator=(const node&) = delete;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; }
							 | 
						||
| 
								 | 
							
								  const node_ref* ref() const { return m_pRef.get(); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  bool is_defined() const { return m_pRef->is_defined(); }
							 | 
						||
| 
								 | 
							
								  const Mark& mark() const { return m_pRef->mark(); }
							 | 
						||
| 
								 | 
							
								  NodeType::value type() const { return m_pRef->type(); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const std::string& scalar() const { return m_pRef->scalar(); }
							 | 
						||
| 
								 | 
							
								  const std::string& tag() const { return m_pRef->tag(); }
							 | 
						||
| 
								 | 
							
								  EmitterStyle::value style() const { return m_pRef->style(); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  template <typename T>
							 | 
						||
| 
								 | 
							
								  bool equals(const T& rhs, shared_memory_holder pMemory);
							 | 
						||
| 
								 | 
							
								  bool equals(const char* rhs, shared_memory_holder pMemory);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  void mark_defined() {
							 | 
						||
| 
								 | 
							
								    if (is_defined())
							 | 
						||
| 
								 | 
							
								      return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    m_pRef->mark_defined();
							 | 
						||
| 
								 | 
							
								    for (node* dependency : m_dependencies)
							 | 
						||
| 
								 | 
							
								      dependency->mark_defined();
							 | 
						||
| 
								 | 
							
								    m_dependencies.clear();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  void add_dependency(node& rhs) {
							 | 
						||
| 
								 | 
							
								    if (is_defined())
							 | 
						||
| 
								 | 
							
								      rhs.mark_defined();
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								      m_dependencies.insert(&rhs);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  void set_ref(const node& rhs) {
							 | 
						||
| 
								 | 
							
								    if (rhs.is_defined())
							 | 
						||
| 
								 | 
							
								      mark_defined();
							 | 
						||
| 
								 | 
							
								    m_pRef = rhs.m_pRef;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  void set_data(const node& rhs) {
							 | 
						||
| 
								 | 
							
								    if (rhs.is_defined())
							 | 
						||
| 
								 | 
							
								      mark_defined();
							 | 
						||
| 
								 | 
							
								    m_pRef->set_data(*rhs.m_pRef);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  void set_mark(const Mark& mark) { m_pRef->set_mark(mark); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  void set_type(NodeType::value type) {
							 | 
						||
| 
								 | 
							
								    if (type != NodeType::Undefined)
							 | 
						||
| 
								 | 
							
								      mark_defined();
							 | 
						||
| 
								 | 
							
								    m_pRef->set_type(type);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  void set_null() {
							 | 
						||
| 
								 | 
							
								    mark_defined();
							 | 
						||
| 
								 | 
							
								    m_pRef->set_null();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  void set_scalar(const std::string& scalar) {
							 | 
						||
| 
								 | 
							
								    mark_defined();
							 | 
						||
| 
								 | 
							
								    m_pRef->set_scalar(scalar);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  void set_tag(const std::string& tag) {
							 | 
						||
| 
								 | 
							
								    mark_defined();
							 | 
						||
| 
								 | 
							
								    m_pRef->set_tag(tag);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // style
							 | 
						||
| 
								 | 
							
								  void set_style(EmitterStyle::value style) {
							 | 
						||
| 
								 | 
							
								    mark_defined();
							 | 
						||
| 
								 | 
							
								    m_pRef->set_style(style);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // size/iterator
							 | 
						||
| 
								 | 
							
								  std::size_t size() const { return m_pRef->size(); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const_node_iterator begin() const {
							 | 
						||
| 
								 | 
							
								    return static_cast<const node_ref&>(*m_pRef).begin();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  node_iterator begin() { return m_pRef->begin(); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const_node_iterator end() const {
							 | 
						||
| 
								 | 
							
								    return static_cast<const node_ref&>(*m_pRef).end();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  node_iterator end() { return m_pRef->end(); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // sequence
							 | 
						||
| 
								 | 
							
								  void push_back(node& input, shared_memory_holder pMemory) {
							 | 
						||
| 
								 | 
							
								    m_pRef->push_back(input, pMemory);
							 | 
						||
| 
								 | 
							
								    input.add_dependency(*this);
							 | 
						||
| 
								 | 
							
								    m_index = m_amount.fetch_add(1);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  void insert(node& key, node& value, shared_memory_holder pMemory) {
							 | 
						||
| 
								 | 
							
								    m_pRef->insert(key, value, pMemory);
							 | 
						||
| 
								 | 
							
								    key.add_dependency(*this);
							 | 
						||
| 
								 | 
							
								    value.add_dependency(*this);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // indexing
							 | 
						||
| 
								 | 
							
								  template <typename Key>
							 | 
						||
| 
								 | 
							
								  node* get(const Key& key, shared_memory_holder pMemory) const {
							 | 
						||
| 
								 | 
							
								    // NOTE: this returns a non-const node so that the top-level Node can wrap
							 | 
						||
| 
								 | 
							
								    // it, and returns a pointer so that it can be nullptr (if there is no such
							 | 
						||
| 
								 | 
							
								    // key).
							 | 
						||
| 
								 | 
							
								    return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  template <typename Key>
							 | 
						||
| 
								 | 
							
								  node& get(const Key& key, shared_memory_holder pMemory) {
							 | 
						||
| 
								 | 
							
								    node& value = m_pRef->get(key, pMemory);
							 | 
						||
| 
								 | 
							
								    value.add_dependency(*this);
							 | 
						||
| 
								 | 
							
								    return value;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  template <typename Key>
							 | 
						||
| 
								 | 
							
								  bool remove(const Key& key, shared_memory_holder pMemory) {
							 | 
						||
| 
								 | 
							
								    return m_pRef->remove(key, pMemory);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  node* get(node& key, shared_memory_holder pMemory) const {
							 | 
						||
| 
								 | 
							
								    // NOTE: this returns a non-const node so that the top-level Node can wrap
							 | 
						||
| 
								 | 
							
								    // it, and returns a pointer so that it can be nullptr (if there is no such
							 | 
						||
| 
								 | 
							
								    // key).
							 | 
						||
| 
								 | 
							
								    return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  node& get(node& key, shared_memory_holder pMemory) {
							 | 
						||
| 
								 | 
							
								    node& value = m_pRef->get(key, pMemory);
							 | 
						||
| 
								 | 
							
								    key.add_dependency(*this);
							 | 
						||
| 
								 | 
							
								    value.add_dependency(*this);
							 | 
						||
| 
								 | 
							
								    return value;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  bool remove(node& key, shared_memory_holder pMemory) {
							 | 
						||
| 
								 | 
							
								    return m_pRef->remove(key, pMemory);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // map
							 | 
						||
| 
								 | 
							
								  template <typename Key, typename Value>
							 | 
						||
| 
								 | 
							
								  void force_insert(const Key& key, const Value& value,
							 | 
						||
| 
								 | 
							
								                    shared_memory_holder pMemory) {
							 | 
						||
| 
								 | 
							
								    m_pRef->force_insert(key, value, pMemory);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 private:
							 | 
						||
| 
								 | 
							
								  shared_node_ref m_pRef;
							 | 
						||
| 
								 | 
							
								  using nodes = std::set<node*, less>;
							 | 
						||
| 
								 | 
							
								  nodes m_dependencies;
							 | 
						||
| 
								 | 
							
								  size_t m_index;
							 | 
						||
| 
								 | 
							
								  static YAML_CPP_API std::atomic<size_t> m_amount;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								}  // namespace detail
							 | 
						||
| 
								 | 
							
								}  // namespace YAML
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif  // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
							 |