OFFIS DCMTK  Version 3.6.0
oflist.h
1 /*
2  *
3  * Copyright (C) 1997-2010, OFFIS e.V.
4  * All rights reserved. See COPYRIGHT file for details.
5  *
6  * This software and supporting documentation were developed by
7  *
8  * OFFIS e.V.
9  * R&D Division Health
10  * Escherweg 2
11  * D-26121 Oldenburg, Germany
12  *
13  *
14  * Module: ofstd
15  *
16  * Author: Andreas Barth
17  *
18  * Purpose:
19  * Defines a template list class with interfaces similar to the C++ Standard
20  *
21  * Last Update: $Author: joergr $
22  * Update Date: $Date: 2010-10-14 13:15:50 $
23  * CVS/RCS Revision: $Revision: 1.26 $
24  * Status: $State: Exp $
25  *
26  * CVS/RCS Log at end of file
27  *
28  */
29 
30 #ifndef OFLIST_H
31 #define OFLIST_H
32 
33 // Usage (only non standard):
34 // OFListInsert(InputIterator_type, T_type, c, pos, first, last)
35 // Inserts the elements of type T in
36 // range [first, last) into list c,
37 // OFListRemoveIf(Predicate_Type, T_type, c, pred)
38 // Erases all elements of type T in the list referred by
39 // an iterator i where pred(*i) == true.
40 // Predicate_Type is the function type of pred
41 //
42 // Additional Remarks:
43 // In some template functions one template parameter is another function.
44 // Some compilers cannot determine automatically the type of template
45 // function parameters, so you must give them a hint casting
46 // the parameter function to the correct type (e.g. NeXT gcc 2.5.8)
47 
48 #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
49 #include "dcmtk/ofstd/oftypes.h"
50 #include "dcmtk/ofstd/ofcast.h"
51 
52 #ifndef HAVE_CLASS_TEMPLATE
53 #error Your C++ compiler cannot handle class templates:
54 #endif
55 
56 #if defined(HAVE_STL) || defined(HAVE_STL_LIST)
57 // It is possible to use the standard template library list class since the
58 // interface is nearly identical.
59 // Important: If you want to use the standard template library (STL), no
60 // variable within a namespace using a class of the STL shall have a name
61 // of one class of the STL
62 #include <list>
63 
64 #ifdef HAVE_STD_NAMESPACE
65 #define OFList std::list
66 #define OFListIterator(x) std::list< x >::iterator
67 #define OFListConstIterator(x) std::list< x >::const_iterator
68 #else
69 #define OFList list
70 #define OFListIterator(x) list< x >::iterator
71 #define OFListConstIterator(x) list< x >::const_iterator
72 #endif
73 
74 #define OFListInsert(InputIterator, T, c, pos, first, last) (c).insert((pos), (first), (last))
75 #define OFListRemoveIf(Predicate, T, c, pred) (c).remove_if((pred))
76 
77 // workaround for "implicit typename" warning on gcc 3.x
78 #define OFLIST_TYPENAME OFTypename
79 
80 #else
81 
82 #define INCLUDE_CASSERT
83 #define INCLUDE_CSTDDEF
84 #include "dcmtk/ofstd/ofstdinc.h"
85 
86 #define OFLIST_TYPENAME
87 
88 BEGIN_EXTERN_C
89 #ifdef HAVE_SYS_TYPES_H
90 /* needed e.g. on Solaris for definition of size_t */
91 #include <sys/types.h>
92 #endif
93 END_EXTERN_C
94 
95 // OFListLinkBase, OFListLink and OFListBase are classes for internal
96 // use only and shall not be used.
97 
98 /* non-template double linked list. Base class fo OFListLink.
99  * Implicitly used by OFList, should not be called by users.
100  */
102 {
103  OFListLinkBase * next;
104  OFListLinkBase * prev;
105  OFBool dummy;
106  OFListLinkBase(): next(NULL), prev(NULL), dummy(OFFalse) { }
107  virtual ~OFListLinkBase() {}
108 
109  private:
110  /* undefined */ OFListLinkBase(const OFListLinkBase&);
111  /* undefined */ OFListLinkBase& operator=(const OFListLinkBase&);
112 };
113 
114 
115 /* non-template list. Base class fo OFList.
116  * Implicitly used by OFList, should not be called by users.
117  */
119 {
120 protected:
121  OFListLinkBase * afterLast;
122  size_t listSize;
123  void base_recalcListSize();
124 public:
125  OFListBase();
126  virtual ~OFListBase();
127  OFListLinkBase * base_begin() const { return afterLast->next; }
128  OFListLinkBase * base_end() const { return afterLast; }
129  OFBool base_empty() const { return afterLast == afterLast->next; }
130  size_t base_size() const { return listSize; }
131  OFListLinkBase * base_insert(OFListLinkBase * pos, OFListLinkBase * newElem);
132  OFListLinkBase * base_erase(OFListLinkBase * pos);
133  void base_splice(OFListLinkBase * pos,
134  OFListLinkBase * begin, OFListLinkBase * end);
135  void base_clear();
136 
137  private:
138  /* undefined */ OFListBase(const OFListBase&);
139  /* undefined */ OFListBase& operator=(const OFListBase&);
140 };
141 
142 
143 
144 /* template class for double linked list entries.
145  * Implicitly used by OFList, should not be called by users.
146  */
147 template <class T>
148 struct OFListLink : public OFListLinkBase
149 {
150  T info;
151  OFListLink(const T& i) : OFListLinkBase(), info(i) { }
152  virtual ~OFListLink() {}
153  private:
154  /* undefined */ OFListLink(const OFListLink<T>&);
155  /* undefined */ OFListLink<T>& operator=(const OFListLink<T>&);
156 };
157 
158 
159 // Definition of OFList and OFIterator
160 
161 template <class T> class OFList;
162 
163 
170 template <class T>
172 {
173  friend class OFList<T>;
174 protected:
175 
178 
183 public:
184 
189  OFIterator() : node(NULL) { }
190 
193  OFIterator(const OFIterator<T>& x) : node(x.node) { };
194 
198  {
199  node = x.node;
200  return *this;
201  }
202 
208  OFBool operator==(const OFIterator<T>& x) const { return node == x.node; }
209 
215  OFBool operator!=(const OFIterator<T>& x) const { return node != x.node; }
216 
221  T& operator*() const
222  {
223  assert(!node->dummy);
224  return (OFstatic_cast(OFListLink<T> *,node))->info;
225  }
226 
231  T* operator->() const
232  {
233  return &(**this);
234  }
235 
242  {
243  node = node->next;
244  return *this;
245  }
246 
254  {
255  OFIterator<T> tmp(*this);
256  node = node->next;
257  return tmp;
258  }
259 
266  {
267  node = node->prev;
268  return *this;
269  }
270 
278  {
279  OFIterator<T> tmp(*this);
280  node = node->prev;
281  return tmp;
282  }
283 };
284 
285 
289 template <class T>
290 class OFList : private OFListBase
291 {
292 public:
298  OFIterator<T> insert(OFIterator<T> position, const T& x)
299  {
300  return OFIterator<T>(OFListBase::base_insert(position.node, new OFListLink<T>(x)));
301  }
302 
303 private:
304 
308  void copy(const OFList<T>& oldList)
309  {
310  OFIterator<T> vfirst(oldList.begin());
311  OFIterator<T> vend(oldList.end());
312  OFIterator<T> vpos(this->end());
313  while (vfirst != vend)
314  {
315  insert(vpos, *vfirst);
316  ++vfirst;
317  }
318  }
319 
323  void recalcListSize() { OFListBase::base_recalcListSize(); }
324 
325 public:
326 
329  OFList() : OFListBase() { }
330 
333  OFList(const OFList<T>& oldList):OFListBase()
334  {
335  copy(oldList);
336  }
337 
342  OFIterator<T> begin() const { return OFIterator<T>(OFListBase::base_begin()); }
343 
348  OFIterator<T> end() const { return OFIterator<T>(OFListBase::base_end()); }
349 
353  OFBool empty() const { return OFListBase::base_empty(); }
354 
358  size_t size() const { return OFListBase::base_size(); }
359 
364  T& front() { return *begin(); }
365 
370  T& back() { return *(--end()); }
371 
375  void push_front(const T& x) { insert(begin(), OFconst_cast(T&, x)); }
376  /* const cast away to keep some old compilers happy */
377 
382  void pop_front() { erase(begin()); }
383 
387  void push_back(const T& x) { insert(end(), OFconst_cast(T&, x)); }
388  /* const cast away to keep some old compilers happy */
389 
394  void pop_back() { erase(--end()); }
395 
401  void insert(OFIterator<T> position, size_t n, const T& x)
402  {
403  while(n--) OFListBase::base_insert(position.node, new OFListLink<T>(x));
404  }
405 
411  {
412  return OFIterator<T>(OFListBase::base_erase(position.node));
413  }
414 
422  {
423  while (position != last) position = erase(position);
424  return last;
425  }
426 
430  void clear() { OFListBase::base_clear(); }
431 
437  void splice(OFIterator<T> position, OFList<T>& x)
438  {
439  splice(position, x, x.begin(), x.end());
440  }
441 
448  {
449  OFIterator<T> change(i);
450  ++i;
451  splice(position, x, change, i);
452  }
453 
461  void splice(OFIterator<T> position, OFList<T>& x,
462  OFIterator<T> first, OFIterator<T> last)
463  {
464  OFListBase::base_splice(position.node, first.node, last.node);
465  x.recalcListSize();
466  }
467 
472  void remove(const T& value)
473  {
474  OFIterator<T> first = begin();
475  OFIterator<T> last = end();
476  while(first != last)
477  {
478  if (*first == value) first = erase(first);
479  else ++first;
480  }
481  }
482 
483 private:
484 
487  OFList<T>& operator=(const OFList<T>& arg);
488 };
489 
490 
491 #ifdef HAVE_FUNCTION_TEMPLATE
492 
493 #define OFListInsert(InputIterator, T, c, pos, first, last) OF_ListInsert((c), (pos), (first), (last))
494 
495 #define OFListRemoveIf(Predicate, T, c, pred) OF_ListRemoveIf((c), (pred))
496 
497 #elif defined(HAVE_STATIC_TEMPLATE_METHOD)
498 
499 #define OFListInsert(InputIterator, T, c, pos, first, last) OF_ListInsertClass<InputIterator, T>::OF_ListInsert((c), (pos), (first), (last))
500 
501 #define OFListRemoveIf(Predicate, T, c, pred) OF_ListRemoveIfClass<Predicate, T>::OF_ListRemoveIf((c), (pred))
502 
503 #else
504 #error Your C++ Compiler is not capable of compiling this code
505 #endif
506 
507 // Insert the elements in range [first, last) into list
508 template <class InputIterator, class T>
509 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
510 class OF_ListInsertClass
511 {
512 public:
513 static
514 #endif
515 void OF_ListInsert(OFList<T>& c, OFIterator<T> position,
516  InputIterator first, InputIterator last)
517 {
518  while(first != last)
519  {
520  c.insert(position, *first);
521  ++first;
522  }
523 }
524 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
525 };
526 #endif
527 
528 // Erases all elements in the list referred by an iterator i where
529 // pred(*i) == true
530 template <class Predicate, class T>
531 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
532 class OF_ListRemoveIfClass
533 {
534 public:
535 static
536 #endif
537 void OF_ListRemoveIf(OFList<T>& c, Predicate pred)
538 {
539  OFIterator<T> first = c.begin();
540  OFIterator<T> last = c.end();
541  while (first != last)
542  {
543  if (pred(*first))
544  first = c.erase(first);
545  else
546  ++first;
547  }
548 }
549 
550 #if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
551 };
552 #endif
553 
554 #define OFListIterator(x) OFIterator< x >
555 #define OFListConstIterator(x) OFIterator< x >
556 
557 #endif
558 
559 #endif
560 
561 /*
562 ** CVS/RCS Log:
563 ** $Log: oflist.h,v $
564 ** Revision 1.26 2010-10-14 13:15:50 joergr
565 ** Updated copyright header. Added reference to COPYRIGHT file.
566 **
567 ** Revision 1.25 2010-05-07 11:13:42 uli
568 ** Use OFTypename for OFLIST_TYPENAME.
569 **
570 ** Revision 1.24 2009-08-19 11:55:45 meichel
571 ** Added additional includes needed for Sun Studio 11 on Solaris.
572 **
573 ** Revision 1.23 2009-08-19 10:44:36 joergr
574 ** Added missing dereference operator.
575 **
576 ** Revision 1.22 2005/12/08 16:05:58 meichel
577 ** Changed include path schema for all DCMTK header files
578 **
579 ** Revision 1.21 2004/04/14 11:44:48 joergr
580 ** Replaced non-Unix newline characters.
581 **
582 ** Revision 1.20 2003/08/07 11:44:55 joergr
583 ** Slightly modified header comments to conform to doxygen syntax.
584 **
585 ** Revision 1.19 2003/07/11 13:46:14 joergr
586 ** Added workaround to get rid of "implicit typename" warnings on gcc 3.x
587 ** (introduced macro OFLIST_TYPENAME).
588 **
589 ** Revision 1.18 2003/07/09 13:57:43 meichel
590 ** Adapted type casts to new-style typecast operators defined in ofcast.h
591 **
592 ** Revision 1.17 2003/06/12 15:20:30 joergr
593 ** Slightly modified macro definitions to avoid potential parser errors (added
594 ** space character after '<' and before '>').
595 **
596 ** Revision 1.16 2003/06/12 13:21:54 joergr
597 ** Introduced macro OFListConstIterator() to support STL const_iterators.
598 **
599 ** Revision 1.15 2003/06/03 10:20:00 meichel
600 ** OFList now explicitly defined as std::list if std namespace present
601 **
602 ** Revision 1.14 2002/11/27 11:23:05 meichel
603 ** Adapted module ofstd to use of new header file ofstdinc.h
604 **
605 ** Revision 1.13 2001/08/23 16:05:52 meichel
606 ** Added private undefined copy assignment operators to avoid gcc warnings
607 **
608 ** Revision 1.12 2001/06/01 15:51:34 meichel
609 ** Updated copyright header
610 **
611 ** Revision 1.11 2000/10/10 12:01:21 meichel
612 ** Created/updated doc++ comments
613 **
614 ** Revision 1.10 2000/03/08 16:36:02 meichel
615 ** Updated copyright header.
616 **
617 ** Revision 1.9 1998/11/27 12:42:51 joergr
618 ** Added copyright message to source files and changed CVS header.
619 **
620 ** Revision 1.8 1998/07/02 07:47:02 meichel
621 ** Some code purifications to avoid gcc 2.8.1 -Weffc++ warnings.
622 **
623 ** Revision 1.7 1998/06/29 12:09:23 meichel
624 ** Removed some name clashes (e.g. local variable with same
625 ** name as class member) to improve maintainability.
626 ** Applied some code purifications proposed by the gcc 2.8.1 -Weffc++ option.
627 **
628 ** Revision 1.6 1998/02/06 15:07:38 meichel
629 ** Removed many minor problems (name clashes, unreached code)
630 ** reported by Sun CC4 with "+w" or Sun CC2.
631 **
632 ** Revision 1.5 1997/11/10 16:31:19 meichel
633 ** Corrected bug possibly causing a memory leak in OFList.
634 ** Added virtual destructors to classes OFListLinkBase and OFListLink.
635 **
636 ** Revision 1.4 1997/09/11 15:43:15 hewett
637 ** Minor changes to eliminate warnings when compiled under the
638 ** Signus GnuWin32 envionment. Changed order of initialisers
639 ** for OFListLink and OFStackLink. Make ~OFLisBase and ~OFStackBase
640 ** virtual destructors.
641 **
642 ** Revision 1.3 1997/07/24 13:11:00 andreas
643 ** - Removed Warnings from SUN CC 2.0.1
644 **
645 ** Revision 1.2 1997/07/07 07:34:18 andreas
646 ** - Corrected destructor for OFListBase, now the dummy element is
647 ** deleted.
648 **
649 ** Revision 1.1 1997/07/02 11:51:14 andreas
650 ** - Preliminary release of the OFFIS Standard Library.
651 ** In the future this library shall contain a subset of the
652 ** ANSI C++ Library (Version 3) that works on a lot of different
653 ** compilers. Additionally this library shall include classes and
654 ** functions that are often used. All classes and functions begin
655 ** with OF... This library is independent of the DICOM development and
656 ** shall contain no DICOM specific stuff.
657 **
658 **
659 */


Generated on Thu Dec 20 2012 for OFFIS DCMTK Version 3.6.0 by Doxygen 1.8.2