File indexing completed on 2025-01-18 10:15:43
0001 #ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
0002 #define NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
0003
0004 #if defined(_MSC_VER) || \
0005 (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
0006 (__GNUC__ >= 4))
0007 #pragma once
0008 #endif
0009
0010 #include "yaml-cpp/node/detail/node.h"
0011 #include "yaml-cpp/node/detail/node_data.h"
0012
0013 #include <algorithm>
0014 #include <type_traits>
0015
0016 namespace YAML {
0017 namespace detail {
0018 template <typename Key, typename Enable = void>
0019 struct get_idx {
0020 static node* get(const std::vector<node*>& ,
0021 const Key& , shared_memory_holder ) {
0022 return nullptr;
0023 }
0024 };
0025
0026 template <typename Key>
0027 struct get_idx<Key,
0028 typename std::enable_if<std::is_unsigned<Key>::value &&
0029 !std::is_same<Key, bool>::value>::type> {
0030 static node* get(const std::vector<node*>& sequence, const Key& key,
0031 shared_memory_holder ) {
0032 return key < sequence.size() ? sequence[key] : nullptr;
0033 }
0034
0035 static node* get(std::vector<node*>& sequence, const Key& key,
0036 shared_memory_holder pMemory) {
0037 if (key > sequence.size() || (key > 0 && !sequence[key - 1]->is_defined()))
0038 return nullptr;
0039 if (key == sequence.size())
0040 sequence.push_back(&pMemory->create_node());
0041 return sequence[key];
0042 }
0043 };
0044
0045 template <typename Key>
0046 struct get_idx<Key, typename std::enable_if<std::is_signed<Key>::value>::type> {
0047 static node* get(const std::vector<node*>& sequence, const Key& key,
0048 shared_memory_holder pMemory) {
0049 return key >= 0 ? get_idx<std::size_t>::get(
0050 sequence, static_cast<std::size_t>(key), pMemory)
0051 : nullptr;
0052 }
0053 static node* get(std::vector<node*>& sequence, const Key& key,
0054 shared_memory_holder pMemory) {
0055 return key >= 0 ? get_idx<std::size_t>::get(
0056 sequence, static_cast<std::size_t>(key), pMemory)
0057 : nullptr;
0058 }
0059 };
0060
0061 template <typename Key, typename Enable = void>
0062 struct remove_idx {
0063 static bool remove(std::vector<node*>&, const Key&, std::size_t&) {
0064 return false;
0065 }
0066 };
0067
0068 template <typename Key>
0069 struct remove_idx<
0070 Key, typename std::enable_if<std::is_unsigned<Key>::value &&
0071 !std::is_same<Key, bool>::value>::type> {
0072
0073 static bool remove(std::vector<node*>& sequence, const Key& key,
0074 std::size_t& seqSize) {
0075 if (key >= sequence.size()) {
0076 return false;
0077 } else {
0078 sequence.erase(sequence.begin() + key);
0079 if (seqSize > key) {
0080 --seqSize;
0081 }
0082 return true;
0083 }
0084 }
0085 };
0086
0087 template <typename Key>
0088 struct remove_idx<Key,
0089 typename std::enable_if<std::is_signed<Key>::value>::type> {
0090
0091 static bool remove(std::vector<node*>& sequence, const Key& key,
0092 std::size_t& seqSize) {
0093 return key >= 0 ? remove_idx<std::size_t>::remove(
0094 sequence, static_cast<std::size_t>(key), seqSize)
0095 : false;
0096 }
0097 };
0098
0099 template <typename T>
0100 inline bool node::equals(const T& rhs, shared_memory_holder pMemory) {
0101 T lhs;
0102 if (convert<T>::decode(Node(*this, pMemory), lhs)) {
0103 return lhs == rhs;
0104 }
0105 return false;
0106 }
0107
0108 inline bool node::equals(const char* rhs, shared_memory_holder pMemory) {
0109 std::string lhs;
0110 if (convert<std::string>::decode(Node(*this, std::move(pMemory)), lhs)) {
0111 return lhs == rhs;
0112 }
0113 return false;
0114 }
0115
0116
0117 template <typename Key>
0118 inline node* node_data::get(const Key& key,
0119 shared_memory_holder pMemory) const {
0120 switch (m_type) {
0121 case NodeType::Map:
0122 break;
0123 case NodeType::Undefined:
0124 case NodeType::Null:
0125 return nullptr;
0126 case NodeType::Sequence:
0127 if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory))
0128 return pNode;
0129 return nullptr;
0130 case NodeType::Scalar:
0131 throw BadSubscript(m_mark, key);
0132 }
0133
0134 auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) {
0135 return m.first->equals(key, pMemory);
0136 });
0137
0138 return it != m_map.end() ? it->second : nullptr;
0139 }
0140
0141 template <typename Key>
0142 inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
0143 switch (m_type) {
0144 case NodeType::Map:
0145 break;
0146 case NodeType::Undefined:
0147 case NodeType::Null:
0148 case NodeType::Sequence:
0149 if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory)) {
0150 m_type = NodeType::Sequence;
0151 return *pNode;
0152 }
0153
0154 convert_to_map(pMemory);
0155 break;
0156 case NodeType::Scalar:
0157 throw BadSubscript(m_mark, key);
0158 }
0159
0160 auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) {
0161 return m.first->equals(key, pMemory);
0162 });
0163
0164 if (it != m_map.end()) {
0165 return *it->second;
0166 }
0167
0168 node& k = convert_to_node(key, pMemory);
0169 node& v = pMemory->create_node();
0170 insert_map_pair(k, v);
0171 return v;
0172 }
0173
0174 template <typename Key>
0175 inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) {
0176 if (m_type == NodeType::Sequence) {
0177 return remove_idx<Key>::remove(m_sequence, key, m_seqSize);
0178 }
0179
0180 if (m_type == NodeType::Map) {
0181 kv_pairs::iterator it = m_undefinedPairs.begin();
0182 while (it != m_undefinedPairs.end()) {
0183 kv_pairs::iterator jt = std::next(it);
0184 if (it->first->equals(key, pMemory)) {
0185 m_undefinedPairs.erase(it);
0186 }
0187 it = jt;
0188 }
0189
0190 auto iter = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) {
0191 return m.first->equals(key, pMemory);
0192 });
0193
0194 if (iter != m_map.end()) {
0195 m_map.erase(iter);
0196 return true;
0197 }
0198 }
0199
0200 return false;
0201 }
0202
0203
0204 template <typename Key, typename Value>
0205 inline void node_data::force_insert(const Key& key, const Value& value,
0206 shared_memory_holder pMemory) {
0207 switch (m_type) {
0208 case NodeType::Map:
0209 break;
0210 case NodeType::Undefined:
0211 case NodeType::Null:
0212 case NodeType::Sequence:
0213 convert_to_map(pMemory);
0214 break;
0215 case NodeType::Scalar:
0216 throw BadInsert();
0217 }
0218
0219 node& k = convert_to_node(key, pMemory);
0220 node& v = convert_to_node(value, pMemory);
0221 insert_map_pair(k, v);
0222 }
0223
0224 template <typename T>
0225 inline node& node_data::convert_to_node(const T& rhs,
0226 shared_memory_holder pMemory) {
0227 Node value = convert<T>::encode(rhs);
0228 value.EnsureNodeExists();
0229 pMemory->merge(*value.m_pMemory);
0230 return *value.m_pNode;
0231 }
0232 }
0233 }
0234
0235 #endif