DYT/Tool/3rdParty_x64/include/dcmtk/ofstd/oflist.h

571 lines
18 KiB
C
Raw Normal View History

2024-11-22 15:19:31 +00:00
/*
*
* Copyright (C) 1997-2011, OFFIS e.V.
* All rights reserved. See COPYRIGHT file for details.
*
* This software and supporting documentation were developed by
*
* OFFIS e.V.
* R&D Division Health
* Escherweg 2
* D-26121 Oldenburg, Germany
*
*
* Module: ofstd
*
* Author: Andreas Barth
*
* Purpose:
* Defines a template list class with interfaces similar to the C++ Standard
*
*/
#ifndef OFLIST_H
#define OFLIST_H
// Usage (only non standard):
// OFListInsert(InputIterator_type, T_type, c, pos, first, last)
// Inserts the elements of type T in
// range [first, last) into list c,
// OFListRemoveIf(Predicate_Type, T_type, c, pred)
// Erases all elements of type T in the list referred by
// an iterator i where pred(*i) == true.
// Predicate_Type is the function type of pred
//
// Additional Remarks:
// In some template functions one template parameter is another function.
// Some compilers cannot determine automatically the type of template
// function parameters, so you must give them a hint casting
// the parameter function to the correct type (e.g. NeXT gcc 2.5.8)
#include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
#include "dcmtk/ofstd/oftypes.h"
#include "dcmtk/ofstd/ofcast.h"
#include "dcmtk/ofstd/ofdefine.h"
#ifndef HAVE_CLASS_TEMPLATE
#error Your C++ compiler cannot handle class templates:
#endif
#if defined(HAVE_STL) || defined(HAVE_STL_LIST)
// It is possible to use the standard template library list class since the
// interface is nearly identical.
// Important: If you want to use the standard template library (STL), no
// variable within a namespace using a class of the STL shall have a name
// of one class of the STL
#include <list>
#ifdef HAVE_STD_NAMESPACE
#define OFList std::list
#define OFListIterator(x) std::list< x >::iterator
#define OFListConstIterator(x) std::list< x >::const_iterator
#else
#define OFList list
#define OFListIterator(x) list< x >::iterator
#define OFListConstIterator(x) list< x >::const_iterator
#endif
#define OFListInsert(InputIterator, T, c, pos, first, last) (c).insert((pos), (first), (last))
#define OFListRemoveIf(Predicate, T, c, pred) (c).remove_if((pred))
// workaround for "implicit typename" warning on gcc 3.x
#define OFLIST_TYPENAME OFTypename
#else
#define INCLUDE_CASSERT
#define INCLUDE_CSTDDEF
#include "dcmtk/ofstd/ofstdinc.h"
#define OFLIST_TYPENAME
BEGIN_EXTERN_C
#ifdef HAVE_SYS_TYPES_H
/* needed e.g. on Solaris for definition of size_t */
#include <sys/types.h>
#endif
END_EXTERN_C
// OFListLinkBase, OFListLink and OFListBase are classes for internal
// use only and shall not be used.
/* non-template double linked list. Base class fo OFListLink.
* Implicitly used by OFList, should not be called by users.
*/
struct OFListLinkBase
{
OFListLinkBase * next;
OFListLinkBase * prev;
OFBool dummy;
OFListLinkBase(): next(NULL), prev(NULL), dummy(OFFalse) { }
virtual ~OFListLinkBase() {}
private:
/* undefined */ OFListLinkBase(const OFListLinkBase&);
/* undefined */ OFListLinkBase& operator=(const OFListLinkBase&);
};
/* non-template list. Base class fo OFList.
* Implicitly used by OFList, should not be called by users.
*/
class DCMTK_OFSTD_EXPORT OFListBase
{
protected:
OFListLinkBase * afterLast;
size_t listSize;
void base_recalcListSize();
public:
OFListBase();
virtual ~OFListBase();
OFListLinkBase * base_begin() const { return afterLast->next; }
OFListLinkBase * base_end() const { return afterLast; }
OFBool base_empty() const { return afterLast == afterLast->next; }
size_t base_size() const { return listSize; }
OFListLinkBase * base_insert(OFListLinkBase * pos, OFListLinkBase * newElem);
OFListLinkBase * base_erase(OFListLinkBase * pos);
void base_splice(OFListLinkBase * pos,
OFListLinkBase * begin, OFListLinkBase * end);
void base_clear();
private:
/* undefined */ OFListBase(const OFListBase&);
/* undefined */ OFListBase& operator=(const OFListBase&);
};
/* template class for double linked list entries.
* Implicitly used by OFList, should not be called by users.
*/
template <class T>
struct OFListLink : public OFListLinkBase
{
T info;
OFListLink(const T& i) : OFListLinkBase(), info(i) { }
virtual ~OFListLink() {}
private:
/* undefined */ OFListLink(const OFListLink<T>&);
/* undefined */ OFListLink<T>& operator=(const OFListLink<T>&);
};
// Definition of OFList and OFIterator
template <class T> class OFList;
/** iterator class for OFList. An iterator is a generalization of a pointer
* and allows a C++ program to work with different containers independently
* from their internal structure. Instances of this template class should
* be declared as OFListIterator(T) instead of OFListIterator<T>. This
* allows to re-map OFList to the STL list class if available.
*/
template <class T>
class OFIterator
{
friend class OFList<T>;
protected:
/// list node referenced by the iterator
OFListLinkBase * node;
/** constructor.
* @param x list node referenced by the iterator
*/
OFIterator(OFListLinkBase * x) : node(x) { }
public:
/** default constructor. Creates an iterator referencing nothing.
* In general, iterators should always be copy-constructed
* in user code.
*/
OFIterator() : node(NULL) { }
/** copy constructor
*/
OFIterator(const OFIterator<T>& x) : node(x.node) { };
/** copy assignment operator
*/
OFIterator<T>& operator=(const OFIterator<T>& x)
{
node = x.node;
return *this;
}
/** comparison of two iterators. The iterators are equal if and only if
* they reference the same element, independent from the element values.
* @param x iterator to be compared
* @return OFTrue if equal, OFFalse otherwise.
*/
OFBool operator==(const OFIterator<T>& x) const { return node == x.node; }
/** comparison of two iterators. The iterators are equal if and only if
* they reference the same element, independent from the element values.
* @param x iterator to be compared
* @return OFTrue if not equal, OFFalse otherwise.
*/
OFBool operator!=(const OFIterator<T>& x) const { return node != x.node; }
/** dereferences the iterator. May only be called if iterator references
* a valid element of a list.
* @return reference to the element "pointed to" by the iterator.
*/
T& operator*() const
{
assert(!node->dummy);
return (OFstatic_cast(OFListLink<T> *,node))->info;
}
/** dereferences the iterator. May only be called if iterator references
* a valid element of a list.
* @return reference to the element "pointed to" by the iterator.
*/
T* operator->() const
{
return &(**this);
}
/** moves the iterator to the next element of the list.
* The list is circular: the first element follows after the end of the list.
* May only be called if iterator references a valid element or the end of a list.
* @return reference to the incremented iterator.
*/
OFIterator<T>& operator++()
{
node = node->next;
return *this;
}
/** moves the iterator to the next element of the list.
* The list is circular: the first element follows after the end of the list.
* May only be called if iterator references a valid element or the end of a list.
* This is the post-increment operator.
* @return previous iterator state, by value
*/
OFIterator<T> operator++(int)
{
OFIterator<T> tmp(*this);
node = node->next;
return tmp;
}
/** moves the iterator to the previous element of the list.
* The list is circular: the end of the list follows before the first element.
* May only be called if iterator references a valid element or the end of a list.
* @return reference to the decremented iterator.
*/
OFIterator<T>& operator--()
{
node = node->prev;
return *this;
}
/** moves the iterator to the previous element of the list.
* The list is circular: the end of the list follows before the first element.
* May only be called if iterator references a valid element or the end of a list.
* This is the post-decremented operator.
* @return previous iterator state, by value
*/
OFIterator<T> operator--(int)
{
OFIterator<T> tmp(*this);
node = node->prev;
return tmp;
}
};
/** double linked list template class. The interface is a subset of the STL
* list class.
*/
template <class T>
class OFList : private OFListBase
{
public:
/** inserts an element into the list before the given position.
* @param position iterator to position before which the element is inserted
* @param x value from which the new list entry is copy-constructed
* @return iterator pointing to the new element in the list
*/
OFIterator<T> insert(OFIterator<T> position, const T& x)
{
return OFIterator<T>(OFListBase::base_insert(position.node, new OFListLink<T>(x)));
}
private:
/** inserts a copy of the given list into the current list.
* @param oldList list to be copied
*/
void copy(const OFList<T>& oldList)
{
OFIterator<T> vfirst(oldList.begin());
OFIterator<T> vend(oldList.end());
OFIterator<T> vpos(this->end());
while (vfirst != vend)
{
insert(vpos, *vfirst);
++vfirst;
}
}
/** counts the elements in the list and adjusts the listSize
* member variable.
*/
void recalcListSize() { OFListBase::base_recalcListSize(); }
public:
/** default constructor
*/
OFList() : OFListBase() { }
/** copy constructor
*/
OFList(const OFList<T>& oldList):OFListBase()
{
copy(oldList);
}
/** returns an iterator referencing the first element in the list.
* If the list is empty, then begin() == end().
* @return iterator to first element of list, by value.
*/
OFIterator<T> begin() const { return OFIterator<T>(OFListBase::base_begin()); }
/** returns an iterator which points to the past-to-end element
* of the list.
* @return iterator to past-to-end, by value.
*/
OFIterator<T> end() const { return OFIterator<T>(OFListBase::base_end()); }
/** returns true if list is empty.
* @return OFTrue if list is empty, OFFalse otherwise.
*/
OFBool empty() const { return OFListBase::base_empty(); }
/** returns number of elements in the list.
* @return number of elements
*/
size_t size() const { return OFListBase::base_size(); }
/** returns a reference to the first element in the list.
* May only be called if list is non-empty.
* @return first element in list, by reference
*/
T& front() { return *begin(); }
/** returns a constant reference to the first element in the list.
* May only be called if list is non-empty.
* @return first element in list, by constant reference
*/
const T& front() const { return *begin(); }
/** returns a reference to the last element in the list.
* May only be called if list is non-empty.
* @return last element in list, by reference
*/
T& back() { return *(--end()); }
/** returns a constant reference to the last element in the list.
* May only be called if list is non-empty.
* @return last element in list, by constant reference
*/
const T& back() const { return *(--end()); }
/** inserts before the first element of the list.
* @param x value from which the new list entry is copy constructed
*/
void push_front(const T& x) { insert(begin(), OFconst_cast(T&, x)); }
/* const cast away to keep some old compilers happy */
/** removes the first element of the list.
* May only be called if list is non-empty.
* All iterators pointing to the removed element become invalid.
*/
void pop_front() { erase(begin()); }
/** inserts after the last element of the list.
* @param x value from which the new list entry is copy constructed
*/
void push_back(const T& x) { insert(end(), OFconst_cast(T&, x)); }
/* const cast away to keep some old compilers happy */
/** removes the last element of the list.
* May only be called if list is non-empty.
* All iterators pointing to the removed element become invalid.
*/
void pop_back() { erase(--end()); }
/** inserts n elements with value x into the list, before the given position.
* @param position iterator to position before which the elements are inserted
* @param n number of entries to be created
* @param x value from which the new list entries are copy-constructed
*/
void insert(OFIterator<T> position, size_t n, const T& x)
{
while(n--) OFListBase::base_insert(position.node, new OFListLink<T>(x));
}
/** removes the element at the given position from the list.
* All iterators pointing to the removed element become invalid.
* @return iterator pointing to the element after the removed one
*/
OFIterator<T> erase(OFIterator<T> position)
{
return OFIterator<T>(OFListBase::base_erase(position.node));
}
/** removes all elements in the range [position,last) from the list.
* All iterators pointing to the removed elements become invalid.
* @param position iterator to the first element to be deleted
* @param last iterator pointing to the element after the last element to be removed
* @return iterator pointing to the element after the last removed element
*/
OFIterator<T> erase(OFIterator<T> position, OFIterator<T> last)
{
while (position != last) position = erase(position);
return last;
}
/** removes all elements from the list.
* All iterators pointing to elements in the list become invalid.
*/
void clear() { OFListBase::base_clear(); }
/** moves the contents of list x into the current list before the
* given position.
* @param position iterator to position before which the elements are inserted
* @param x list from which the elements are taken, becomes empty
*/
void splice(OFIterator<T> position, OFList<T>& x)
{
splice(position, x, x.begin(), x.end());
}
/** inserts one element from list x into the current list and removes it from x
* @param position iterator to position before which the element is inserted
* @param x list from which the element is taken
* @param i iterator to element in list x which is to be moved
*/
void splice(OFIterator<T> position, OFList<T>& x, OFIterator<T> i)
{
OFIterator<T> change(i);
++i;
splice(position, x, change, i);
}
/** inserts elements in the range [first, last) before position and
* removes the elements from x
* @param position iterator to position before which the elements are inserted
* @param x list from which the elements are taken
* @param first iterator to first element in list x to be moved
* @param last iterator to element after last element in list x to be moved
*/
void splice(OFIterator<T> position, OFList<T>& x,
OFIterator<T> first, OFIterator<T> last)
{
OFListBase::base_splice(position.node, first.node, last.node);
x.recalcListSize();
}
/** removes all elements from the list referred by an iterator i where
* *i == value
* @param value value to be compared with list contents
*/
void remove(const T& value)
{
OFIterator<T> first = begin();
OFIterator<T> last = end();
while(first != last)
{
if (*first == value) first = erase(first);
else ++first;
}
}
/** copy assignment operator
* @param arg the list to copy from
* @return *this
*/
OFList<T>& operator=(const OFList<T>& arg)
{
clear();
copy(arg);
return *this;
}
};
#ifdef HAVE_FUNCTION_TEMPLATE
#define OFListInsert(InputIterator, T, c, pos, first, last) OF_ListInsert((c), (pos), (first), (last))
#define OFListRemoveIf(Predicate, T, c, pred) OF_ListRemoveIf((c), (pred))
#elif defined(HAVE_STATIC_TEMPLATE_METHOD)
#define OFListInsert(InputIterator, T, c, pos, first, last) OF_ListInsertClass<InputIterator, T>::OF_ListInsert((c), (pos), (first), (last))
#define OFListRemoveIf(Predicate, T, c, pred) OF_ListRemoveIfClass<Predicate, T>::OF_ListRemoveIf((c), (pred))
#else
#error Your C++ Compiler is not capable of compiling this code
#endif
// Insert the elements in range [first, last) into list
template <class InputIterator, class T>
#if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
class OF_ListInsertClass
{
public:
static
#endif
void OF_ListInsert(OFList<T>& c, OFIterator<T> position,
InputIterator first, InputIterator last)
{
while(first != last)
{
c.insert(position, *first);
++first;
}
}
#if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
};
#endif
// Erases all elements in the list referred by an iterator i where
// pred(*i) == true
template <class Predicate, class T>
#if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
class OF_ListRemoveIfClass
{
public:
static
#endif
void OF_ListRemoveIf(OFList<T>& c, Predicate pred)
{
OFIterator<T> first = c.begin();
OFIterator<T> last = c.end();
while (first != last)
{
if (pred(*first))
first = c.erase(first);
else
++first;
}
}
#if defined(HAVE_STATIC_TEMPLATE_METHOD) && !defined(HAVE_FUNCTION_TEMPLATE)
};
#endif
#define OFListIterator(x) OFIterator< x >
#define OFListConstIterator(x) OFIterator< x >
#endif
#endif