/***************************************************************************** * Dictionary.h * * * * XFX System::Collections::Generic::Dictionary class definition file * * Copyright (c) XFX Team. All Rights Reserved * *****************************************************************************/ #ifndef _SYSTEM_COLLECTIONS_GENERIC_DICTIONARY_ #define _SYSTEM_COLLECTIONS_GENERIC_DICTIONARY_ #include #include #include "EqualityComparer.h" #include "Interfaces.h" #include "KeyValuePair.h" #include "List.h" #include namespace System { namespace Collections { namespace Generic { /** * Represents a collection of keys and values. */ template class Dictionary : public IDictionary, public ICollection >, public IEnumerable >, public Object { private: template struct Entry { UKey Key; UValue Value; Entry* next; Entry(UKey key, UValue value) : Key(key), Value(value), next(NULL) { } }; static const int defaultCapacity = 4; IEqualityComparer* comparer; int _count; Entry** _internalStorage; int _size; int _version; void Add(const KeyValuePair& keyValuePair); bool Contains(const KeyValuePair& keyValuePair) const; void CopyTo(KeyValuePair array[], const int index) const; void EnsureCapacity(int capacity); Entry* FindEntry(const TKey& key) const; bool Remove(const KeyValuePair& keyValuePair); void Initialize(const int capacity); //void Insert(const TKey& key, const TValue& value, const bool add); void Resize(); public: /** * Represents the collection of keys in a Dictionary<,>. */ template class KeyCollection : public ICollection { private: Dictionary const * const _dictionary; public: int Count() const; bool IsReadOnly() const { return true; } KeyCollection(Dictionary const * const dictionary); void Add(const UKey& item); void Clear(); bool Contains(const UKey& item) const; void CopyTo(UKey array[], const int arrayIndex) const; bool Remove(const UKey& item); }; /** * Represents the collection of values in a Dictionary<,>. */ template class ValueCollection : public ICollection { private: Dictionary const * const _dictionary; public: int Count() const; bool IsReadOnly() const { return true; } ValueCollection(Dictionary const * const dictionary); void Add(const UValue& item); void Clear(); bool Contains(const UValue& item) const; void CopyTo(UValue array[], const int arrayIndex) const; bool Remove(const UValue& item); }; public: IEqualityComparer* getComparer() const; int Count() const; bool IsReadOnly() const; KeyCollection* getKeys() const; ValueCollection* getValues() const; TValue& operator[](const TKey& key); Dictionary(); Dictionary(const IDictionary* dictionary); Dictionary(const int capacity); virtual ~Dictionary(); void Add(const TKey& key, const TValue& value); void Clear(); bool ContainsKey(const TKey& key) const; bool ContainsValue(const TValue& value) const; IEnumerator >* GetEnumerator(); static const Type& GetType(); bool Remove(const TKey& key); bool TryGetValue(const TKey& key, out TValue value) const; private: struct DictionaryEnumerator : IEnumerator > { private: Dictionary* _parentDictionary; Entry* currentEntry; public: DictionaryEnumerator(Dictionary* _parentDictionary); KeyValuePair& Current() const; bool MoveNext(); void Reset(); }; }; /////////////////////////////////////////////////////////////////// template int Dictionary::Count() const { return _count; } template bool Dictionary::IsReadOnly() const { return false; } template Dictionary::KeyCollection* Dictionary::getKeys() const { return new KeyCollection(this); } template Dictionary::ValueCollection* Dictionary::getValues() const { return new ValueCollection(this); } template Dictionary::Dictionary() : _count(0), _size(defaultCapacity), _version(0) { _internalStorage = new Entry*[defaultCapacity]; for (int i = 0; i < _size; i++) _internalStorage[i] = NULL; } template Dictionary::Dictionary(const IDictionary* dictionary) : _count(0), _size(dictionary->Keys()->Count()), _version(0) { _internalStorage = new Entry*[_size]; IEnumerator >* enumerator = dictionary->GetEnumerator(); enumerator->Reset(); while (enumerator->MoveNext()) { this->Add(enumerator->Current()); } } template Dictionary::Dictionary(const int capacity) : _count(0), _size(capacity), _version(0) { _internalStorage = new Entry*[capacity]; for (int i = 0; i < _size; i++) _internalStorage[i] = NULL; } template Dictionary::~Dictionary() { for (int i = 0; i < _size; i++) { if (_internalStorage[i] != NULL) { Entry* prevEntry = NULL; Entry* entry = _internalStorage[i]; while (entry != NULL) { prevEntry = entry; entry = entry->next; delete prevEntry; } } } delete[] _internalStorage; } template void Dictionary::Add(const TKey& key, const TValue& value) { int hash = key.GetHashCode() % _size; if (_internalStorage[hash] == NULL) _internalStorage[hash] = new Entry(TKey(key), TValue(value)); else { Entry* entry = _internalStorage[hash]; while (entry->next != NULL) entry = entry->next; if (entry->Key == key) return; // throw error else entry->next = new Entry(TKey(key), TValue(value)); } _count++; } template void Dictionary::Add(const KeyValuePair& keyValuePair) { int hash = keyValuePair.Key.GetHashCode() % _size; if (_internalStorage[hash] == NULL) _internalStorage[hash] = new Entry(keyValuePair.Key, keyValuePair.Value); else { Entry* entry = _internalStorage[hash]; while (entry->next != NULL) entry = entry->next; if (entry->Key == keyValuePair.Key) return; // throw error else entry->next = new Entry(keyValuePair.Key, keyValuePair.Value); } _count++; } template bool Dictionary::Contains(const KeyValuePair& keyValuePair) const { // TODO: implement return false; } template bool Dictionary::ContainsKey(const TKey& key) const { int hash = key.GetHashCode() % _size; if (_internalStorage[hash] != NULL) { Entry* entry = _internalStorage[hash]; while (entry->next != NULL) entry = entry->next; return (entry->Key == key); } return false; } template bool Dictionary::ContainsValue(const TValue& value) const { // TODO: implement return false; } template void Dictionary::CopyTo(KeyValuePair array[], const int arrayIndex) const { sassert(false, "Function not implemented."); } template void Dictionary::EnsureCapacity(int capacity) { /*if (_actualSize < capacity) { int num = (_size == 0) ? defaultCapacity : _size * 2; if (num > 0x7fefffff) { num = 0x7fefffff; } if (num < capacity) { num = capacity; } if (num != _size) { if (num > 0) { Entry** destinationArray = new Entry*[num]; if (_count > 0) { for(int i = 0; i < _count; i++) { destinationArray[i] = entries[i]; } } delete[] entries; entries = destinationArray; } else { delete[] entries; entries = new Entry*[0]; } _size = num; } }*/ } template Dictionary::Entry* Dictionary::FindEntry(const TKey& key) const { // TODO: implement /*for (Entry* e = *entries; e != NULL; e = e->next) { if (e->key == key) return e; }*/ return NULL; } template const Type& Dictionary::GetType() { static const Type DictionaryTypeInfo("Dictionary", "System::Collections::Generic::Dictionary", TypeCode::Object, true); return DictionaryTypeInfo; } //template //void Dictionary::Insert(const TKey& key, const TValue& value, const bool add) //{ // Entry* e = FindEntry(key); // if (e) // { // sassert(!add, "Attempting to add duplicate Key/Value pair to dictionary."); // e->value = value; // return; // } // while(e->next != NULL) // { // e = e->next; // } // // e now points to the last element in the list // e->next = new Entry(); // e = e->next; // e->key = key; // e->value = value; // e->next = NULL; // _count++; //} template bool Dictionary::Remove(const KeyValuePair& keyValuePair) { Entry* e = FindEntry(keyValuePair.Key); if (e) { // TODO: implement return true; } return false; } template template int Dictionary::KeyCollection::Count() const { return _dictionary->Count(); } template template Dictionary::KeyCollection::KeyCollection(Dictionary const * const dictionary) : _dictionary(dictionary) { } template template void Dictionary::KeyCollection::Add(const UKey& item) { sassert(false, "Adding keys directly to the Dictionary::Keycollection is not supported."); return; } template template void Dictionary::KeyCollection::Clear() { sassert(false, "Directly clearing the Dictionary::KeyCollection is not supported."); return; } template template bool Dictionary::KeyCollection::Contains(const UKey& item) const { return _dictionary->ContainsKey(item); } template template void Dictionary::KeyCollection::CopyTo(UKey array[], const int arrayIndex) const { sassert(array != NULL, String::Format("array; %s", FrameworkResources::ArgumentNull_Generic)); sassert(arrayIndex >= 0, String::Format("arrayIndex; %s", FrameworkResources::ArgumentOutOfRange_NeedNonNegNum)); // TODO: implement } template template bool Dictionary::KeyCollection::Remove(const UKey& item) { sassert(false, "Removing keys directly from the Dictionary::KeyCollection is not supported."); return false; } template template Dictionary::ValueCollection::ValueCollection(Dictionary const * const dictionary) : _dictionary(dictionary) { } template template int Dictionary::ValueCollection::Count() const { return _dictionary->Count(); } template template void Dictionary::ValueCollection::Add(const UValue& item) { sassert(false, "Adding values directly to the Dictionary::Valuecollection is not supported."); return; } template template void Dictionary::ValueCollection::Clear() { sassert(false, "Directly clearing the Dictionary::ValueCollection is not supported."); return; } template template bool Dictionary::ValueCollection::Contains(const UValue& item) const { return _dictionary->ContainsValue(item); } template template void Dictionary::ValueCollection::CopyTo(UValue array[], const int arrayIndex) const { sassert(array != NULL, String::Format("array; %s", FrameworkResources::ArgumentNull_Generic)); sassert(arrayIndex >= 0, String::Format("arrayIndex; %s", FrameworkResources::ArgumentOutOfRange_NeedNonNegNum)); // TODO: implement } template template bool Dictionary::ValueCollection::Remove(const UValue& item) { sassert(false, "Removing values directly from the Dictionary::ValueCollection is not supported."); return false; } template void Dictionary::Clear() { for (int i = 0; i < _size; i++) { if (_internalStorage[i] != NULL) { Entry* prevEntry = NULL; Entry* entry = _internalStorage[i]; while (entry != NULL) { prevEntry = entry; entry = entry->next; delete prevEntry; } } } _count = 0; } template IEnumerator >* Dictionary::GetEnumerator() { return new DictionaryEnumerator(this); } template bool Dictionary::Remove(const TKey& key) { int hash = key.GetHashCode() % _size; if (_internalStorage[hash] != NULL) { Entry* prevEntry = NULL; Entry* entry = _internalStorage[hash]; while (entry->next != NULL && entry->Key != key) { prevEntry = entry; entry = entry->next; } if (entry->Key == key) { if (prevEntry == NULL) { Entry* nextEntry = entry->next; delete entry; _internalStorage[hash] = nextEntry; } else { Entry* next = entry->next; delete entry; prevEntry->next = next; } return true; } } return false; } template bool Dictionary::TryGetValue(const TKey& key, out TValue value) const { int hash = key.GetHashCode() % _size; if (_internalStorage[hash] != NULL) { // TODO: implement return true; } return false; } template Dictionary::DictionaryEnumerator::DictionaryEnumerator(Dictionary *_parentDictionary) : _parentDictionary(_parentDictionary) { } template KeyValuePair& Dictionary::DictionaryEnumerator::Current() const { KeyValuePair* kv = new KeyValuePair(currentEntry->Key, currentEntry->Value); return *kv; } template bool Dictionary::DictionaryEnumerator::MoveNext() { // TODO: implement /*bool canMove = ((Entry*)*(_parentDictionary->entries))->next != null; if (currentEntry == NULL) currentEntry = *(_parentDictionary->entries); else currentEntry = currentEntry->next;*/ } template void Dictionary::DictionaryEnumerator::Reset() { currentEntry = NULL; } template TValue& Dictionary::operator [](const TKey& key) { int hash = key.GetHashCode() % _size; if (_internalStorage[hash] == NULL) { sassert(false, ""); // KeyNotFoundException } else { Entry* entry = _internalStorage[hash]; while (entry != NULL && entry->Key != key) entry = entry->next; if (entry == NULL) sassert(false, ""); // KeyNotFoundException else return entry->Value; } } } } } #endif //_SYSTEM_COLLECTIONS_GENERIC_DICTIONARY_