From 7f7e598c4aed8bf6369820c646c167cfc62ff777 Mon Sep 17 00:00:00 2001 From: spog Date: Tue, 21 Feb 2006 22:18:44 +0000 Subject: [PATCH] fixed eol-style git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/trunk@23 8a3a26a2-13c4-0310-b231-cf6edde360e5 --- libs/container/stack.h | 478 ++++++++++++++++++++--------------------- 1 file changed, 239 insertions(+), 239 deletions(-) diff --git a/libs/container/stack.h b/libs/container/stack.h index 85b3d07..d83674c 100644 --- a/libs/container/stack.h +++ b/libs/container/stack.h @@ -1,239 +1,239 @@ -/* -Copyright (C) 2001-2006, William Joseph. -All Rights Reserved. - -This file is part of GtkRadiant. - -GtkRadiant is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -GtkRadiant is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GtkRadiant; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#if !defined(INCLUDED_CONTAINER_STACK_H) -#define INCLUDED_CONTAINER_STACK_H - -#include "memory/allocator.h" -#include - -/// \brief A stack whose storage capacity is variable at run-time. Similar to std::vector. -/// -/// - Pushing or popping elements is a constant-time operation (on average). -/// - The storage capacity of the stack will grow when a new element is added beyond the current capacity. Iterators are invalidated when the storage capacity grows. -/// - DefaultConstructible, Copyable, Assignable. -/// - Compatible with the containers and algorithms in the Standard Template Library (STL) - http://www.sgi.com/tech/stl/ -/// -/// \param Type: The type to be stored in the stack. Must provide a copy-constructor. -template -class Stack : public DefaultAllocator -{ - typedef DefaultAllocator Allocator; - - enum - { - DEFAULT_CAPACITY = 4, - }; - - typedef Type* pointer; - typedef const Type* const_pointer; - -public: - typedef const_pointer const_iterator; -private: - - pointer m_data; - pointer m_end; - std::size_t m_capacity; - - - void insert(const Type& value) - { - Allocator::construct(m_end++, value); - } - void insert_overflow(const Type& value) - { - const std::size_t new_capacity = (m_capacity) ? m_capacity + m_capacity : std::size_t(DEFAULT_CAPACITY); - const pointer new_data = Allocator::allocate(new_capacity); - const pointer new_end = std::copy(m_data, m_end, new_data); - - destroy(); - Allocator::deallocate(m_data, m_capacity); - - m_capacity = new_capacity; - m_data = new_data; - m_end = new_end; - insert(value); - } - void destroy() - { - for(pointer p = m_data; p != m_end; ++p) - { - Allocator::destroy(p); - } - } - void construct(const Stack& other) - { - pointer p = m_data; - for(const_iterator i = other.begin(); i != other.end(); ++i) - { - Allocator::construct(p++, *i); - } - } - -public: - - Stack() : - m_data(0), - m_end(0), - m_capacity(0) - { - } - Stack(const Type& value) : - m_data(0), - m_end(0), - m_capacity(0) - { - push(value); - } - Stack(const Stack& other) : - DefaultAllocator(other) - { - m_capacity = other.m_capacity; - m_data = Allocator::allocate(m_capacity); - construct(other); - m_end = m_data + other.size(); - } - ~Stack() - { - destroy(); - Allocator::deallocate(m_data, m_capacity); - } - - const_iterator begin() const - { - return m_data; - } - const_iterator end() const - { - return m_end; - } - - bool empty() const - { - return end() == begin(); - } - void clear() - { - destroy(); - m_end = m_data; - } - - std::size_t size() const - { - return m_end - m_data; - } - Type operator[](const std::size_t i) const - { - return m_data[i]; - } - /// \brief Pushes \p value onto the stack at the top element. If reserved storage is insufficient for the new element, this will invalidate all iterators. - void push(const Type& value) - { - if(size() == m_capacity) - { - insert_overflow(value); - } - else - { - insert(value); - } - } - /// \brief Removes the top element of the stack. - void pop() - { - Allocator::destroy(--m_end); - } - /// \brief Returns the top element of the mutable stack. - Type& top() - { - return *(m_end-1); - } - /// \brief Returns the top element of the non-mutable stack. - const Type& top() const - { - return *(m_end-1); - } - /// \brief Returns the element below the top element of the mutable stack. - Type& parent() - { - return *(m_end-2); - } - /// \brief Returns the element below the top element of the non-mutable stack. - const Type& parent() const - { - return *(m_end-2); - } - /// \brief Swaps the values of this stack and \p other. - void swap(Stack& other) - { - std::swap(m_data, other.m_data); - std::swap(m_end, other.m_end); - std::swap(m_capacity, other.m_capacity); - } -#if 1 // use copy-swap technique - Stack& operator=(const Stack& other) - { - Stack temp(other); - temp.swap(*this); - return *this; - } -#else // avoids memory allocation if capacity is already sufficient. - Stack& operator=(const Stack& other) - { - if(&other != this) - { - destroy(); - - if(other.size() > m_capacity) - { - Allocator::deallocate(m_data, m_capacity); - m_capacity = other.m_capacity; - m_data = Allocator::allocate(m_capacity); - } - m_end = m_data + other.size(); - - construct(other); - } - return *this; - } -#endif -}; - -/// \brief Returns true if \p self is lexicographically less than \p other. -template -inline bool operator<(const Stack& self, const Stack& other) -{ - return std::lexicographical_compare(self.begin(), self.end(), other.begin(), other.end()); -} - -namespace std -{ - /// \brief Swaps the values of \p self and \p other. - /// Overloads std::swap(). - template - inline void swap(Stack& self, Stack& other) - { - self.swap(other); - } -} - -#endif +/* +Copyright (C) 2001-2006, William Joseph. +All Rights Reserved. + +This file is part of GtkRadiant. + +GtkRadiant is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +GtkRadiant is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GtkRadiant; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#if !defined(INCLUDED_CONTAINER_STACK_H) +#define INCLUDED_CONTAINER_STACK_H + +#include "memory/allocator.h" +#include + +/// \brief A stack whose storage capacity is variable at run-time. Similar to std::vector. +/// +/// - Pushing or popping elements is a constant-time operation (on average). +/// - The storage capacity of the stack will grow when a new element is added beyond the current capacity. Iterators are invalidated when the storage capacity grows. +/// - DefaultConstructible, Copyable, Assignable. +/// - Compatible with the containers and algorithms in the Standard Template Library (STL) - http://www.sgi.com/tech/stl/ +/// +/// \param Type: The type to be stored in the stack. Must provide a copy-constructor. +template +class Stack : public DefaultAllocator +{ + typedef DefaultAllocator Allocator; + + enum + { + DEFAULT_CAPACITY = 4, + }; + + typedef Type* pointer; + typedef const Type* const_pointer; + +public: + typedef const_pointer const_iterator; +private: + + pointer m_data; + pointer m_end; + std::size_t m_capacity; + + + void insert(const Type& value) + { + Allocator::construct(m_end++, value); + } + void insert_overflow(const Type& value) + { + const std::size_t new_capacity = (m_capacity) ? m_capacity + m_capacity : std::size_t(DEFAULT_CAPACITY); + const pointer new_data = Allocator::allocate(new_capacity); + const pointer new_end = std::copy(m_data, m_end, new_data); + + destroy(); + Allocator::deallocate(m_data, m_capacity); + + m_capacity = new_capacity; + m_data = new_data; + m_end = new_end; + insert(value); + } + void destroy() + { + for(pointer p = m_data; p != m_end; ++p) + { + Allocator::destroy(p); + } + } + void construct(const Stack& other) + { + pointer p = m_data; + for(const_iterator i = other.begin(); i != other.end(); ++i) + { + Allocator::construct(p++, *i); + } + } + +public: + + Stack() : + m_data(0), + m_end(0), + m_capacity(0) + { + } + Stack(const Type& value) : + m_data(0), + m_end(0), + m_capacity(0) + { + push(value); + } + Stack(const Stack& other) : + DefaultAllocator(other) + { + m_capacity = other.m_capacity; + m_data = Allocator::allocate(m_capacity); + construct(other); + m_end = m_data + other.size(); + } + ~Stack() + { + destroy(); + Allocator::deallocate(m_data, m_capacity); + } + + const_iterator begin() const + { + return m_data; + } + const_iterator end() const + { + return m_end; + } + + bool empty() const + { + return end() == begin(); + } + void clear() + { + destroy(); + m_end = m_data; + } + + std::size_t size() const + { + return m_end - m_data; + } + Type operator[](const std::size_t i) const + { + return m_data[i]; + } + /// \brief Pushes \p value onto the stack at the top element. If reserved storage is insufficient for the new element, this will invalidate all iterators. + void push(const Type& value) + { + if(size() == m_capacity) + { + insert_overflow(value); + } + else + { + insert(value); + } + } + /// \brief Removes the top element of the stack. + void pop() + { + Allocator::destroy(--m_end); + } + /// \brief Returns the top element of the mutable stack. + Type& top() + { + return *(m_end-1); + } + /// \brief Returns the top element of the non-mutable stack. + const Type& top() const + { + return *(m_end-1); + } + /// \brief Returns the element below the top element of the mutable stack. + Type& parent() + { + return *(m_end-2); + } + /// \brief Returns the element below the top element of the non-mutable stack. + const Type& parent() const + { + return *(m_end-2); + } + /// \brief Swaps the values of this stack and \p other. + void swap(Stack& other) + { + std::swap(m_data, other.m_data); + std::swap(m_end, other.m_end); + std::swap(m_capacity, other.m_capacity); + } +#if 1 // use copy-swap technique + Stack& operator=(const Stack& other) + { + Stack temp(other); + temp.swap(*this); + return *this; + } +#else // avoids memory allocation if capacity is already sufficient. + Stack& operator=(const Stack& other) + { + if(&other != this) + { + destroy(); + + if(other.size() > m_capacity) + { + Allocator::deallocate(m_data, m_capacity); + m_capacity = other.m_capacity; + m_data = Allocator::allocate(m_capacity); + } + m_end = m_data + other.size(); + + construct(other); + } + return *this; + } +#endif +}; + +/// \brief Returns true if \p self is lexicographically less than \p other. +template +inline bool operator<(const Stack& self, const Stack& other) +{ + return std::lexicographical_compare(self.begin(), self.end(), other.begin(), other.end()); +} + +namespace std +{ + /// \brief Swaps the values of \p self and \p other. + /// Overloads std::swap(). + template + inline void swap(Stack& self, Stack& other) + { + self.swap(other); + } +} + +#endif