00001 // $Id: list.h 751 2006-03-31 15:43:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 00099 /* 00100 */ 00101 00102 /*********************************************************************************************** 00103 00104 > class List : public CCObject 00105 00106 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 00107 Created: 13/4/1993 00108 Base Class: CObject 00109 Friends: ListItem 00110 Purpose: 00111 00112 The member functions are based on the MFC CObList class, though the 00113 implementation differs greatly. In particular no exceptions are thrown 00114 as all new items are allocated by someone else and some of the types 00115 have changed. An instance of the list class will be something like a list 00116 of fonts, and list of undo records etc. Remove functions don't actually 00117 de-allocate anything, they just remove items from the list. 00118 00119 Notes: Two ways of using a list item are provided: by pointer-to-item, and 00120 by item-index. The latter is very slow on average compared to the former 00121 because the list must be scanned each time to find a LISTPOS. Thus, use 00122 the pointer method where possible. 00123 00124 Errors: None. 00125 00126 ***********************************************************************************************/ 00127 00128 #ifndef INC_LIST 00129 #define INC_LIST 00130 00131 // Set up a local debugging flag so that the debugging of lists can be turned off in normal 00132 // debug builds and thus make things that use lists a lot faster! 00133 // If you want the list debugging in then please make a local writable copy, uncomment the 00134 // first #define and comment out the second. 00135 #undef _SLOW_LIST_DEBUG 00136 #ifdef _DEBUG 00137 // #define _SLOW_LIST_DEBUG // Slow debugging as well as normal 00138 #undef _SLOW_LIST_DEBUG // Omit slow (O(n)) debugging 00139 #endif 00140 00141 #include "ensure.h" 00142 #include "listitem.h" 00143 00144 typedef INT32 LISTPOS; // 32-bit unsigned integer used to return 00145 // the position of a ListItem in a List 00146 00147 // LISTPOS values of ZERO or GREATER are valid 00148 // LISTPOS values less than ZERO are invalid - Below is a list of LISTPOS error flags 00149 00150 const LISTPOS NOT_IN_LIST = -1; // Constant used to flag when a ListItem 00151 // is not found in a list 00152 const LISTPOS EMPTY_LIST = -2; // Constant used to flag when a List is 00153 // empty 00154 const LISTPOS INVALID_LISTPOS = -3; // Constant used to flag when a LISTPOS 00155 // is does not exist in list 00156 const LISTPOS INVALID_NEWITEM = -4; // Constant used to flag when new item to 00157 // be added to list is NULL 00158 00159 class CCAPI List : public CCObject 00160 { 00161 CC_DECLARE_DYNAMIC( List ) 00162 00163 private: 00164 ListItem *HeadItem; // pointer to head of list 00165 ListItem *TailItem; // pointer to tail of list 00166 UINT32 ItemCount; // number of items in list 00167 00168 public: 00169 List(); // List constructor 00170 virtual ~List(); // List destructor 00171 00172 virtual ListItem *RemoveHead(); 00173 virtual ListItem *RemoveTail(); 00174 virtual void DeleteAll(); 00175 00176 virtual void AddHead( ListItem* ); 00177 virtual void AddTail( ListItem* ); 00178 00179 ListItem *GetHead( ) const; 00180 LISTPOS GetHeadPosition() const; 00181 00182 ListItem *GetTail( ) const; 00183 LISTPOS GetTailPosition() const; 00184 00185 inline ListItem *GetNext( const ListItem* ) const; 00186 inline ListItem *GetPrev( const ListItem* ) const; 00187 00188 ListItem *FindItem( LISTPOS ) const; 00189 LISTPOS FindPosition(ListItem *) const; 00190 00191 virtual ListItem *RemoveItem( ListItem* ); 00192 00193 virtual LISTPOS InsertBefore(LISTPOS here, ListItem* item); 00194 virtual ListItem *InsertBefore(ListItem* here, ListItem* item); 00195 00196 virtual LISTPOS InsertAfter(LISTPOS here, ListItem* item); 00197 virtual ListItem *InsertAfter(ListItem* here, ListItem* item); 00198 00199 UINT32 GetCount() const; 00200 00201 BOOL IsEmpty() const; 00202 00203 // Creates a list of in-order pointers to each item in this list 00204 BOOL CreateIndex(List* IndexedList); 00205 00206 #ifdef _DEBUG // only required in DEBUG version 00207 public: 00208 void AssertValid() const; 00209 00210 private: 00211 ListItem *LastItemRemoved; // Used to check for stupidity 00212 // when deleteing items in a list 00213 // See GetNext/GetPrev 00214 00215 public: 00216 static INT32 ListDebugLevel; 00217 00218 #endif 00219 }; 00220 00221 /******************************************************************************************** 00222 00223 > class ListItemIdx: public ListItem 00224 00225 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00226 Created: 28/9/95 00227 Purpose: A ListItem that points to another ListItem. Used to created list indexes 00228 SeeAlso: List::CreateIndex 00229 00230 ********************************************************************************************/ 00231 00232 class ListItemIdx: public ListItem 00233 { 00234 public: 00235 ListItem* pItem; 00236 }; 00237 00238 /******************************************************************************************** 00239 00240 > class ListListItem: public ListItem 00241 00242 Author: Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com> 00243 Created: 3/10/95 00244 Purpose: A ListItem with a 'list' in it. Useful for lists of lists. 00245 The destructor deletes all items in its List. 00246 SeeAlso: ListItem 00247 00248 ********************************************************************************************/ 00249 00250 class ListListItem: public ListItem 00251 { 00252 public: 00253 virtual ~ListListItem() { list.DeleteAll(); }; 00254 List list; // A list 00255 }; 00256 00257 /********************************************************************************************** 00258 00259 > inline ListItem *List::GetNext( const ListItem* ) const 00260 00261 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 00262 Created: 14/4/93 00263 Inputs: pointer to ListItem 00264 Outputs: None 00265 Returns: ListItem if not empty 00266 NULL if list empty or if ListItem not found or end of list or input pointer 00267 is NULL 00268 Purpose: 00269 00270 To allow access to the next ListItem in the list after the one that has been 00271 passed in as input. 00272 00273 Errors: In the debug build, if SLOW_LIST_DEBUG is enabled (see list.h), this 00274 will check that the item is valid (is in the list etc), and generate 00275 ENSURE failures if not. 00276 In all debug builds, we will still check that the list is non-empty and 00277 that the passed ListItem is non-NULL. 00278 In debug, a check is also made that you are not trying to GetNext on the 00279 last item you removed from the list, as this is a common mistake to make 00280 00281 **********************************************************************************************/ 00282 /* 00283 Technical notes: 00284 00285 In debug builds the input ListItem is validated and its existence in the List is also checked. 00286 In release build it is assume that the input parameter will be ok and that it is in the list. 00287 00288 **********************************************************************************************/ 00289 00290 inline ListItem *List::GetNext( const ListItem* here ) const 00291 { 00292 #ifdef _DEBUG 00293 CC_ASSERT_VALID(this); 00294 00295 ENSURE(!this->IsEmpty() && here != NULL, 00296 "List::GetNext(here) - The list is empty, or 'here' is NULL"); 00297 00298 ENSURE(here != LastItemRemoved, 00299 "List::GetNext - Serious mistake! The item has just been removed from the list!!"); 00300 00301 if (ListDebugLevel > 1) 00302 { 00303 ListItem *listIter; // list iterator 00304 00305 listIter = HeadItem; 00306 00307 while (listIter != here && listIter != NULL) // iterate until input ListItem found 00308 listIter = listIter->Next; 00309 00310 ENSURE(listIter != NULL, "List:GetNext(here) - 'here' isn't in the list!"); 00311 } 00312 #endif 00313 00314 return here->Next; 00315 } 00316 00317 00318 00319 /********************************************************************************************** 00320 00321 > inline ListItem *List::GetPrev( const ListItem* here ) const 00322 00323 Author: Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> 00324 Created: 14/4/93 00325 Inputs: pointer to a ListItem 00326 Outputs: None 00327 Returns: ListItem if found 00328 NULL if list empty or ListItem not found or beginning of list or input pointer 00329 is NULL. 00330 Purpose: 00331 00332 To allow access to the previous ListItem in the list before the one that has been 00333 passed in as input. 00334 00335 Errors: In the debug build, if SLOW_LIST_DEBUG is enabled (see list.h), this 00336 will check that the item is valid (is in the list etc), and generate 00337 ENSURE failures if not. 00338 In all debug builds, we will still check that the list is non-empty and 00339 that the passed ListItem is non-NULL. 00340 In debug, a check is also made that you are not trying to GetNext on the 00341 last item you removed from the list, as this is a common mistake to make 00342 00343 **********************************************************************************************/ 00344 00345 inline ListItem *List::GetPrev( const ListItem* here ) const 00346 { 00347 #ifdef _DEBUG 00348 CC_ASSERT_VALID(this); 00349 00350 ENSURE(!this->IsEmpty() && here != NULL, 00351 "List::GetNext(here) - The list is empty, or 'here' is NULL"); 00352 00353 ENSURE(here != LastItemRemoved, 00354 "List::GetPrev - Serious mistake! The item has just been removed from the list!!"); 00355 00356 if (ListDebugLevel > 1) 00357 { 00358 ListItem *listIter; // list iterator 00359 00360 listIter = HeadItem; 00361 00362 while (listIter != here && listIter != NULL) // iterate until input ListItem found 00363 listIter = listIter->Next; 00364 00365 ENSURE(listIter != NULL, "List:GetPrev(here) - 'here' isn't in the list!"); 00366 } 00367 00368 #endif 00369 00370 return(here->Previous); 00371 } 00372 00373 00374 00375 00376 #endif