fixed eol-style

git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/trunk@23 8a3a26a2-13c4-0310-b231-cf6edde360e5
This commit is contained in:
spog 2006-02-21 22:18:44 +00:00
parent 29ac8a44c6
commit 7f7e598c4a
1 changed files with 239 additions and 239 deletions

View File

@ -1,239 +1,239 @@
/* /*
Copyright (C) 2001-2006, William Joseph. Copyright (C) 2001-2006, William Joseph.
All Rights Reserved. All Rights Reserved.
This file is part of GtkRadiant. This file is part of GtkRadiant.
GtkRadiant is free software; you can redistribute it and/or modify GtkRadiant is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
GtkRadiant is distributed in the hope that it will be useful, GtkRadiant is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with GtkRadiant; if not, write to the Free Software along with GtkRadiant; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#if !defined(INCLUDED_CONTAINER_STACK_H) #if !defined(INCLUDED_CONTAINER_STACK_H)
#define INCLUDED_CONTAINER_STACK_H #define INCLUDED_CONTAINER_STACK_H
#include "memory/allocator.h" #include "memory/allocator.h"
#include <algorithm> #include <algorithm>
/// \brief A stack whose storage capacity is variable at run-time. Similar to std::vector. /// \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). /// - 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. /// - 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. /// - DefaultConstructible, Copyable, Assignable.
/// - Compatible with the containers and algorithms in the Standard Template Library (STL) - http://www.sgi.com/tech/stl/ /// - 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. /// \param Type: The type to be stored in the stack. Must provide a copy-constructor.
template<typename Type> template<typename Type>
class Stack : public DefaultAllocator<Type> class Stack : public DefaultAllocator<Type>
{ {
typedef DefaultAllocator<Type> Allocator; typedef DefaultAllocator<Type> Allocator;
enum enum
{ {
DEFAULT_CAPACITY = 4, DEFAULT_CAPACITY = 4,
}; };
typedef Type* pointer; typedef Type* pointer;
typedef const Type* const_pointer; typedef const Type* const_pointer;
public: public:
typedef const_pointer const_iterator; typedef const_pointer const_iterator;
private: private:
pointer m_data; pointer m_data;
pointer m_end; pointer m_end;
std::size_t m_capacity; std::size_t m_capacity;
void insert(const Type& value) void insert(const Type& value)
{ {
Allocator::construct(m_end++, value); Allocator::construct(m_end++, value);
} }
void insert_overflow(const Type& 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 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_data = Allocator::allocate(new_capacity);
const pointer new_end = std::copy(m_data, m_end, new_data); const pointer new_end = std::copy(m_data, m_end, new_data);
destroy(); destroy();
Allocator::deallocate(m_data, m_capacity); Allocator::deallocate(m_data, m_capacity);
m_capacity = new_capacity; m_capacity = new_capacity;
m_data = new_data; m_data = new_data;
m_end = new_end; m_end = new_end;
insert(value); insert(value);
} }
void destroy() void destroy()
{ {
for(pointer p = m_data; p != m_end; ++p) for(pointer p = m_data; p != m_end; ++p)
{ {
Allocator::destroy(p); Allocator::destroy(p);
} }
} }
void construct(const Stack& other) void construct(const Stack& other)
{ {
pointer p = m_data; pointer p = m_data;
for(const_iterator i = other.begin(); i != other.end(); ++i) for(const_iterator i = other.begin(); i != other.end(); ++i)
{ {
Allocator::construct(p++, *i); Allocator::construct(p++, *i);
} }
} }
public: public:
Stack() : Stack() :
m_data(0), m_data(0),
m_end(0), m_end(0),
m_capacity(0) m_capacity(0)
{ {
} }
Stack(const Type& value) : Stack(const Type& value) :
m_data(0), m_data(0),
m_end(0), m_end(0),
m_capacity(0) m_capacity(0)
{ {
push(value); push(value);
} }
Stack(const Stack& other) : Stack(const Stack& other) :
DefaultAllocator<Type>(other) DefaultAllocator<Type>(other)
{ {
m_capacity = other.m_capacity; m_capacity = other.m_capacity;
m_data = Allocator::allocate(m_capacity); m_data = Allocator::allocate(m_capacity);
construct(other); construct(other);
m_end = m_data + other.size(); m_end = m_data + other.size();
} }
~Stack() ~Stack()
{ {
destroy(); destroy();
Allocator::deallocate(m_data, m_capacity); Allocator::deallocate(m_data, m_capacity);
} }
const_iterator begin() const const_iterator begin() const
{ {
return m_data; return m_data;
} }
const_iterator end() const const_iterator end() const
{ {
return m_end; return m_end;
} }
bool empty() const bool empty() const
{ {
return end() == begin(); return end() == begin();
} }
void clear() void clear()
{ {
destroy(); destroy();
m_end = m_data; m_end = m_data;
} }
std::size_t size() const std::size_t size() const
{ {
return m_end - m_data; return m_end - m_data;
} }
Type operator[](const std::size_t i) const Type operator[](const std::size_t i) const
{ {
return m_data[i]; 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. /// \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) void push(const Type& value)
{ {
if(size() == m_capacity) if(size() == m_capacity)
{ {
insert_overflow(value); insert_overflow(value);
} }
else else
{ {
insert(value); insert(value);
} }
} }
/// \brief Removes the top element of the stack. /// \brief Removes the top element of the stack.
void pop() void pop()
{ {
Allocator::destroy(--m_end); Allocator::destroy(--m_end);
} }
/// \brief Returns the top element of the mutable stack. /// \brief Returns the top element of the mutable stack.
Type& top() Type& top()
{ {
return *(m_end-1); return *(m_end-1);
} }
/// \brief Returns the top element of the non-mutable stack. /// \brief Returns the top element of the non-mutable stack.
const Type& top() const const Type& top() const
{ {
return *(m_end-1); return *(m_end-1);
} }
/// \brief Returns the element below the top element of the mutable stack. /// \brief Returns the element below the top element of the mutable stack.
Type& parent() Type& parent()
{ {
return *(m_end-2); return *(m_end-2);
} }
/// \brief Returns the element below the top element of the non-mutable stack. /// \brief Returns the element below the top element of the non-mutable stack.
const Type& parent() const const Type& parent() const
{ {
return *(m_end-2); return *(m_end-2);
} }
/// \brief Swaps the values of this stack and \p other. /// \brief Swaps the values of this stack and \p other.
void swap(Stack& other) void swap(Stack& other)
{ {
std::swap(m_data, other.m_data); std::swap(m_data, other.m_data);
std::swap(m_end, other.m_end); std::swap(m_end, other.m_end);
std::swap(m_capacity, other.m_capacity); std::swap(m_capacity, other.m_capacity);
} }
#if 1 // use copy-swap technique #if 1 // use copy-swap technique
Stack& operator=(const Stack& other) Stack& operator=(const Stack& other)
{ {
Stack temp(other); Stack temp(other);
temp.swap(*this); temp.swap(*this);
return *this; return *this;
} }
#else // avoids memory allocation if capacity is already sufficient. #else // avoids memory allocation if capacity is already sufficient.
Stack& operator=(const Stack& other) Stack& operator=(const Stack& other)
{ {
if(&other != this) if(&other != this)
{ {
destroy(); destroy();
if(other.size() > m_capacity) if(other.size() > m_capacity)
{ {
Allocator::deallocate(m_data, m_capacity); Allocator::deallocate(m_data, m_capacity);
m_capacity = other.m_capacity; m_capacity = other.m_capacity;
m_data = Allocator::allocate(m_capacity); m_data = Allocator::allocate(m_capacity);
} }
m_end = m_data + other.size(); m_end = m_data + other.size();
construct(other); construct(other);
} }
return *this; return *this;
} }
#endif #endif
}; };
/// \brief Returns true if \p self is lexicographically less than \p other. /// \brief Returns true if \p self is lexicographically less than \p other.
template<typename Type> template<typename Type>
inline bool operator<(const Stack<Type>& self, const Stack<Type>& other) inline bool operator<(const Stack<Type>& self, const Stack<Type>& other)
{ {
return std::lexicographical_compare(self.begin(), self.end(), other.begin(), other.end()); return std::lexicographical_compare(self.begin(), self.end(), other.begin(), other.end());
} }
namespace std namespace std
{ {
/// \brief Swaps the values of \p self and \p other. /// \brief Swaps the values of \p self and \p other.
/// Overloads std::swap(). /// Overloads std::swap().
template<typename Type> template<typename Type>
inline void swap(Stack<Type>& self, Stack<Type>& other) inline void swap(Stack<Type>& self, Stack<Type>& other)
{ {
self.swap(other); self.swap(other);
} }
} }
#endif #endif