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

📄 wxstlac.h

📁 wxGTK 是 wxWidgets 的 linux GTK+ (>2.2.3)版本。wxWidgets 是一个跨平台的 GUI 框架
💻 H
字号:
/////////////////////////////////////////////////////////////////////////////// Name:        No names yet.// Purpose:     Contrib. demo// Author:      Aleksandras Gluchovas// Modified by:// Created:     27/09/98// RCS-ID:      $Id: wxstlac.h,v 1.5 2005/06/02 09:44:45 ABX Exp $// Copyright:   (c) Aleskandars Gluchovas// Licence:     wxWindows licence/////////////////////////////////////////////////////////////////////////////#ifndef __WXSTLAC_G__#define __WXSTLAC_G__#ifdef new#undef new#endif#include <stddef.h>#if !defined(__WXMAC__) || defined(__DARWIN__)#  include <sys/types.h>#endif#include <memory.h>#include <limits.h>/* #include <new.h> */// the below macro used internally (see actual interface after this macro)// arguments:////      ARG_IS_UNIQUE//      ASSOC_CONT_CLASS_NAME////      ARG_VALUE_TYPE//      ARG_KEY_TYPE//      ARG_ACTUAL_VALUE_TYPE////      _KEY_NAME//      _VALUE_NAME////      _X_KEY_NAME//      _X_VALUE_NAME////      _INSERT_METHOD_DEFINITION#define __DEFINE_ASOC_CLASS( ARG_IS_UNIQUE, \FUNCTOR,\ASSOC_CONT_CLASS_NAME, \ARG_VALUE_TYPE, \ARG_KEY_TYPE, \ARG_ACTUAL_VALUE_TYPE, \_KEY_NAME, \_VALUE_NAME, \_X_KEY_NAME, \_X_VALUE_NAME, \_INSERT_METHOD_DEFINITION \) class \ASSOC_CONT_CLASS_NAME\{\protected:\\public:\    typedef ARG_VALUE_TYPE        value_type;\    typedef ARG_KEY_TYPE          key_type;\    typedef ARG_ACTUAL_VALUE_TYPE actual_value_type;\\	typedef value_type*			  pointer;\	typedef value_type&			  reference;\\	typedef const value_type&	  const_reference;\\	typedef FUNCTOR				  key_compare;\	typedef key_compare           Compare;\\protected:\\	struct tree_node \	{\		tree_node*  m_pParent;\		tree_node*  mpLeft;\		tree_node*  mpRight;\\		value_type  mData;\	};\\public:\	typedef tree_node* node_ref_type;\protected:\\	node_ref_type   mpRoot;\	node_ref_type   mpLeftMost;\	node_ref_type   mpRightMost;\\	node_ref_type   mpFreeListHead;\	int             mKeyIsUnique;\\	key_compare     mCmpFunctorObj;\\public:\\	static inline node_ref_type next( node_ref_type pNode )\	{\		if ( pNode->mpRight ) \		{\			pNode = pNode->mpRight;\\			while ( pNode->mpLeft ) pNode = pNode->mpLeft;\\			return pNode;\		}\		else\		if ( pNode->m_pParent )\		{\			if ( pNode == pNode->m_pParent->mpLeft )\\				return pNode->m_pParent;\\			pNode = pNode->m_pParent;\\			node_ref_type prevNode = pNode;\			pNode = pNode->m_pParent;\\			while(pNode)\			{\				if ( pNode->mpRight &&\					 pNode->mpRight != prevNode\				   ) return pNode;\\				prevNode = pNode;\				pNode= pNode->m_pParent;\			}\\			return 0;\		}\		else\			return 0;\	}\\	static inline node_ref_type prev( node_ref_type pNode )\	{\		if ( pNode->mpLeft ) \		{\			pNode = pNode->mpLeft;\\			while ( pNode->mpRight ) pNode = pNode->mpRight;\\			return pNode;\		}\		else\		if ( pNode->m_pParent )\		{\			if ( pNode == pNode->m_pParent->mpRight )\				return pNode->m_pParent;\\			pNode = pNode->m_pParent;\\			node_ref_type prevNode = pNode;\			pNode = pNode->m_pParent;\\			while(pNode)\			{\				if ( pNode->mpLeft &&\					 pNode->mpLeft != prevNode\				   ) return pNode;\\				prevNode = pNode;\				pNode= pNode->m_pParent;\			}\\			return 0;\		}\		else \			return 0;\	}\\protected:\\	inline int are_equel( const key_type& x, const key_type& y )\	{\		return ( !mCmpFunctorObj(x,y) && !mCmpFunctorObj(y,x) );\	}\\	inline int is_less( const key_type& x, const key_type& y )\	{\		return mCmpFunctorObj(x,y);\	}\\	static inline const actual_value_type& value( node_ref_type pNode )\	{\		return pNode->_VALUE_NAME;\	}\\	static inline const key_type& key( node_ref_type pNode )\	{\		return pNode->_KEY_NAME;\	}\\	inline node_ref_type AllocNode() \	{ \		if ( mpFreeListHead ) \		{\			node_ref_type pFreeNode = mpFreeListHead;\			mpFreeListHead = mpFreeListHead->mpLeft;\\			return pFreeNode;\		}\		else\		{\			char* pHeapBlock = new char[sizeof(tree_node)];\\			return (node_ref_type)pHeapBlock;\		}\	}\\	inline void DestroyFreeList()\	{\		while ( mpFreeListHead )\		{\			node_ref_type tmp = mpFreeListHead;\			mpFreeListHead = mpFreeListHead->mpLeft;\\			delete [](char*)tmp;\		}\	}\\	inline void RecycleNode( node_ref_type pNode ) \	{\		pNode->mpLeft = mpFreeListHead;\		mpFreeListHead = pNode;\	}\\	inline node_ref_type do_insert(const value_type& x = value_type() )\	{\		node_ref_type pNewNode = AllocNode();\\		pNewNode->m_pParent = \			pNewNode->mpLeft =\				pNewNode->mpRight = 0;\\	    node_ref_type pCurrent = mpRoot;\		node_ref_type pParent = 0;\    \		while (pCurrent) \		{\			if ( mKeyIsUnique && are_equel( _X_KEY_NAME, value(pCurrent) ) )\			{\				RecycleNode(pNewNode);\				return 0;\			}\\			pParent = pCurrent;\\			pCurrent = is_less( _X_KEY_NAME, value(pCurrent) ) \				? pCurrent->mpLeft \				: pCurrent->mpRight;\		}\    \		pNewNode->m_pParent = pParent;\\	    if(pParent)\\			if( is_less(_X_KEY_NAME, value(pParent) ) )\            \				pParent->mpLeft = pNewNode;\			else\				pParent->mpRight = pNewNode;\			else\				mpRoot = pNewNode;\\		new ( &pNewNode->_KEY_NAME   ) key_type(_X_KEY_NAME);\		new ( &pNewNode->_VALUE_NAME ) actual_value_type(_X_VALUE_NAME);\\		if ( prev(pNewNode) == 0 ) mpLeftMost = pNewNode;\		if ( next(pNewNode) == 0 ) mpRightMost = pNewNode;\\		return pNewNode;\	}\\	friend class iterator;\\public:\\	class iterator;\	class const_iterator;\\	class iterator \	{\	public:\		node_ref_type mpNode;\		friend class CONT_CLASS_NAME;\		friend class const_iterator;\		friend class const_reverse_iterator;\\		inline iterator( node_ref_type pNode )\		{\			mpNode = pNode;\		}\	\	public:\		inline iterator() {}\		inline int operator==( const iterator& rhs ) const { return (mpNode == rhs.mpNode); }\		inline int operator!=( const iterator& rhs ) const { return (mpNode != rhs.mpNode); }\\		inline iterator( const iterator& other )\		{\			mpNode = other.mpNode;\		}\\		inline const iterator& operator=( const iterator& other )\		{\			mpNode = other.mpNode;\			return *this;\		}\\		inline const iterator& operator--() \		{\			mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\			return *this;\		}\\		inline iterator operator--(int)\		{\			iterator tmp = *this;\			mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\			return tmp;\		}\\		inline const iterator& operator++() \		{\			mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\			return *this;\		}\\		inline iterator operator++(int)\		{\			iterator tmp = *this;\			mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\			return tmp;\		}\\		inline reference operator*() const { return mpNode->mData; }\	};\\\	class const_iterator \	{\	public:\		node_ref_type mpNode;\		friend class CONT_CLASS_NAME;\		friend class const_reverse_iterator;\\		inline const_iterator( node_ref_type pNode )\		{\			mpNode = pNode;\		}\	\	public:\		inline const_iterator() {}\\		inline int operator==( const const_iterator& rhs ) const { return (mpNode == rhs.mpNode); }\		inline int operator!=( const const_iterator& rhs ) const { return (mpNode != rhs.mpNode); }\\		inline const_iterator( const iterator& other )\		{\			mpNode = other.mpNode;\		}\\		inline const_iterator( const const_iterator& other )\		{\			mpNode = other.mpNode;\		}\\		inline const const_iterator& operator=( const const_iterator& other )\		{\			mpNode = other.mpNode;\			return *this;\		}\\		inline const const_iterator& operator--() \		{\			mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\			return *this;\		}\\		inline const_iterator operator--(int)\		{\			const_iterator tmp = *this;\			mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\			return tmp;\		}\\		inline const const_iterator& operator++() \		{\			mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\			return *this;\		}\\		inline const_iterator operator++(int)\		{\			const_iterator tmp = *this;\			mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\			return tmp;\		}\\		inline const_reference operator*() const { return mpNode->mData; }\	};\\public:\\	inline ASSOC_CONT_CLASS_NAME( key_compare cmpFunctorObj = key_compare(),\								  int keyIsUnique = ARG_IS_UNIQUE )\			: mpFreeListHead( 0 ),\			  mKeyIsUnique( keyIsUnique ),\			  mCmpFunctorObj( cmpFunctorObj )\	{\		mpLeftMost = 0;\		mpRightMost = 0;\		mpRoot = 0;\	}\\	inline ~ASSOC_CONT_CLASS_NAME() \	{ \		erase( begin(), end() ); \\		DestroyFreeList();\	}\\	inline iterator begin() { return mpLeftMost; }\	inline iterator end()   { return 0; }\\	inline const_iterator begin() const { return mpLeftMost; }\	inline const_iterator end()   const { return 0; }\\	inline iterator lower_bound( const key_type& x )\	{ \		node_ref_type pCurrent = mpRoot;\    \		while( pCurrent )\		{\			node_ref_type pParent = pCurrent;\\			if( are_equel( x, key(pCurrent) ) )\				\				return (pCurrent);\			else\				pCurrent = is_less( x, key(pCurrent) ) \					? pCurrent->mpLeft \					: pCurrent->mpRight;\\			if ( !pCurrent ) return (pParent);\		}\\		return begin();\	}\\	inline const_iterator lower_bound( const key_type& x ) const\\		{ return const_iterator( lower_bound(x).mpNode ); }\\	inline iterator upper_bound( const key_type& x )\	{\		node_ref_type pCurrent = mpRoot;\    \		while( pCurrent )\		{\			node_ref_type pParent = pCurrent;\\			if( are_equel( x, key(pCurrent) ) )\				\				return (pCurrent);\			else\				pCurrent = is_less( x, key(pCurrent) ) \					? pCurrent->mpLeft \					: pCurrent->mpRight;\\			if ( !pCurrent ) return next(pParent);\		}\\		return end();\	}\\	inline const_iterator upper_bound( const key_type& x ) const\\		{ return const_iterator( upper_bound(x).mpNode ); }\\	inline iterator find( const key_type& x )\	{\		node_ref_type pCurrent = mpRoot;\    \		while( pCurrent )\		{\			if( are_equel( x, key(pCurrent) ) )\				\				return (pCurrent);\			else\				pCurrent = is_less( x, key(pCurrent) ) \					? pCurrent->mpLeft \					: pCurrent->mpRight;\		}\\		return end();\	}\\	inline const_iterator find( const key_type& x ) const\\		{ return const_iterator( find(x).mpNode ); }\\	inline void erase(iterator first, iterator last)\	{\		if ( first.mpNode == 0 ) return;\\		while( first != last ) \		{\			iterator next = first;\			++next;\			erase( first );\			first = next;\		}\	}\\	inline void erase(iterator position)\	{\		if ( position.mpNode == 0 ) return;\\		node_ref_type pZ = position.mpNode;\		node_ref_type pX, pY;\\		if ( pZ == mpLeftMost ) mpLeftMost   = next(pZ);\		if ( pZ == mpRightMost ) mpRightMost = prev( pZ );\\        if ( !pZ->mpLeft || !pZ->mpRight )\	    \            pY = pZ;\        else \		{\            pY = pZ->mpRight;\	    \            while (pY->mpLeft) \				\				pY = pY->mpLeft;\        }\	    \        if ( pY->mpLeft)\	    \            pX = pY->mpLeft;\        else\            pX = pY->mpRight;\	    \        if ( pX ) pX->m_pParent = pY->m_pParent;\	    \        if (pY->m_pParent)\	    \            if (pY == pY->m_pParent->mpLeft )\	    \                pY->m_pParent->mpLeft = pX;\		    else\                pY->m_pParent->mpRight = pX;\        else\            mpRoot = pX;\	    \		node_ref_type toRemove = 0;\		\        if (pY != pZ) {\	    \            pY->mpLeft = pZ->mpLeft;\	    \            if (pY->mpLeft) pY->mpLeft->m_pParent = pY;\	    \            pY->mpRight = pZ->mpRight;\	    \            if ( pY->mpRight ) \				\				pY->mpRight->m_pParent = pY;\	    \            pY->m_pParent = pZ->m_pParent;\	    \            if (pZ->m_pParent)\	    \                if (pZ == pZ->m_pParent->mpLeft)\	    \                    pZ->m_pParent->mpLeft = pY;\                else\                    pZ->m_pParent->mpRight = pY;\            else\                mpRoot = pY;\	    \            toRemove = pZ;\        } \		else \            toRemove = pY;\	    \		value(toRemove).~actual_value_type();\		key(toRemove).~actual_value_type();\\		RecycleNode( toRemove );\	}\\	_INSERT_METHOD_DEFINITION\}// do not undefine ___WXSTL_COMMA, where associated containers are defined!// (it is used as workaround for constraints of C-Preprocessor's nested macros)#define ___WXSTL_COMMA ,#define __DEFINE_MAP(ARG_IS_UNIQUE, KEY_TYPE, VAL_TYPE, FUNCTOR ) \__DEFINE_ASOC_CLASS( ARG_IS_UNIQUE,\FUNCTOR,\__WXSTLMAP_##KEY_TYPE##VAL_TYPE##ARG_IS_UNIQUE, \struct key_value_pair   { KEY_TYPE first ; \                          VAL_TYPE second;\                          key_value_pair() {}\                          key_value_pair( const KEY_TYPE& key ___WXSTL_COMMA const VAL_TYPE& value ) \                            : first(key) ___WXSTL_COMMA second( value ) {} \                         } , \KEY_TYPE,\VAL_TYPE,\mData.first, mData.second, x.first, x.second, \struct insert_result_iterator\{\	iterator first;\	int      second;\};\inline insert_result_iterator insert( const value_type& x )\{\	insert_result_iterator result;\\	result.first = do_insert(x);\	result.second  = ( result.first == end() ) ? 0 : 1;\\	return result;\} )#define __DEFINE_SET(ARG_IS_UNIQUE, KEY_TYPE, FUNCTOR ) \__DEFINE_ASOC_CLASS( ARG_IS_UNIQUE,\FUNCTOR,\__WXSTLSET_##TYPE##ARG_IS_UNIQUE, \KEY_TYPE,\KEY_TYPE,\KEY_TYPE,\mData, mData, x, x, \struct insert_result_iterator\{\	iterator first;\	int      second;\};\inline insert_result_iterator insert( const value_type& x )\{\	insert_result_iterator result;\\	result.first = do_insert(x);\	result.second  = ( result.first == end() ) ? 0 : 1;\\	return result;\} )// helper macros to create functor objects for associative containers of the given type#define LESS_THEN_FUNCTOR(TYPE) struct \{ inline int operator()(const TYPE& x, const TYPE& y ) const { return x < y; } }#define GREATER_THEN_FUNCTOR(TYPE) struct \{ inline int operator()(const TYPE& x, const TYPE& y ) const { return x > y; } }// functor argument should be created using the two above macros// or passing own class with method "operator()(const TYPE&,cosnt TYPE&)" defined in it#define WXSTL_MAP( KEY_TYPE, VALUE_TYPE, FUNCTOR )      __DEFINE_MAP( 1 ,KEY_TYPE, VALUE_TYPE, FUNCTOR)#define WXSTL_MULTIMAP( KEY_TYPE, VALUE_TYPE, FUNCTOR ) __DEFINE_MAP( 0 ,KEY_TYPE, VALUE_TYPE, FUNCTOR)#define WXSTL_SET( KEY_TYPE, FUNCTOR )                  __DEFINE_SET( 1 ,KEY_TYPE, FUNCTOR )#define WXSTL_MULTISET( KEY_TYPE, FUNCTOR )             __DEFINE_SET( 0 ,KEY_TYPE, FUNCTOR )#endif

⌨️ 快捷键说明

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