impl.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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 nullptr;
  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] : nullptr;
  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. : nullptr;
  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. : nullptr;
  50. }
  51. };
  52. template <typename Key, typename Enable = void>
  53. struct remove_idx {
  54. static bool remove(std::vector<node*>&, const Key&) { return false; }
  55. };
  56. template <typename Key>
  57. struct remove_idx<
  58. Key, typename std::enable_if<std::is_unsigned<Key>::value &&
  59. !std::is_same<Key, bool>::value>::type> {
  60. static bool remove(std::vector<node*>& sequence, const Key& key) {
  61. if (key >= sequence.size()) {
  62. return false;
  63. } else {
  64. sequence.erase(sequence.begin() + key);
  65. return true;
  66. }
  67. }
  68. };
  69. template <typename Key>
  70. struct remove_idx<Key,
  71. typename std::enable_if<std::is_signed<Key>::value>::type> {
  72. static bool remove(std::vector<node*>& sequence, const Key& key) {
  73. return key >= 0 ? remove_idx<std::size_t>::remove(
  74. sequence, static_cast<std::size_t>(key))
  75. : false;
  76. }
  77. };
  78. template <typename T>
  79. inline bool node::equals(const T& rhs, shared_memory_holder pMemory) {
  80. T lhs;
  81. if (convert<T>::decode(Node(*this, pMemory), lhs)) {
  82. return lhs == rhs;
  83. }
  84. return false;
  85. }
  86. inline bool node::equals(const char* rhs, shared_memory_holder pMemory) {
  87. return equals<std::string>(rhs, pMemory);
  88. }
  89. // indexing
  90. template <typename Key>
  91. inline node* node_data::get(const Key& key,
  92. shared_memory_holder pMemory) const {
  93. switch (m_type) {
  94. case NodeType::Map:
  95. break;
  96. case NodeType::Undefined:
  97. case NodeType::Null:
  98. return nullptr;
  99. case NodeType::Sequence:
  100. if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory))
  101. return pNode;
  102. return nullptr;
  103. case NodeType::Scalar:
  104. throw BadSubscript(key);
  105. }
  106. for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
  107. if (it->first->equals(key, pMemory)) {
  108. return it->second;
  109. }
  110. }
  111. return nullptr;
  112. }
  113. template <typename Key>
  114. inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
  115. switch (m_type) {
  116. case NodeType::Map:
  117. break;
  118. case NodeType::Undefined:
  119. case NodeType::Null:
  120. case NodeType::Sequence:
  121. if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory)) {
  122. m_type = NodeType::Sequence;
  123. return *pNode;
  124. }
  125. convert_to_map(pMemory);
  126. break;
  127. case NodeType::Scalar:
  128. throw BadSubscript(key);
  129. }
  130. for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
  131. if (it->first->equals(key, pMemory)) {
  132. return *it->second;
  133. }
  134. }
  135. node& k = convert_to_node(key, pMemory);
  136. node& v = pMemory->create_node();
  137. insert_map_pair(k, v);
  138. return v;
  139. }
  140. template <typename Key>
  141. inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) {
  142. if (m_type == NodeType::Sequence) {
  143. return remove_idx<Key>::remove(m_sequence, key);
  144. } else if (m_type == NodeType::Map) {
  145. kv_pairs::iterator it = m_undefinedPairs.begin();
  146. while (it != m_undefinedPairs.end()) {
  147. kv_pairs::iterator jt = std::next(it);
  148. if (it->first->equals(key, pMemory)) {
  149. m_undefinedPairs.erase(it);
  150. }
  151. it = jt;
  152. }
  153. for (node_map::iterator iter = m_map.begin(); iter != m_map.end(); ++iter) {
  154. if (iter->first->equals(key, pMemory)) {
  155. m_map.erase(iter);
  156. return true;
  157. }
  158. }
  159. }
  160. return false;
  161. }
  162. // map
  163. template <typename Key, typename Value>
  164. inline void node_data::force_insert(const Key& key, const Value& value,
  165. shared_memory_holder pMemory) {
  166. switch (m_type) {
  167. case NodeType::Map:
  168. break;
  169. case NodeType::Undefined:
  170. case NodeType::Null:
  171. case NodeType::Sequence:
  172. convert_to_map(pMemory);
  173. break;
  174. case NodeType::Scalar:
  175. throw BadInsert();
  176. }
  177. node& k = convert_to_node(key, pMemory);
  178. node& v = convert_to_node(value, pMemory);
  179. insert_map_pair(k, v);
  180. }
  181. template <typename T>
  182. inline node& node_data::convert_to_node(const T& rhs,
  183. shared_memory_holder pMemory) {
  184. Node value = convert<T>::encode(rhs);
  185. value.EnsureNodeExists();
  186. pMemory->merge(*value.m_pMemory);
  187. return *value.m_pNode;
  188. }
  189. }
  190. }
  191. #endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66