impl.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
  2. #define NODE_DETAIL_IMPL_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/node/detail/node.h"
  9. #include "yaml-cpp/node/detail/node_data.h"
  10. #include <type_traits>
  11. namespace YAML {
  12. namespace detail {
  13. template <typename Key, typename Enable = void>
  14. struct get_idx {
  15. static node* get(const std::vector<node*>& /* sequence */,
  16. const Key& /* key */, shared_memory_holder /* pMemory */) {
  17. return 0;
  18. }
  19. };
  20. template <typename Key>
  21. struct get_idx<Key,
  22. typename std::enable_if<std::is_unsigned<Key>::value &&
  23. !std::is_same<Key, bool>::value>::type> {
  24. static node* get(const std::vector<node*>& sequence, const Key& key,
  25. shared_memory_holder /* pMemory */) {
  26. return key < sequence.size() ? sequence[key] : 0;
  27. }
  28. static node* get(std::vector<node*>& sequence, const Key& key,
  29. shared_memory_holder pMemory) {
  30. if (key > sequence.size() || (key > 0 && !sequence[key-1]->is_defined()))
  31. return 0;
  32. if (key == sequence.size())
  33. sequence.push_back(&pMemory->create_node());
  34. return sequence[key];
  35. }
  36. };
  37. template <typename Key>
  38. struct get_idx<Key, typename std::enable_if<std::is_signed<Key>::value>::type> {
  39. static node* get(const std::vector<node*>& sequence, const Key& key,
  40. shared_memory_holder pMemory) {
  41. return key >= 0 ? get_idx<std::size_t>::get(
  42. sequence, static_cast<std::size_t>(key), pMemory)
  43. : 0;
  44. }
  45. static node* get(std::vector<node*>& sequence, const Key& key,
  46. shared_memory_holder pMemory) {
  47. return key >= 0 ? get_idx<std::size_t>::get(
  48. sequence, static_cast<std::size_t>(key), pMemory)
  49. : 0;
  50. }
  51. };
  52. template <typename T>
  53. inline bool node::equals(const T& rhs, shared_memory_holder pMemory) {
  54. T lhs;
  55. if (convert<T>::decode(Node(*this, pMemory), lhs)) {
  56. return lhs == rhs;
  57. }
  58. return false;
  59. }
  60. inline bool node::equals(const char* rhs, shared_memory_holder pMemory) {
  61. return equals<std::string>(rhs, pMemory);
  62. }
  63. // indexing
  64. template <typename Key>
  65. inline node* node_data::get(const Key& key,
  66. shared_memory_holder pMemory) const {
  67. switch (m_type) {
  68. case NodeType::Map:
  69. break;
  70. case NodeType::Undefined:
  71. case NodeType::Null:
  72. return NULL;
  73. case NodeType::Sequence:
  74. if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory))
  75. return pNode;
  76. return NULL;
  77. case NodeType::Scalar:
  78. throw BadSubscript();
  79. }
  80. for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
  81. if (it->first->equals(key, pMemory)) {
  82. return it->second;
  83. }
  84. }
  85. return NULL;
  86. }
  87. template <typename Key>
  88. inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
  89. switch (m_type) {
  90. case NodeType::Map:
  91. break;
  92. case NodeType::Undefined:
  93. case NodeType::Null:
  94. case NodeType::Sequence:
  95. if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory)) {
  96. m_type = NodeType::Sequence;
  97. return *pNode;
  98. }
  99. convert_to_map(pMemory);
  100. break;
  101. case NodeType::Scalar:
  102. throw BadSubscript();
  103. }
  104. for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
  105. if (it->first->equals(key, pMemory)) {
  106. return *it->second;
  107. }
  108. }
  109. node& k = convert_to_node(key, pMemory);
  110. node& v = pMemory->create_node();
  111. insert_map_pair(k, v);
  112. return v;
  113. }
  114. template <typename Key>
  115. inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) {
  116. if (m_type != NodeType::Map)
  117. return false;
  118. for (kv_pairs::iterator it = m_undefinedPairs.begin();
  119. it != m_undefinedPairs.end();) {
  120. kv_pairs::iterator jt = std::next(it);
  121. if (it->first->equals(key, pMemory))
  122. m_undefinedPairs.erase(it);
  123. it = jt;
  124. }
  125. for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
  126. if (it->first->equals(key, pMemory)) {
  127. m_map.erase(it);
  128. return true;
  129. }
  130. }
  131. return false;
  132. }
  133. // map
  134. template <typename Key, typename Value>
  135. inline void node_data::force_insert(const Key& key, const Value& value,
  136. shared_memory_holder pMemory) {
  137. switch (m_type) {
  138. case NodeType::Map:
  139. break;
  140. case NodeType::Undefined:
  141. case NodeType::Null:
  142. case NodeType::Sequence:
  143. convert_to_map(pMemory);
  144. break;
  145. case NodeType::Scalar:
  146. throw BadInsert();
  147. }
  148. node& k = convert_to_node(key, pMemory);
  149. node& v = convert_to_node(value, pMemory);
  150. insert_map_pair(k, v);
  151. }
  152. template <typename T>
  153. inline node& node_data::convert_to_node(const T& rhs,
  154. shared_memory_holder pMemory) {
  155. Node value = convert<T>::encode(rhs);
  156. value.EnsureNodeExists();
  157. pMemory->merge(*value.m_pMemory);
  158. return *value.m_pNode;
  159. }
  160. }
  161. }
  162. #endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66