oflist.h

00001 /*
00002  *
00003  *  Copyright (C) 1997-2005, OFFIS
00004  *
00005  *  This software and supporting documentation were developed by
00006  *
00007  *    Kuratorium OFFIS e.V.
00008  *    Healthcare Information and Communication Systems
00009  *    Escherweg 2
00010  *    D-26121 Oldenburg, Germany
00011  *
00012  *  THIS SOFTWARE IS MADE AVAILABLE,  AS IS,  AND OFFIS MAKES NO  WARRANTY
00013  *  REGARDING  THE  SOFTWARE,  ITS  PERFORMANCE,  ITS  MERCHANTABILITY  OR
00014  *  FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES  OR
00015  *  ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY AND
00016  *  PERFORMANCE OF THE SOFTWARE IS WITH THE USER.
00017  *
00018  *  Module:  ofstd
00019  *
00020  *  Author:  Andreas Barth
00021  *
00022  *  Purpose:
00023  *          Defines a template list class with interfaces similar to the C++ Standard
00024  *
00025  *  Last Update:      $Author: meichel $
00026  *  Update Date:      $Date: 2005/12/08 16:05:58 $
00027  *  Source File:      $Source: /share/dicom/cvs-depot/dcmtk/ofstd/include/dcmtk/ofstd/oflist.h,v $
00028  *  CVS/RCS Revision: $Revision: 1.22 $
00029  *  Status:           $State: Exp $
00030  *
00031  *  CVS/RCS Log at end of file
00032  *
00033  */
00034 
00035 #ifndef OFLIST_H
00036 #define OFLIST_H
00037 
00038 // Usage (only non standard):
00039 //   OFListInsert(InputIterator_type, T_type, c, pos, first, last)
00040 //                      Inserts the elements of type T in
00041 //                      range [first, last) into list c,
00042 //   OFListRemoveIf(Predicate_Type, T_type, c, pred)
00043 //                      Erases all elements of type T in the list referred by
00044 //                      an iterator i where pred(*i) == true.
00045 //                      Predicate_Type is the function type of pred
00046 //
00047 // Additional Remarks:
00048 //   In some template functions one template parameter is another function.
00049 //   Some compilers  cannot determine automatically the type of template
00050 //   function parameters, so you must give  them a hint casting
00051 //   the parameter function to the correct type (e.g. NeXT gcc 2.5.8)
00052 
00053 #include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
00054 #include "dcmtk/ofstd/oftypes.h"
00055 #include "dcmtk/ofstd/ofcast.h"
00056 
00057 #ifndef HAVE_CLASS_TEMPLATE
00058 #error Your C++ compiler cannot handle class templates:
00059 #endif
00060 
00061 #if defined(HAVE_STL) || defined(HAVE_STL_LIST)
00062 // It is possible to use the standard template library list class since the
00063 // interface is nearly identical.
00064 // Important: If you want to use the standard template library (STL), no
00065 // variable within a namespace using a class of the STL shall have a name
00066 // of one class of the STL
00067 #include <list>
00068 
00069 #ifdef HAVE_STD_NAMESPACE
00070 #define OFList std::list
00071 #define OFListIterator(x) std::list< x >::iterator
00072 #define OFListConstIterator(x) std::list< x >::const_iterator
00073 #else
00074 #define OFList list
00075 #define OFListIterator(x) list< x >::iterator
00076 #define OFListConstIterator(x) list< x >::const_iterator
00077 #endif
00078 
00079 #define OFListInsert(InputIterator, T, c, pos, first, last) (c).insert((pos), (first), (last))
00080 #define OFListRemoveIf(Predicate, T, c, pred) (c).remove_if((pred))
00081 
00082 // workaround for "implicit typename" warning on gcc 3.x
00083 #if defined(HAVE_TYPENAME)
00084 #define OFLIST_TYPENAME typename
00085 #else
00086 #define OFLIST_TYPENAME
00087 #endif
00088 
00089 #else
00090 
00091 #define INCLUDE_CASSERT
00092 #define INCLUDE_CSTDDEF
00093 #include "dcmtk/ofstd/ofstdinc.h"
00094 
00095 #define OFLIST_TYPENAME
00096 
00097 
00098 // OFListLinkBase, OFListLink and OFListBase are classes for internal
00099 // use only and shall not be used.
00100 
00101 /* non-template double linked list. Base class fo OFListLink.
00102  * Implicitly used by OFList, should not be called by users.
00103  */
00104 struct OFListLinkBase
00105 {
00106     OFListLinkBase * next;
00107     OFListLinkBase * prev;
00108     OFBool dummy;
00109     OFListLinkBase(): next(NULL), prev(NULL), dummy(OFFalse) { }
00110     virtual ~OFListLinkBase() {}
00111 
00112   private:
00113     /* undefined */ OFListLinkBase(const OFListLinkBase&);
00114     /* undefined */ OFListLinkBase& operator=(const OFListLinkBase&);
00115 };
00116 
00117 
00118 /* non-template list. Base class fo OFList.
00119  * Implicitly used by OFList, should not be called by users.
00120  */
00121 class OFListBase
00122 {
00123 protected:
00124     OFListLinkBase * afterLast;
00125     size_t listSize;
00126     void base_recalcListSize();
00127 public:
00128     OFListBase();
00129     virtual ~OFListBase();
00130     OFListLinkBase * base_begin() const { return afterLast->next; }
00131     OFListLinkBase * base_end() const { return afterLast; }
00132     OFBool base_empty() const { return afterLast == afterLast->next; }
00133     size_t base_size() const { return listSize; }
00134     OFListLinkBase * base_insert(OFListLinkBase * pos, OFListLinkBase * newElem);
00135     OFListLinkBase * base_erase(OFListLinkBase * pos);
00136     void base_splice(OFListLinkBase * pos,
00137                 OFListLinkBase * begin, OFListLinkBase * end);
00138     void base_clear();
00139 
00140   private:
00141     /* undefined */ OFListBase(const OFListBase&);
00142     /* undefined */ OFListBase& operator=(const OFListBase&);
00143 };
00144 
00145 
00146 
00147 /* template class for double linked list entries.
00148  * Implicitly used by OFList, should not be called by users.
00149  */
00150 template <class T>
00151 struct OFListLink : public OFListLinkBase
00152 {
00153     T info;
00154     OFListLink(const T& i) : OFListLinkBase(), info(i)  { }
00155     virtual ~OFListLink() {}
00156   private:
00157     /* undefined */ OFListLink(const OFListLink<T>&);
00158     /* undefined */ OFListLink<T>& operator=(const OFListLink<T>&);
00159 };
00160 
00161 
00162 // Definition of OFList and OFIterator
00163 
00164 template <class T> class OFList;
00165 
00166 
00173 template <class T>
00174 class OFIterator
00175 {
00176     friend class OFList<T>;
00177 protected:
00178 
00180     OFListLinkBase * node;
00181 
00185     OFIterator(OFListLinkBase * x) : node(x) { }
00186 public:
00187 
00192     OFIterator() : node(NULL)  { }
00193 
00196     OFIterator(const OFIterator<T>& x) : node(x.node) { };
00197 
00200     OFIterator<T>& operator=(const OFIterator<T>& x)
00201     {
00202         node = x.node;
00203         return *this;
00204     }
00205 
00211     OFBool operator==(const OFIterator<T>& x) const { return node == x.node; }
00212 
00218     OFBool operator!=(const OFIterator<T>& x) const { return node != x.node; }
00219 
00224     T& operator*() const
00225     {
00226         assert(!node->dummy);
00227         return (OFstatic_cast(OFListLink<T> *,node))->info;
00228     }
00229 
00235     OFIterator<T>& operator++()
00236     {
00237         node = node->next;
00238         return *this;
00239     }
00240 
00247     OFIterator<T> operator++(int)
00248     {
00249         OFIterator<T> tmp(*this);
00250         node = node->next;
00251         return tmp;
00252     }
00253 
00259     OFIterator<T>& operator--()
00260     {
00261         node = node->prev;
00262         return *this;
00263     }
00264 
00271     OFIterator<T> operator--(int)
00272     {
00273         OFIterator<T> tmp(*this);
00274         node = node->prev;
00275         return tmp;
00276     }
00277 };
00278 
00279 
00283 template <class T>
00284 class OFList : private OFListBase
00285 {
00286 public:
00292     OFIterator<T> insert(OFIterator<T> position, const T& x)
00293     {
00294       return OFIterator<T>(OFListBase::base_insert(position.node, new OFListLink<T>(x)));
00295     }
00296 
00297 private:
00298 
00302     void copy(const OFList<T>& oldList)
00303     {
00304         OFIterator<T> vfirst(oldList.begin());
00305         OFIterator<T> vend(oldList.end());
00306         OFIterator<T> vpos(this->end());
00307         while (vfirst != vend)
00308         {
00309             insert(vpos, *vfirst);
00310             ++vfirst;
00311         }
00312     }
00313 
00317     void recalcListSize() { OFListBase::base_recalcListSize(); }
00318 
00319 public:
00320 
00323     OFList() : OFListBase() { }
00324 
00327     OFList(const OFList<T>& oldList):OFListBase()
00328     {
00329         copy(oldList);
00330     }
00331 
00336     OFIterator<T> begin() const { return OFIterator<T>(OFListBase::base_begin()); }
00337 
00342     OFIterator<T> end() const { return OFIterator<T>(OFListBase::base_end()); }
00343 
00347     OFBool empty() const { return OFListBase::base_empty(); }
00348 
00352     size_t size() const { return OFListBase::base_size(); }
00353 
00358     T& front() { return *begin(); }
00359 
00364     T& back() { return *(--end()); }
00365 
00369     void push_front(const T& x) { insert(begin(), OFconst_cast(T&, x)); }
00370     /* const cast away to keep some old compilers happy */
00371 
00376     void pop_front() { erase(begin()); }
00377 
00381     void push_back(const T& x) { insert(end(), OFconst_cast(T&, x)); }
00382     /* const cast away to keep some old compilers happy */
00383 
00388     void pop_back() { erase(--end()); }
00389 
00395     void insert(OFIterator<T> position, size_t n, const T& x)
00396     {
00397       while(n--) OFListBase::base_insert(position.node, new OFListLink<T>(x));
00398     }
00399 
00404     OFIterator<T> erase(OFIterator<T> position)
00405     {
00406       return OFIterator<T>(OFListBase::base_erase(position.node));
00407     }
00408 
00415     OFIterator<T> erase(OFIterator<T> position, OFIterator<T> last)
00416     {
00417       while (position != last) position = erase(position);
00418       return last;
00419     }
00420 
00424     void clear() { OFListBase::base_clear(); }
00425 
00431     void splice(OFIterator<T> position, OFList<T>& x)
00432     {
00433       splice(position, x, x.begin(), x.end());
00434     }
00435 
00441     void splice(OFIterator<T> position, OFList<T>& x, OFIterator<T> i)
00442     {
00443       OFIterator<T> change(i);
00444       ++i;
00445       splice(position, x, change, i);
00446     }
00447 
00455     void splice(OFIterator<T> position, OFList<T>& x,
00456                 OFIterator<T> first, OFIterator<T> last)
00457     {
00458       OFListBase::base_splice(position.node, first.node, last.node);
00459       x.recalcListSize();
00460     }
00461 
00466     void remove(const T& value)
00467     {
00468       OFIterator<T> first = begin();
00469       OFIterator<T> last = end();
00470       while(first != last)
00471       {
00472         if (*first == value) first = erase(first);
00473         else ++first;
00474       }
00475     }
00476 
00477 private:
00478 
00481     OFList<T>& operator=(const OFList<T>& arg);
00482 };
00483 
00484 
00485 #ifdef HAVE_FUNCTION_TEMPLATE
00486 
00487 #define OFListInsert(InputIterator, T, c, pos, first, last) OF_ListInsert((c), (pos), (first), (last))
00488 
00489 #define OFListRemoveIf(Predicate, T, c, pred) OF_ListRemoveIf((c), (pred))
00490 
00491 #elif defined(HAVE_STATIC_TEMPLATE_METHOD)
00492 
00493 #define OFListInsert(InputIterator, T, c, pos, first, last) OF_ListInsertClass<InputIterator, T>::OF_ListInsert((c), (pos), (first), (last))
00494 
00495 #define OFListRemoveIf(Predicate, T, c, pred) OF_ListRemoveIfClass<Predicate, T>::OF_ListRemoveIf((c), (pred))
00496 
00497 #else
00498 #error Your C++ Compiler is not capable of compiling this code
00499 #endif
00500 
00501 // Insert the elements in range [first, last) into list
00502 template <class InputIterator, class T>
00503 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
00504 class OF_ListInsertClass
00505 {
00506 public:
00507 static
00508 #endif
00509 void OF_ListInsert(OFList<T>& c, OFIterator<T> position,
00510                   InputIterator first, InputIterator last)
00511 {
00512     while(first != last)
00513     {
00514         c.insert(position, *first);
00515         ++first;
00516     }
00517 }
00518 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
00519 };
00520 #endif
00521 
00522 // Erases all elements in the list referred by an iterator i where
00523 // pred(*i) == true
00524 template <class Predicate, class T>
00525 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
00526 class OF_ListRemoveIfClass
00527 {
00528 public:
00529 static
00530 #endif
00531 void OF_ListRemoveIf(OFList<T>& c, Predicate pred)
00532 {
00533     OFIterator<T> first = c.begin();
00534     OFIterator<T> last = c.end();
00535     while (first != last)
00536     {
00537         if (pred(*first))
00538             first = c.erase(first);
00539         else
00540             ++first;
00541     }
00542 }
00543 
00544 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
00545 };
00546 #endif
00547 
00548 #define OFListIterator(x) OFIterator< x >
00549 #define OFListConstIterator(x) OFIterator< x >
00550 
00551 #endif
00552 
00553 #endif
00554 
00555 /*
00556 ** CVS/RCS Log:
00557 ** $Log: oflist.h,v $
00558 ** Revision 1.22  2005/12/08 16:05:58  meichel
00559 ** Changed include path schema for all DCMTK header files
00560 **
00561 ** Revision 1.21  2004/04/14 11:44:48  joergr
00562 ** Replaced non-Unix newline characters.
00563 **
00564 ** Revision 1.20  2003/08/07 11:44:55  joergr
00565 ** Slightly modified header comments to conform to doxygen syntax.
00566 **
00567 ** Revision 1.19  2003/07/11 13:46:14  joergr
00568 ** Added workaround to get rid of "implicit typename" warnings on gcc 3.x
00569 ** (introduced macro OFLIST_TYPENAME).
00570 **
00571 ** Revision 1.18  2003/07/09 13:57:43  meichel
00572 ** Adapted type casts to new-style typecast operators defined in ofcast.h
00573 **
00574 ** Revision 1.17  2003/06/12 15:20:30  joergr
00575 ** Slightly modified macro definitions to avoid potential parser errors (added
00576 ** space character after '<' and before '>').
00577 **
00578 ** Revision 1.16  2003/06/12 13:21:54  joergr
00579 ** Introduced macro OFListConstIterator() to support STL const_iterators.
00580 **
00581 ** Revision 1.15  2003/06/03 10:20:00  meichel
00582 ** OFList now explicitly defined as std::list if std namespace present
00583 **
00584 ** Revision 1.14  2002/11/27 11:23:05  meichel
00585 ** Adapted module ofstd to use of new header file ofstdinc.h
00586 **
00587 ** Revision 1.13  2001/08/23 16:05:52  meichel
00588 ** Added private undefined copy assignment operators to avoid gcc warnings
00589 **
00590 ** Revision 1.12  2001/06/01 15:51:34  meichel
00591 ** Updated copyright header
00592 **
00593 ** Revision 1.11  2000/10/10 12:01:21  meichel
00594 ** Created/updated doc++ comments
00595 **
00596 ** Revision 1.10  2000/03/08 16:36:02  meichel
00597 ** Updated copyright header.
00598 **
00599 ** Revision 1.9  1998/11/27 12:42:51  joergr
00600 ** Added copyright message to source files and changed CVS header.
00601 **
00602 ** Revision 1.8  1998/07/02 07:47:02  meichel
00603 ** Some code purifications to avoid gcc 2.8.1 -Weffc++ warnings.
00604 **
00605 ** Revision 1.7  1998/06/29 12:09:23  meichel
00606 ** Removed some name clashes (e.g. local variable with same
00607 **   name as class member) to improve maintainability.
00608 **   Applied some code purifications proposed by the gcc 2.8.1 -Weffc++ option.
00609 **
00610 ** Revision 1.6  1998/02/06 15:07:38  meichel
00611 ** Removed many minor problems (name clashes, unreached code)
00612 **   reported by Sun CC4 with "+w" or Sun CC2.
00613 **
00614 ** Revision 1.5  1997/11/10 16:31:19  meichel
00615 ** Corrected bug possibly causing a memory leak in OFList.
00616 **   Added virtual destructors to classes OFListLinkBase and OFListLink.
00617 **
00618 ** Revision 1.4  1997/09/11 15:43:15  hewett
00619 ** Minor changes to eliminate warnings when compiled under the
00620 ** Signus GnuWin32 envionment.  Changed order of initialisers
00621 ** for OFListLink and OFStackLink.  Make ~OFLisBase and ~OFStackBase
00622 ** virtual destructors.
00623 **
00624 ** Revision 1.3  1997/07/24 13:11:00  andreas
00625 ** - Removed Warnings from SUN CC 2.0.1
00626 **
00627 ** Revision 1.2  1997/07/07 07:34:18  andreas
00628 ** - Corrected destructor for OFListBase, now the dummy element is
00629 **   deleted.
00630 **
00631 ** Revision 1.1  1997/07/02 11:51:14  andreas
00632 ** - Preliminary release of the OFFIS Standard Library.
00633 **   In the future this library shall contain a subset of the
00634 **   ANSI C++ Library (Version 3) that works on a lot of different
00635 **   compilers. Additionally this library shall include classes and
00636 **   functions that are often used. All classes and functions begin
00637 **   with OF... This library is independent of the DICOM development and
00638 **   shall contain no DICOM specific stuff.
00639 **
00640 **
00641 */


Generated on 20 Dec 2005 for OFFIS DCMTK Version 3.5.4 by Doxygen 1.4.5