]> git.xonotic.org Git - voretournament/voretournament.git/blob - misc/source/netradiant-src/libs/container/array.h
Rename mediasource to source
[voretournament/voretournament.git] / misc / source / netradiant-src / libs / container / array.h
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #if !defined(INCLUDED_CONTAINER_ARRAY_H)
23 #define INCLUDED_CONTAINER_ARRAY_H
24
25 #include <cstddef>
26 #include <algorithm>
27
28 #include "memory/allocator.h"
29
30 /// \brief An array whose size is variable at run-time.
31 ///
32 /// - Resizing the array destroys all the existing elements and invalidates all iterators.
33 /// - Default-Constructible, Copyable, Assignable. 
34 /// - Compatible with the containers and algorithms in the Standard Template Library (STL) - http://www.sgi.com/tech/stl/
35 ///
36 /// \param Element The type to be stored in the array. Must provide a default-constructor and a copy-constructor.
37 /// \param Allocator A custom memory-allocator, conforming to the std::allocator interface.
38 template<typename Element, typename Allocator = DefaultAllocator<Element> >
39 class Array : public Allocator
40 {
41   std::size_t m_size;
42   Element* m_data;
43
44   Element* construct(std::size_t size)
45   {
46 #if 1
47     return New<Element, Allocator>(*this).vector(size);
48 #else
49     return new Element[size];
50 #endif
51   }
52   template<typename T1>
53   Element* construct(std::size_t size, const T1& value)
54   {
55     return New<Element, Allocator>(*this).vector(size, value);
56   }
57   void destroy(Element* data, std::size_t size)
58   {
59 #if 1
60     Delete<Element, Allocator>(*this).vector(data, size);
61 #else
62     delete[] data;
63 #endif
64   }
65
66 public:
67   typedef Element value_type;
68   typedef value_type* iterator;
69   typedef const value_type* const_iterator;
70
71   Array()
72     : m_size(0), m_data(0)
73   {
74   }
75   Array(std::size_t size)
76     : m_size(size), m_data(construct(size))
77   {
78   }
79   template<typename T1>
80   Array(std::size_t size, const T1& value)
81     : m_size(size), m_data(construct(size, value))
82   {
83   }
84   Array(const Array& other)
85     : Allocator(other), m_size(other.size()), m_data(construct(m_size))
86   {
87     std::copy(other.begin(), other.end(), begin());
88   }
89   template<typename Iterator>
90   Array(Iterator start, Iterator finish)
91   : m_size(std::distance(start, finish)), m_data(construct(m_size))
92   {
93     std::copy(start, finish, begin());
94   }
95   ~Array()
96   {
97     destroy(m_data, m_size);
98   }
99
100   Array& operator=(const Array& other)
101   {
102     if(other.size() == size())
103     {
104       std::copy(other.begin(), other.end(), begin());
105     }
106     else
107     {
108       Array temp(other);
109       temp.swap(*this);
110     }
111     return *this;
112   }
113
114   void swap(Array& other)
115   {
116     std::swap(m_size, other.m_size);
117     std::swap(m_data, other.m_data);
118   }
119
120   iterator begin()
121   {
122     return m_data;
123   }
124   const_iterator begin() const
125   {
126     return m_data;
127   }
128   iterator end()
129   {
130     return m_data + m_size;
131   }
132   const_iterator end() const
133   {
134     return m_data + m_size;
135   }
136
137   value_type& operator[](std::size_t index)
138   {
139 #if defined(_DEBUG)
140     ASSERT_MESSAGE(index < size(), "array index out of bounds");
141 #endif
142     return m_data[index];
143   }
144   const value_type& operator[](std::size_t index) const
145   {
146 #if defined(_DEBUG)
147     ASSERT_MESSAGE(index < size(), "array index out of bounds");
148 #endif
149     return m_data[index];
150   }
151   value_type* data()
152   {
153     return m_data;
154   }
155   const value_type* data() const
156   {
157     return m_data;
158   }
159   std::size_t size() const
160   {
161     return m_size;
162   }
163   bool empty() const
164   {
165     return m_size == 0;
166   }
167
168   void resize(std::size_t count)
169   {
170     if(count != size())
171     {
172       Array temp(count);
173       temp.swap(*this);
174     }
175   }
176   void resize(std::size_t count, const value_type& value)
177   {
178     if(count != size())
179     {
180       Array temp(count, value);
181       temp.swap(*this);
182     }
183   }
184 };
185
186 namespace std
187 {
188   /// \brief Swaps the values of \p self and \p other.
189   /// Overloads std::swap.
190   template<typename Element, typename Allocator>
191   inline void swap(Array<Element, Allocator>& self, Array<Element, Allocator>& other)
192   {
193     self.swap(other);
194   }
195 }
196
197 #endif