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

297 lines
6.8 KiB
C
Raw Normal View History

2024-11-22 15:19:31 +00:00
/*
*
* Copyright (C) 1997-2016, 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 stack class with interfaces similar to the C++ Standard
*
*/
#ifndef OFSTACK_H
#define OFSTACK_H
#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"
#if defined(HAVE_STL) || defined(HAVE_STL_STACK)
// 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, no variable
// in a namespace with using a list shall have the name stack
#include <stack>
#define OFStack std::stack
#else
#define INCLUDE_CASSERT
#define INCLUDE_CSTDDEF
#include "dcmtk/ofstd/ofstdinc.h"
#ifndef HAVE_CLASS_TEMPLATE
#error Your C++ compiler cannot handle class templates:
#endif
/** non-template single linked list class, used to store elements of a stack.
* Implicitly used by OFStack, should not be called by users.
*/
struct OFStackLinkBase
{
/// pointer to next entry in list
OFStackLinkBase * next;
/// default constructor
OFStackLinkBase()
: next(NULL)
{
}
/// destructor
virtual ~OFStackLinkBase()
{
}
private:
/// private undefined copy constructor
OFStackLinkBase(const OFStackLinkBase &);
/// private undefined copy assignment operator
OFStackLinkBase &operator=(const OFStackLinkBase &);
};
/** non-template base class for OFStack.
* Implicitly used by OFStack, should not be called by users.
*/
class DCMTK_OFSTD_EXPORT OFStackBase
{
public:
/// default constructor
OFStackBase()
: head(NULL),
stackSize(0)
{
}
/// destructor
virtual ~OFStackBase()
{
while(!base_empty())
base_pop();
}
/** checks if the stack is empty
* @return true if stack is empty, false otherwise
*/
OFBool base_empty() const { return head == NULL; }
/** returns size of stack
* @return size of stack
*/
size_t base_size() const { return stackSize; }
/** returns element on top of stack.
* precondition: stack is not empty
* @return element on top of stack.
*/
OFStackLinkBase * base_top()
{
assert(head!=NULL);
return head;
}
/** returns element on top of stack.
* precondition: stack is not empty
* @return element on top of stack.
*/
const OFStackLinkBase * base_top() const
{
assert(head!=NULL);
return head;
}
/** pushes element onto stack.
* @param element pointer to element
*/
void base_push(OFStackLinkBase * element)
{
element->next = head;
head = element;
stackSize++;
}
/** removes top element from stack.
* precondition: stack not empty.
*/
void base_pop()
{
assert(head!=NULL);
OFStackLinkBase * delObj = head;
head = head->next;
delete delObj;
stackSize--;
}
protected:
/// pointer to top element of stack
OFStackLinkBase * head;
/// size of stack
size_t stackSize;
private:
/// private undefined copy constructor
OFStackBase(const OFStackBase &);
/// private undefined copy assignment operator
OFStackBase &operator=(const OFStackBase &);
};
/** template class used to store stack entries.
* Implicitly used by OFStack, should not be called by users.
*/
template <class T>
struct OFStackLink : public OFStackLinkBase
{
/// element on stack
T info;
/** constructor
* @param i element maintain by this object
*/
OFStackLink(const T & i) : OFStackLinkBase(), info(i) { }
/// destructor
virtual ~OFStackLink()
{
}
private:
/// private undefined copy constructor
OFStackLink(const OFStackLink<T> &);
/// private undefined copy assignment operator
OFStackLink<T> &operator=(const OFStackLink<T> &);
};
/** template stack class. The interface is a subset of
* the STL stack class.
*/
template <class T>
class OFStack : private OFStackBase
{
public:
/// default constructor
OFStack() {};
/// copy constructor
OFStack(const OFStack<T> & x) : OFStackBase()
{
copy(x);
}
/// assignment operator
OFStack<T> &operator=(const OFStack<T> &x)
{
if (this != &x)
{
while(!OFStackBase::base_empty())
OFStackBase::base_pop();
copy(x);
}
return *this;
}
/** checks if the stack is empty.
* @return OFTrue if stack is empty, OFFalse otherwise.
*/
OFBool empty() const { return OFStackBase::base_empty(); }
/** returns the number of elements on the stack
* @return number of elements on stack
*/
size_t size() const { return OFStackBase::base_size(); }
/** returns a reference to the top element on the stack.
* This method may not be called if the stack is empty.
* @return reference to top element
*/
T & top()
{
return (OFstatic_cast(OFStackLink<T> *, OFStackBase::base_top()))->info;
}
/** returns a const reference to the top element on the stack.
* This method may not be called if the stack is empty.
* @return const reference to top element
*/
const T & top() const
{
return (OFstatic_cast(const OFStackLink<T> *, OFStackBase::base_top()))->info;
}
/** inserts a new element on top of the stack. The value of
* the new element is copy constructed from the given argument.
* @param x value to be pushed (copied) onto the stack
*/
void push(const T & x)
{
OFStackBase::base_push(new OFStackLink<T>(x));
}
/** removes the top element from the stack.
* This method may not be called if the stack is empty.
*/
void pop() { OFStackBase::base_pop(); }
private:
/** copy assignment of a stack.
* @param x stack to be copied
* @return dummy value, required to keep Sun CC 2.0.1 happy
*/
int copy(const OFStack<T> & x)
{
stackSize = x.size();
if (stackSize)
{
head = new OFStackLink<T>((OFstatic_cast(OFStackLink<T>*, x.head))->info);
OFStackLinkBase * newPtr = head;
OFStackLinkBase * oldPtr = x.head->next;
while (oldPtr)
{
newPtr->next = new OFStackLink<T>((OFstatic_cast(OFStackLink<T>*, oldPtr))->info);
oldPtr = oldPtr->next;
newPtr = newPtr->next;
}
}
return 0;
}
};
#endif
#endif