⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gacatalogue.h

📁 遗传算法做的排课系统
💻 H
字号:

#ifndef __GA_CATALOGUE_H__
#define __GA_CATALOGUE_H__

#include <utility>
#include <hash_map>

#include "..\ExportImport.h"
#include "..\CallConvention.h"
#include "..\Threading\GaThreading.h"

using namespace stdext;
using namespace std;

namespace Common
{
	template <typename T>
	class GaCatalogue;

	// Entry of catalogue
	template <typename T>
	class GaCatalogueEntry
	{
	friend class GaCatalogue<T>;

	private:

		// Name of entry
		char* _name;

		// Length of name
		int _nameLength;

		// Pointer to the data
		T* _data;

	public:

		// Initialization of the entry
		GaCatalogueEntry(const char* name,
						T& data)
		{
			if( name )
			{
				_nameLength = (int)strlen( name );

				// copy name
				_name = new char[ _nameLength + 1 ];
				strcpy( _name, name );

				_data = &data;

				return;
			}

			_name = NULL;
			_nameLength = 0;
			_data = NULL;
		};

		// Frees aquired resources
		~GaCatalogueEntry()
		{
			if( _name )
				delete[] _name;

			if( _data )
				delete _data;
		};

		// Returns name of entry
		const char* GACALL GetName() const
		{
			return _name;
		};

		// Sets name of entry
		void GACALL SetName(const char* name)
		{
			if( name )
			{
				if( _name )
					delete[] _name;

				_nameLength = strlen( name );

				// copy name
				_name = new char[ _nameLength + 1 ];
				strcpy( _name, name );
			}
		};

		// Returns length of entry's name
		int GACALL GetNameLength() const
		{
			return _nameLength;
		};

		// Returns pointer to data
		T& GACALL GetData() const
		{
			return *_data;
		};

		// Sets pointer to data
		void GACALL SetData(T& data)
		{
			_data = &data;
		};

	};// END CLASS DEFINITION GaCatalogueEntry


	// Manages catalogues and their entries
	template <typename T>
	class GaCatalogue
	{
		DEFINE_SYNC_CLASS

	private:

		// String comparator
		struct GaStringComparator
		{

		public:
			// comapration
			bool GACALL operator()(const char* left, const char* right) const
			{
				return strcmp( left, right ) == -1;
			}

		};

		// comarator for catalogue's hash map
		class GaCataolgueHashMapComparator
		{
		public:

			// parameters for hash table
			enum
			{
				bucket_size = 4,
				min_buckets = 8
			};	

			// construct with default comparator
			GaCataolgueHashMapComparator() : _comparator() { }

			// construct with _Pred comparator
			GaCataolgueHashMapComparator(GaStringComparator pred) : _comparator( pred ) { }

			// Hash function
			size_t GACALL operator()(const char* key) const
			{
				if( key == NULL )
					return 0;

				size_t t = 0;
				while( *key )
					t += *( key++ );

				ldiv_t rem = ldiv((long)t, 127773);
				rem.rem = 16807 * rem.rem - 2836 * rem.quot;
				if (rem.rem < 0)
					rem.rem += 2147483647;

				return ((size_t)rem.rem);
			}

			// Comparation
			bool GACALL operator()(const char* value1, const char* value2) const
			{
				return _comparator( value1, value2 );
			}

		private:

			// String comparator
			GaStringComparator _comparator;
		};

		typedef hash_map<const char*, GaCatalogueEntry<T>*, GaCataolgueHashMapComparator> GaCataolgueHashMap;

		// Global instance of the catalogue
		DLL_EXPORT
		static GaCatalogue<T>* _instance;

		// Catalogue's entries
		GaCataolgueHashMap _entries;

	public:

		// Returns global instance of the catalogue
		static GaCatalogue<T>& GACALL Instance()
		{
			return *_instance;
		}

		// Makes global instance of catalogue
		static void GACALL MakeInstance()
		{
			if( !_instance )
				_instance = new GaCatalogue();
		}

		// Frees memory used by global instance of catalogue
		static void GACALL FreeInstance()
		{
			if( _instance )
				delete _instance;
		}

		// Initialization of the catalgoue
		GaCatalogue() { }

		// Frees aquired resources
		~GaCatalogue()
		{
			for( GaCataolgueHashMap::const_iterator it = _entries.begin(); it != _entries.end(); it++ )
				delete it->second;

			_entries.clear();
		}

		// Adds entry to catalogue
		bool GACALL Register(const char* name,
				T& data,
				bool replace = false)
		{
			// no name - error?
			if( !name )
				return false;

			LOCK_THIS_OBJECT( lock );

			// does it exist?
			GaCataolgueHashMap::const_iterator it = _entries.find( name );
			bool exists = it != _entries.end();
			if( exists && !replace )
				// exists and no replacing - error
				return false;

			// erease if entry exists and replace is enabled
			if( exists && replace )
			{
				delete it->second;			
				_entries.erase( name );
			}

			// make entry for data and insert to catalogue
			GaCatalogueEntry<T>* new_entry = new GaCatalogueEntry<T>( name, data );
			return _entries.insert( pair<const char*, GaCatalogueEntry<T>*>( name, new_entry ) ).second;
		}

		// Remove entry from the catalgoue
		bool GACALL Unregister(const char* name)
		{
			LOCK_THIS_OBJECT( lock );

			bool removed = false;

			// exists?
			GaCataolgueHashMap::const_iterator it = _entries.find( name );
			if( it != _entries.end() )
			{
				// remove
				delete it->second;
				removed = _entries.erase( name ) > 0;
			}

			return removed;
		}

		// Returns pointer to entry (lookup by name)
		GaCatalogueEntry<T>* GACALL GetEntry(const char* name) const
		{
			LOCK_THIS_OBJECT( lock );

			// find entry and return pointer to entry
			GaCataolgueHashMap::const_iterator it = _entries.find( name );
			return it == _entries.end() ? NULL : it->second;
		}

		// Returns pointer to entry's data (lookup by name)
		T* GACALL GetEntryData(const char* name) const
		{
			LOCK_THIS_OBJECT( lock );
			
			// find entry and return pointer to data
			GaCataolgueHashMap::const_iterator it = _entries.find( name );
			return it == _entries.end() ? NULL : &it->second->GetData();
		}

		// Returns pointer to entry's data (lookup by name)
		T* GACALL operator [](const char* name) const
		{
			return GetEntryData( name );
		}

		// Returns first N names in catalogue
		// Caller must allocate memory for array of pointers to strings.
		// This method allocates memory for names but caller is responsible for it.
		// It also returns a number of names for which is memory allocated.
		bool GACALL GetKeys(char** names,
			   int& number) const
		{
			LOCK_THIS_OBJECT( lock );

			// no buffer or too small?
			if( !names || number < (int)_entries.size() )
			{
				// returns error and number of entries 
				number = _entries.size();
				return false;
			}

			// fill buffer with names
			int i = 0;
			for( GaCataolgueHashMap::const_iterator it = _entries.begin(); it != _entries.end(); it++, i++ )
			{
				names[ i ] = new char[ it->second->GetNameLength() + 1 ];
				strcpy( names[ i ], it->second->GetName() );
			}

			number = i;

			return true;
		}

		// Returns number of entries in catalogue
		int GACALL GetCount() const
		{
			LOCK_THIS_OBJECT( lock );

			return _entries.size();
		}

		// Returns TRUE if entry with given name exists in catalogue
		bool GACALL IsExist(const char* name) const
		{
			LOCK_THIS_OBJECT( lock );

			return _entries.count( name ) > 0;
		}

	};// END CLASS DEFINITION GaCatalogue

	#ifdef DLL_EXPORTING

	// Global instance of the catalogue
	template <typename T>
	GaCatalogue<T>* GaCatalogue<T>::_instance = NULL;

	#endif

} // Common

#endif //__GA_CATALOGUE_H__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -