/*************************************************************************\ * Copyright (c) 2002 The University of Chicago, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS BASE Versions 3.13.7 * and higher are distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ // epicsList.h // Author: Andrew Johnson // Date: October 2000 #ifndef __EPICS_LIST_H__ #define __EPICS_LIST_H__ #include "epicsListBase.h" #include // epicsList // =========== // This implementation omits allocators, and only supports lists of pointers to // objects. Class templates are not provided, so functions overloaded on input // iterators are not available, nor are reverse iterators. Some functionality // makes no sense in this version, for example splice cannot be implemented // quickly because list nodes must never be transferred to a different list. // Reference numbers in comments are to sections in ISO/IEC 14882:1998(E) template class epicsListIterator; template class epicsListConstIterator; template class epicsList { public: // Types typedef size_t size_type; typedef epicsListIterator iterator; typedef epicsListConstIterator const_iterator; // Construct/copy/destroy (23.2.2.1) epicsList(); ~epicsList(); // Iterator support iterator begin(); const_iterator begin() const; iterator end(); const_iterator end() const; // Capacity bool empty() const; size_type size() const; // Element access T front(); const T front() const; T back(); const T back() const; // Modifiers (23.2.2.3) void push_front(const T x); void pop_front(); void push_back(const T x); void pop_back(); iterator insert(iterator position, const T x); iterator erase(iterator position); iterator erase(iterator position, iterator leave); void swap(epicsList& x); void clear(); // List operations (23.2.2.4) // void remove(const T value); // void unique(); // void reverse(); private: // Prevent compiler-generated functions epicsList(const epicsList&); epicsList& operator=(const epicsList&); private: // Data size_type _count; epicsListNode _head; epicsListNodePool _pool; friend class epicsListIterator; friend class epicsListConstIterator; }; // Specialized algorithms: template inline void epicsListSwap(epicsList& x, epicsList& y) { x.swap(y); } // Mutable iterator // These used to be inner classes of epicsList, but MSVC6 // didn't like that so they had to be typedefs... template class epicsListIterator { public: epicsListIterator(); // The following are created automatically by C++: // epicsListIterator(const epicsListIterator& rhs); // epicsListIterator& operator=(const epicsListIterator& rhs); T operator*() const; T operator->() const; epicsListIterator& operator++(); const epicsListIterator operator++(int); epicsListIterator& operator--(); const epicsListIterator operator--(int); bool operator==(const epicsListIterator& rhs) const; bool operator==(const epicsListConstIterator& rhs) const; bool operator!=(const epicsListIterator& rhs) const; bool operator!=(const epicsListConstIterator& rhs) const; private: // Constructor for List use epicsListIterator(epicsListNode* node); private: epicsListNode* _node; friend class epicsList; friend class epicsListConstIterator; }; // Constant iterator template class epicsListConstIterator { public: epicsListConstIterator(); epicsListConstIterator(const epicsListIterator& rhs); epicsListConstIterator& operator=(const epicsListIterator& rhs); // The following are created automatically by C++: // epicsListConstIterator(const epicsListConstIterator& rhs); // epicsListConstIterator& operator=(const epicsListConstIterator& rhs); const T operator*() const; const T operator->() const; epicsListConstIterator& operator++(); const epicsListConstIterator operator++(int); epicsListConstIterator& operator--(); const epicsListConstIterator operator--(int); bool operator==(const epicsListConstIterator& rhs) const; bool operator==(const epicsListIterator& rhs) const; bool operator!=(const epicsListConstIterator& rhs) const; bool operator!=(const epicsListIterator& rhs) const; private: // Constructor for List use epicsListConstIterator(const epicsListNode* node); private: const epicsListNode* _node; friend class epicsList; }; // END OF DECLARATIONS // INLINE METHODS // epicsList template inline epicsList::epicsList() : _count(0), _head(0), _pool() {} template inline epicsList::~epicsList() {} template inline typename epicsList::iterator epicsList::begin() { return _head.next(); } template inline typename epicsList::const_iterator epicsList::begin() const { return _head.next(); } template inline typename epicsList::iterator epicsList::end() { return &_head; } template inline typename epicsList::const_iterator epicsList::end() const { return &_head; } template inline bool epicsList::empty() const { return (_count == 0); } template inline typename epicsList::size_type epicsList::size() const { return _count; } template inline T epicsList::front() { if (empty()) throw std::logic_error("epicsList::front: list empty"); return static_cast(_head.next()->payload); } template inline const T epicsList::front() const { if (empty()) throw std::logic_error("epicsList::front: list empty"); return static_cast(_head.next()->payload); } template inline T epicsList::back() { if (empty()) throw std::logic_error("epicsList::back: list empty"); return static_cast(_head.prev()->payload); } template inline const T epicsList::back() const { if (empty()) throw std::logic_error("epicsList::back: list empty"); return static_cast(_head.prev()->payload); } template inline void epicsList::push_front(const T x) { epicsListNode* node = _pool.allocate(); node->payload = x; _head.append(*node); _count++; } template inline void epicsList::pop_front() { if (empty()) throw std::logic_error("epicsList::pop_front: list empty"); epicsListNode* node = _head.next(); node->unlink(); _count--; _pool.free(node); } template inline void epicsList::push_back(const T x) { epicsListNode* node = _pool.allocate(); node->payload = x; _head.insert(*node); _count++; } template inline void epicsList::pop_back() { if (empty()) throw std::logic_error("epicsList::pop_back: list empty"); epicsListNode* node = _head.prev(); node->unlink(); _count--; _pool.free(node); } template inline typename epicsList::iterator epicsList::insert(iterator pos, const T x) { epicsListNode* node = _pool.allocate(); node->payload = x; pos._node->insert(*node); _count++; return node; } template inline typename epicsList::iterator epicsList::erase(iterator pos) { if ((pos._node == 0) || (pos._node == &_head)) return pos; iterator next = pos._node->next(); pos._node->unlink(); _count--; _pool.free(pos._node); return next; } template inline typename epicsList::iterator epicsList::erase(iterator pos, iterator leave) { while (pos != leave) { pos = erase(pos); } return pos; } template inline void epicsList::swap(epicsList& x) { _head.swap(x._head); _pool.swap(x._pool); epicsSwap(x._count, _count); } template inline void epicsList::clear() { if (!empty()) erase(begin(), end()); } // epicsListIterator template inline epicsListIterator::epicsListIterator() : _node(0) {} template inline epicsListIterator::epicsListIterator(epicsListNode* node) : _node(node) {} template inline T epicsListIterator::operator*() const { return static_cast(_node->payload); } template inline T epicsListIterator::operator->() const { return static_cast(_node->payload); } template inline epicsListIterator& epicsListIterator::operator++() { _node = _node->next(); return *this; } template inline const epicsListIterator epicsListIterator::operator++(int) { epicsListIterator temp = *this; ++(*this); return temp; } template inline epicsListIterator& epicsListIterator::operator--() { _node = _node->prev(); return *this; } template inline const epicsListIterator epicsListIterator::operator--(int) { epicsListIterator temp = *this; --(*this); return temp; } template inline bool epicsListIterator::operator==(const epicsListIterator& rhs) const { return (_node == rhs._node); } template inline bool epicsListIterator::operator==(const epicsListConstIterator& rhs) const { return (rhs == *this); } template inline bool epicsListIterator::operator!=(const epicsListIterator& rhs) const { return !(_node == rhs._node); } template inline bool epicsListIterator::operator!=(const epicsListConstIterator& rhs) const { return !(rhs == *this); } // epicsListConstIterator template inline epicsListConstIterator::epicsListConstIterator() : _node(0) {} template inline epicsListConstIterator::epicsListConstIterator(const epicsListIterator& rhs) : _node(rhs._node) {} template inline epicsListConstIterator::epicsListConstIterator(const epicsListNode* node) : _node(node) {} template inline epicsListConstIterator& epicsListConstIterator::operator=(const epicsListIterator& rhs){ _node = rhs._node; return *this; } template inline const T epicsListConstIterator::operator*() const { return static_cast(_node->payload); } template inline const T epicsListConstIterator::operator->() const { return static_cast(_node->payload); } template inline epicsListConstIterator& epicsListConstIterator::operator++() { _node = _node->next(); return *this; } template inline const epicsListConstIterator epicsListConstIterator::operator++(int) { epicsListConstIterator temp = *this; ++(*this); return temp; } template inline epicsListConstIterator& epicsListConstIterator::operator--() { _node = _node->prev(); return *this; } template inline const epicsListConstIterator epicsListConstIterator::operator--(int) { epicsListConstIterator temp = *this; --(*this); return temp; } template inline bool epicsListConstIterator::operator==(const epicsListConstIterator& rhs) const { return (_node == rhs._node); } template inline bool epicsListConstIterator::operator==(const epicsListIterator& rhs) const { return (_node == rhs._node); } template inline bool epicsListConstIterator::operator!=(const epicsListConstIterator& rhs) const { return !(_node == rhs._node); } template inline bool epicsListConstIterator::operator!=(const epicsListIterator& rhs) const { return !(_node == rhs._node); } #endif