#pragma once namespace Jenga{ namespace Common{ #define MAX_HASHMAP 65535 template class Hashmap { T* hashArray[MAX_HASHMAP]; public: virtual int GetHash( const char *keyName ) const { int key; for(key=0;*keyName!='\0';keyName++){ key=((key<<8)+ *keyName )%MAX_HASHMAP; } return key; } Hashmap() : isIteratorReady( false ) { memset( hashArray, 0, MAX_HASHMAP*sizeof(T*) ); } ~Hashmap() { Clear(); } void Clear() { for( int i=0; iGetKeyName().c_str() ); if(hashArray[key]){ T *temp = hashArray[key]; while( true ){ if( temp->IsDuplication( value ) ) { // 重複している return false; } if( temp->GetChainNext() == NULL ) { break; } temp = temp->GetChainNext(); } temp->SetChainNext( value ); } else{ hashArray[key] = value; } return true; } T* GetHashArrayElement( const char *keyName ) { return hashArray[GetHash(keyName)]; } const T* GetHashArrayElement( const char *keyName ) const { return hashArray[GetHash(keyName)]; } bool IsExistDuplicationKeyName( const std::string &keyName ) const { int key = GetHash( keyName.c_str() ); if(hashArray[key]){ const T *temp = hashArray[key]; while( true ){ if( temp->IsDuplication( keyName ) ) { // 重複している return true; } if( temp->GetChainNext() == NULL ) { break; } temp = temp->GetChainNext(); } } return false; } bool IsExist( const T* value ) const { int key = GetHash( value->GetKeyName().c_str() ); if(hashArray[key]){ const T *temp = hashArray[key]; while( true ){ if( temp->IsDuplication( value ) ) { // 重複している return true; } if( temp->GetChainNext() == NULL ) { break; } temp = temp->GetChainNext(); } } return false; } const T *FindLike( const T* value ) const { int key = GetHash( value->GetKeyName().c_str() ); if(hashArray[key]){ const T *temp = hashArray[key]; while( true ){ if( temp->IsDuplication( value ) ) { // 重複している return temp; } if( temp->GetChainNext() == NULL ) { break; } temp = temp->GetChainNext(); } } return NULL; } ///////////////////////////////////////////////////////////////// // イテレータ ///////////////////////////////////////////////////////////////// private: mutable std::vector iterator_Objects; mutable int iterator_CurrentNext; mutable bool isIteratorReady; public: void Iterator_Init() const { iterator_Objects.clear(); iterator_CurrentNext = 0; for( int i=0; iGetChainNext(); } } } isIteratorReady = true; } void Iterator_Reset() const { if( !isIteratorReady ) { Jenga::Throw( "イテレータの準備ができていない" ); } iterator_CurrentNext = 0; } bool Iterator_HasNext() const { return ( iterator_CurrentNext < (int)iterator_Objects.size() ); } T *Iterator_GetNext() const { return iterator_Objects[iterator_CurrentNext++]; } int Iterator_GetMaxCount() const { return (int)iterator_Objects.size(); } // XMLシリアライズ用 private: friend class boost::serialization::access; BOOST_SERIALIZATION_SPLIT_MEMBER(); template void load(Archive& ar, const unsigned int version) { std::vector objects; ar & BOOST_SERIALIZATION_NVP( objects ); // 読み込み後の処理 Clear(); BOOST_FOREACH( T *object, objects ) { Put( object ); } Iterator_Init(); } template void save(Archive& ar, const unsigned int version) const { // 保存準備 std::vector objects; objects.clear(); Iterator_Reset(); while( Iterator_HasNext() ) { objects.push_back( Iterator_GetNext() ); } ar & BOOST_SERIALIZATION_NVP( objects ); } }; template class ObjectInHashmap { T *pNextObject; public: ObjectInHashmap() : pNextObject( NULL ) { } ~ObjectInHashmap() { if( pNextObject ) { delete pNextObject; } } virtual const std::string &GetKeyName() const = 0; virtual bool IsDuplication( const T *value ) const { return ( GetKeyName() == value->GetName() ); } virtual bool IsDuplication( const std::string &keyName ) const { return ( GetKeyName() == keyName ); } T *GetChainNext() { return pNextObject; } const T *GetChainNext() const { return pNextObject; } void SetChainNext( T *pNextObject ) { this->pNextObject = pNextObject; } }; }}