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

📄 olistc.h

📁 linux下的E_MAIL客户端源码
💻 H
字号:
/* * $Id: OListC.h,v 1.1.1.1 2000/04/25 13:49:01 fnevgeny Exp $ * * Copyright (c) 1992 HaL Computer Systems, Inc.  All rights reserved. *  *          HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. *                  1315 Dell Avenue *                  Campbell, CA  95008 * * Author: Greg Hilton * Contributors: Tom Lang, Frank Bieser, and others * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * http://www.gnu.org/copyleft/gpl.html * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */#ifndef	_OListC_h_#define	_OListC_h_#include "Base.h"#include <generic.h>/* * OListC.h -- header file for class OListC * *   This type of list store the members themselves *   PListC stores only pointers to the members */#define  DEFINE_OListC_Class(CLASS,TYPE) \ \class CLASS { \ \protected: \ \   TYPE		*_list; \   unsigned	_count; \   unsigned	_space; \   char		allow_duplicates; \   char		sorted; \   char		adjustGrowth; \   char		autoShrink; \   void		grow(unsigned size=0); \   void		shrink(); \ \public: \ \   unsigned		GROWTH_AMOUNT; \   const int		NULL_INDEX; \   const unsigned	MAX_GROWTH; \ \   inline CLASS() : GROWTH_AMOUNT(4), NULL_INDEX(-1), MAX_GROWTH(32768) { \      _list = NULL; \      _count = _space = 0; \      allow_duplicates = sorted = FALSE; \      adjustGrowth = TRUE; \      autoShrink = TRUE; \   } \   inline CLASS(unsigned ga) : GROWTH_AMOUNT(ga), NULL_INDEX(-1), MAX_GROWTH(ga) { \      _list = NULL; \      _count = _space = 0; \      allow_duplicates = sorted = FALSE; \      adjustGrowth = FALSE; \      autoShrink = TRUE; \   } \   inline CLASS(const CLASS& l) : GROWTH_AMOUNT(4), NULL_INDEX(-1), MAX_GROWTH(32768) { \      _list = NULL; \      _count = _space = 0; \      allow_duplicates = sorted = FALSE; \      adjustGrowth = TRUE; \      autoShrink = TRUE; \      *this = l; \   } \   virtual inline ~CLASS()	{ if (_list) delete [] _list; } \ \/* Append another list to this one */ \   inline CLASS& operator+=(const CLASS& l) { \      if ( this != &l ) { \	 register int count = l.size(); \	 for (register int i=0; i<count; i++) { \	    TYPE *item = l[i]; \	    add(*item); \	 } \      } \      return (*this); \   } \ \/* Copy another list to this one */ \   inline CLASS& operator=(const CLASS& l) { \      if ( this != &l ) { \	 removeAll(); \	 *this += l; \      } \      return (*this); \   } \ \/* Return the position of the specified object.	 Object must be in list */ \ \   int		indexOf(const TYPE& obj) const; \ \/* Return the sorted position of the specified object.	Object does not */ \/*    have to be in the list */ \ \   unsigned	orderOf(const TYPE& obj) const; \ \/* Return non-zero if the specified object is in the list */ \ \   inline int	includes(const TYPE& obj) const \      { return (indexOf(obj) != NULL_INDEX); } \ \/* Add the specified object to the list in the requested position */ \/*    The position is ignored if this list is sorted */ \ \   TYPE		*insert(const TYPE& obj, unsigned index); \   inline TYPE	*append(const TYPE& obj) { return(insert(obj, _count));} \   inline TYPE	*prepend(const TYPE& obj) { return(insert(obj, 0)); } \   inline TYPE	*add(const TYPE& obj) { return append(obj); } \ \/* Remove the specified object or index from the list */ \ \   void		remove(unsigned index); \   void		remove(const TYPE& obj); \   inline void	removeAll()	{ _count = 0; if (autoShrink) shrink(); } \   inline void	removeLast()	{ if (_count>0) remove(_count-1); } \ \/* Return a pointer to the previous object in the list */ \ \   TYPE		*before(const TYPE& obj) const; \ \/* Functions to support sorting */ \ \   static int	compare(const void*, const void*); \   void		sort(); \   void		sort(int (*)(const void*, const void*)); \   inline void	SetSorted(char val) { \      if ( sorted != val ) { \	 sorted = val; \	 if ( sorted ) sort(); \      } \   } \ \   inline unsigned	size() const	{ return (_count); } \   inline unsigned	capacity() const{ return (_space); } \   inline TYPE		*start() const	{ return (_list); } \   inline void		AllowDuplicates(char val) { allow_duplicates = val; } \   inline void		AutoShrink(char val) { \      autoShrink = val; \      if ( autoShrink ) shrink(); \   } \   inline void		SetCapacity(unsigned count) { \      grow(count*sizeof(TYPE)); \   } \ \   inline TYPE	*operator[](unsigned i) const { \      TYPE	*tp = NULL; \      if (i < _count) \	 tp = &_list[i]; \      else \	 cerr << "OListC[" << i << "]: reference out of bounds." \	      << " Valid range is 0:" << _count-1 NL; \      return tp; \   } \\   inline TYPE		*First() const { \      TYPE	*tp = NULL; \      if ( _count > 0 ) tp = &_list[0]; \      return tp; \   } \\   inline TYPE		*Last() const { \      TYPE	*tp = NULL; \      if ( _count > 0 ) tp = &_list[_count-1]; \      return tp; \   } \\   inline ostream&	printOn(ostream& strm=cout) const { \      for (int i=0; i<_count; i++) { \	 strm << _list[i] NL; \      } \      return strm; \   } \}; \ \/* PRINTING */ \ \inline ostream& \operator<<(ostream& strm, const CLASS& c) \{ \   return c.printOn(strm); \}//***************************************************************************//***************************************************************************#define  DEFINE_OListC_Methods(CLASS,TYPE) \ \/*-------------------------------------------------------------*/ \ \void \CLASS::grow(unsigned newSize) \{ \/* Increase space */ \ \   if ( newSize == 0 ) { \      _space += GROWTH_AMOUNT; \      if ( adjustGrowth && GROWTH_AMOUNT < MAX_GROWTH ) { \	 GROWTH_AMOUNT *= 2; \         if ( GROWTH_AMOUNT > MAX_GROWTH ) GROWTH_AMOUNT = MAX_GROWTH; \      } \   } \   else if ( newSize == _space ) { \      return; \   } \   else if ( newSize < _space ) { \      if ( !autoShrink ) return; \      _space = newSize; \      if ( newSize < _count ) _count = newSize; /* Only copy this many */ \   } \   else { \      _space = newSize; \   } \ \/* Allocate memory for new list */ \   TYPE	*old_list = _list; \   _list = new TYPE[_space]; \   if ( !_list ) { \      cerr << "Could not allocate memory for OListC of size: " << _space NL; \      exit(1); \   } \ \/* Copy list to new memory */ \   for (register int i=0; i<_count; i++) { \      _list[i] = old_list[i]; /* Copying objects here */ \   } \ \/* Free up old memory */ \   if ( old_list ) delete [] old_list; \} \ \/*-------------------------------------------------------------*/ \ \void \CLASS::shrink() \{ \   if ( !autoShrink ) return; \ \/* Decrease space if necessary */ \ \   int  needed = _count * sizeof(TYPE); \   if ( needed > (_space>>1) ) return; \ \/* Start from scratch and get just as much space as necessary */ \ \   if ( adjustGrowth ) GROWTH_AMOUNT = 4; \   _space = GROWTH_AMOUNT; \   if ( adjustGrowth && GROWTH_AMOUNT < MAX_GROWTH ) { \      GROWTH_AMOUNT *= 2; \      if ( GROWTH_AMOUNT > MAX_GROWTH ) GROWTH_AMOUNT = MAX_GROWTH; \   } \ \   while ( _space < needed ) { \      _space += GROWTH_AMOUNT; \      if ( adjustGrowth && GROWTH_AMOUNT < MAX_GROWTH ) { \	 GROWTH_AMOUNT *= 2; \	 if ( GROWTH_AMOUNT > MAX_GROWTH ) GROWTH_AMOUNT = MAX_GROWTH; \      } \   } \ \/* Allocate memory for new list */ \   TYPE	*old_list = _list; \   _list = new TYPE[_space]; \ \/* Copy list to new memory */ \   for (register int i=0; i<_count; i++) { \      _list[i] = old_list[i]; /* Copying objects here */ \   } \ \/* Free up old memory */ \   if ( old_list ) delete [] old_list; \} \ \/*-------------------------------------------------------------*/ \ \int \CLASS::indexOf(const TYPE& obj) const \{ \/* Use the orderOf call if the list is sorted.  This should increase speed */ \/* for very large lists (djl) */ \\   if (sorted) { \     int i = orderOf(obj); \     if (i == _count) return (NULL_INDEX); \     if (_list[i] == obj) return (i); \     else return (NULL_INDEX); \   } \ \/* Loop through the list until the entry is found */ \/* Compare actual objects */ \ \   for (register int i=0; (i<_count && (_list[i] != obj)); i++); \ \   if (i == _count) { \      return (NULL_INDEX); \   } \ \   return (i); \} \ \/*-------------------------------------------------------------*/ \ \TYPE* \CLASS::insert(const TYPE& obj, unsigned i) \{ \/* If this list is sorted, ignore the given index and compute the real one */ \   if ( sorted ) i = orderOf(obj); \ \/* Otherwise, see if index is valid */ \   if (i > _count) return (NULL); \ \/* Don't allow same address in list twice */ \   if ( !allow_duplicates && includes(obj) ) return (NULL); \ \/* See if there is enough space for another entry */ \ \   if ( _count >= _space ) grow(); \ \/* Insert entry in position i */ \/* Make a space for the new entry by moving all others back */ \ \   register int	j; \   for (j=_count; j>i; j--) { \      _list[j] = _list[j-1]; /* Copying objects here */ \   } \ \   _count++; \   TYPE	*tp = (TYPE *)&obj; \/* Copy the object to the list object */ \   _list[i] = *tp; \ \   return(&_list[i]); \} \ \/*-------------------------------------------------------------*/ \ \void \CLASS::remove(unsigned index) \{ \   if (index < _count) { \ \      /* Move entries forward in list and overwrite this one */ \      for (register int i=index+1; i<_count; i++) { \	 _list[i-1] = _list[i]; /* Copying objects here */ \      } \      _count--; \      if ( autoShrink ) shrink(); \   } \} \ \/*-------------------------------------------------------------*/ \ \void \CLASS::remove(const TYPE& obj) \{ \/* Look up this entry */ \ \   register unsigned i = indexOf(obj); \ \   if ( i != NULL_INDEX ) remove(i); \} \ \/*-------------------------------------------------------------*/ \/* Return a pointer to the list entry just before this one */ \ \TYPE* \CLASS::before(const TYPE& obj) const \{ \/* Look up this entry */ \ \   register int i = indexOf(obj); \ \   if ( i == NULL_INDEX || i == 0 ) return (NULL); \   return(&_list[i-1]); \} \ \/*-------------------------------------------------------------*/ \ \unsigned \CLASS::orderOf(const TYPE& obj) const \{ \/* \ *  This algorithm is a simple binary search \ *  If the object is in the list, the index of the object is returned. \ *  If the object is not in the list, the index where the object would fit \ *     iN THE SOrting order is returned.  \ */ \ \/* Check special cases first */ \   if ( _count == 0 || obj < _list[0] ) return (0); \   if ( obj > _list[_count-1] ) return (_count); \ \   int low = 0; \   int high = _count - 1; \   int mid = 0; \ \   while ( low <= high ) { \ \      mid = (low + high) / 2; \      /*int comp = obj.compare(_list[mid]); */ \      int comp = (obj < _list[mid]) ? -1 : ((obj > _list[mid]) ? 1 : 0); \ \      if ( comp > 0 )		low = mid + 1; \      else if (comp == 0)	return (mid); \      else 			high = mid - 1; \   } \ \/* \ * If the last comparison said the value was greater than the mid, \ *    then we want to return an index 1 greater than the mid because \ *    the entry should get inserted after the mid. \ */ \ \   if (low > mid) mid++; \ \   return (mid); \ \} /* End CLASS::orderOf */ \ \/*-------------------------------------------------------------*/ \ \int \CLASS::compare(const void *a, const void *b) \{ \   TYPE *ta = (TYPE *)a; \   TYPE *tb = (TYPE *)b; \ \   /* return ta->compare(*tb); */ \   return (*ta < *tb) ? -1 : ((*ta > *tb) ? 1 : 0); \} \ \/*-------------------------------------------------------------*/ \ \void \CLASS::sort() \{ \   qsort((void *)_list, (size_t)_count, (size_t)sizeof(TYPE), \       	 (int (*)(const void*, const void*))compare); \} \ \/*-------------------------------------------------------------*/ \ \void \CLASS::sort(int (*compar)(const void*, const void*)) \{ \   if ( !compar ) return; \   qsort((void *)_list, (size_t)_count, (size_t)sizeof(TYPE), compar); \}#endif // _OListC_h_

⌨️ 快捷键说明

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