// -*- c++ -*- // Copyright 1998 Zanshin Inc. // The contents of this file are subject to the Zanshin Public License Version // 1.0 (the "License"); you may not use this file except in compliance with the // License. You should have received a copy of the License with Latte; see // the file COPYING. You may also obtain a copy of the License at // . // // Software distributed under the License is distributed on an "AS IS" basis, // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License // for the specific language governing rights and limitations under the // License. // // The Original Code is Latte. // // The Initial Developer of the Original Code is Zanshin, Inc. #ifndef LATTE_SHDEQUE_H # define LATTE_SHDEQUE_H #include #include template class shdeque { private: class rep : public Refcounted, public latte_deque { private: typedef latte_deque super; public: class const_iterator; class iterator : public super::iterator { public: iterator(rep &r, const super::iterator &i) : super::iterator(i), m_rep(&r) {} iterator(const iterator &other) : super::iterator(other), m_rep(other.m_rep) {} iterator &operator = (const iterator &other) { if (this != &other) { m_rep = other.m_rep; static_cast(*this) = other; } return *this; } iterator operator + (long n) const { return iterator(*m_rep, (static_cast(*this) + n)); } bool operator == (const iterator &other) const { return ((this == &other) || ((m_rep == other.m_rep) && (static_cast(*this) == static_cast(other)))); } private: const rep *m_rep; // rep is incomplete here, so unfortunately // this cannot be Refcounter< rep > friend const_iterator; friend shdeque; }; class const_iterator : public super::const_iterator { public: const_iterator(const rep &r, const super::const_iterator &i) : super::const_iterator(i), m_rep(&r) {} const_iterator(const iterator &i) : super::const_iterator(i), m_rep(i.m_rep) {} const_iterator(const const_iterator &other) : super::const_iterator(other), m_rep(other.m_rep) {} const_iterator &operator = (const const_iterator &other) { if (this != &other) { m_rep = other.m_rep; static_cast(*this) = other; } return *this; } const_iterator operator + (long n) const { return const_iterator(*m_rep, (static_cast(*this) + n)); } bool operator == (const const_iterator &other) const { return ((this == &other) || ((m_rep == other.m_rep) && (static_cast(*this) == static_cast(other)))); } private: const rep *m_rep; // rep is incomplete here, so unfortunately // this cannot be Refcounter< rep > friend iterator; friend shdeque; }; rep() {} rep(const iterator &a, const iterator &b) : super(a, b) {} rep(const rep &other) : super(other.begin(), other.end()) {} iterator begin() { return iterator(*this, super::begin()); } iterator end() { return iterator(*this, super::end()); } const_iterator begin() const { return const_iterator(*this, super::begin()); } const_iterator end() const { return const_iterator(*this, super::end()); } }; public: typedef rep::iterator iterator; typedef rep::const_iterator const_iterator; private: Refcounter m_rep; // this... const_iterator m_begin, m_end; // ...must precede this void adjust() { m_begin = m_rep->begin(); m_end = m_rep->end(); } public: shdeque() : m_rep(new rep), m_begin(m_rep->begin()), m_end(m_rep->end()) {} shdeque(const latte_deque::const_iterator &a, const latte_deque::const_iterator &b) : m_rep(new rep(a, b)), m_begin(*m_rep, m_rep->begin()), m_end(*m_rep, m_rep->end()) {} shdeque(const const_iterator &a, const const_iterator &b) : m_rep(a.m_rep), m_begin(*m_rep, a), m_end(*m_rep, b) {} shdeque(const shdeque &other) : m_rep(other.m_rep), m_begin(other.m_begin), m_end(other.m_end) {} size_t size() const { return m_end - m_begin; } bool empty() const { return (m_begin == m_end); } // iterator begin() { return m_rep->begin(); } const_iterator begin() const { return m_begin; } // iterator end() { return m_rep->end(); } const_iterator end() const { return m_end; } // T &front() { return m_rep->front(); } const T &front() const { return *m_begin; } // T &back() { return m_rep->back(); } const T &back() const { const_iterator i = m_end; return *--i; } // T &operator [] (long n) { return *(m_begin + n); } const T &operator [] (long n) const { return *(m_begin + n); } void push_front(const T &t) { const_cast(*m_rep).push_front(t); adjust(); } void push_back(const T &t) { const_cast(*m_rep).push_back(t); adjust(); } void pop_front() { const_cast(*m_rep).pop_front(); adjust(); } void pop_back() { const_cast(*m_rep).pop_back(); adjust(); } void append(const latte_deque::const_iterator &a, const latte_deque::const_iterator &b) { const_cast(*m_rep).append(a, b); adjust(); } }; #endif // LATTE_SHDEQUE_H