void DictionaryValue::setElement(Value const &index, Value *value) { Elements::iterator i = _elements.find(ValueRef(&index)); if (i == _elements.end()) { // Add it to the dictionary. _elements[ValueRef(index.duplicate())] = value; } else { delete i->second; i->second = value; } }
void DictionaryValue::remove(Value const &key) { Elements::iterator i = _elements.find(ValueRef(&key)); if (i != _elements.end()) { remove(i); } }
DictionaryValue::DictionaryValue(DictionaryValue const &other) : Value(), /*_iteration(0),*/ _validIteration(false) { for (Elements::const_iterator i = other._elements.begin(); i != other._elements.end(); ++i) { Value *value = i->second->duplicate(); _elements[ValueRef(i->first.value->duplicate())] = value; } }
void DictionaryValue::add(Value *key, Value *value) { Elements::iterator existing = _elements.find(ValueRef(key)); if (existing != _elements.end()) { // Found it. Replace old value. delete existing->second; existing->second = value; // We already have the key, so the new one is unnecessary. delete key; } else { // Set new value. _elements[ValueRef(key)] = value; } }
Value const &DictionaryValue::element(Value const &index) const { Elements::const_iterator i = _elements.find(ValueRef(&index)); if (i == _elements.end()) { throw KeyError("DictionaryValue::element", "Key '" + index.asText() + "' does not exist in the dictionary"); } return *i->second; }
void DictionaryValue::subtract(Value const &subtrahend) { Elements::iterator i = _elements.find(ValueRef(&subtrahend)); if (i == _elements.end()) { throw KeyError("DictionaryValue::subtract", "Key '" + subtrahend.asText() + "' does not exist in the dictionary"); } delete i->second; _elements.erase(i); }
std::shared_ptr<MultiChange> GrtListDiff::diff(const BaseListRef &source, const BaseListRef &target, const Omf *omf) { typedef std::vector<size_t> TIndexContainer; default_omf def_omf; std::vector<std::shared_ptr<ListItemChange> > changes; const Omf *comparer = omf ? omf : &def_omf; ValueRef prev_value; // This is indexes of source's elements that exist in both target and source // in order of element appearance in target // We need to swap indexes(and eventually elements) so that source's elements order // will become the same as target's TIndexContainer source_indexes; // new indexes for already existing elements TIndexContainer ordered_indexes; // ordered indexes list for set_difference for (size_t target_idx = 0; target_idx < target.count(); ++target_idx) { // look for something that exists in target but not in source, it should be added const ValueRef v = target.get(target_idx); internal::List::raw_const_iterator It_Dup = find_if( target.content().raw_begin(), target.content().raw_begin() + target_idx, std::bind2nd(OmfEqPred(comparer), v)); if (It_Dup != target.content().raw_begin() + target_idx) continue; internal::List::raw_const_iterator It = find_if(source.content().raw_begin(), source.content().raw_end(), std::bind2nd(OmfEqPred(comparer), v)); if (It == source.content().raw_end()) changes.push_back(std::shared_ptr<ListItemChange>(new ListItemAddedChange(v, prev_value, target_idx))); else // item exists in both target and source, save indexes source_indexes.push_back(source.get_index(*It)); prev_value = v; }; for (size_t source_idx = 0; source_idx < source.count(); ++source_idx) { // look for something that exists in source but not in target, it should be removed const ValueRef v = source.get(source_idx); // This shouldn't happend actually, since lists are expected to be unique // But in case of caseless compare we may have non-unique lists // so just skip it internal::List::raw_const_iterator It_Dup = find_if( source.content().raw_begin(), source.content().raw_begin() + source_idx, std::bind2nd(OmfEqPred(comparer), v)); if (It_Dup != source.content().raw_begin() + source_idx) continue; internal::List::raw_const_iterator It = find_if(target.content().raw_begin(), target.content().raw_end(), std::bind2nd(OmfEqPred(comparer), v)); if (It == target.content().raw_end()) { #ifdef DEBUG_DIFF logInfo("Removing %s from list\n", grt::ObjectRef::cast_from(v)->get_string_member("name").c_str()); if (grt::ObjectRef::cast_from(v)->get_string_member("name") == "fk_tblClientApp_base_tblClient_base1_idx") dump_value(target); #endif changes.push_back(std::shared_ptr<ListItemChange>(new ListItemRemovedChange(v, source_idx))); } else ordered_indexes.push_back(source_idx); }; // return changes.empty()? NULL : new MultiChange(ListModified, changes);// No ListItemOrderChange TIndexContainer stable_elements; reversed_LIS(source_indexes, stable_elements); TIndexContainer moved_elements(source_indexes.size() - stable_elements.size()); std::set_difference(ordered_indexes.begin(), ordered_indexes.end(), stable_elements.rbegin(), stable_elements.rend(), moved_elements.begin()); for (TIndexContainer::iterator It = moved_elements.begin(); It != moved_elements.end(); ++It) { internal::List::raw_const_iterator It_target = find_if(target.content().raw_begin(), target.content().raw_end(), std::bind2nd(OmfEqPred(comparer), source.get(*It))); prev_value = It_target == target.content().raw_begin() ? ValueRef() : *(It_target - 1); std::shared_ptr<ListItemOrderChange> orderchange( new ListItemOrderChange(source.get(*It), *It_target, omf, prev_value, target.get_index(*It_target))); // if (!orderchange->subchanges()->empty()) changes.push_back(orderchange); } for (TIndexContainer::iterator It = stable_elements.begin(); It != stable_elements.end(); ++It) { internal::List::raw_const_iterator It_target = find_if(target.content().raw_begin(), target.content().raw_end(), std::bind2nd(OmfEqPred(comparer), source.get(*It))); if (It_target != target.content().raw_end()) { std::shared_ptr<ListItemChange> change = create_item_modified_change(source.get(*It), *It_target, omf, target.get_index(*It_target)); if (change) changes.push_back(change); } } ChangeSet retval; std::sort(changes.begin(), changes.end(), diffPred); for (std::vector<std::shared_ptr<ListItemChange> >::const_iterator It = changes.begin(); It != changes.end(); ++It) retval.append(*It); return retval.empty() ? std::shared_ptr<MultiChange>() : std::shared_ptr<MultiChange>(new MultiChange(ListModified, retval)); }
Settings::ValueRef Settings::set(Key k, Section s){ Settings &self = instance(); return ValueRef(self, self.keyPath(s, k)); }
bool DictionaryValue::contains(Value const &value) const { return _elements.find(ValueRef(&value)) != _elements.end(); }