OSDN Git Service

change EOL style to CRLF to adjust to default setting of Visual Studio
[yamy/yamy.git] / array.h
1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
2 // array.h\r
3 \r
4 \r
5 #ifndef _ARRAY_H\r
6 #  define _ARRAY_H\r
7 \r
8 #  include <memory>\r
9 \r
10 \r
11 ///\r
12 template <class T, class Allocator = std::allocator<T> >\r
13 class Array\r
14 {\r
15 public:\r
16   typedef typename Allocator::reference         reference; ///\r
17   typedef typename Allocator::const_reference   const_reference; ///\r
18   typedef typename Allocator::pointer           iterator; ///\r
19   typedef typename Allocator::const_pointer     const_iterator; ///\r
20   typedef typename Allocator::size_type         size_type; ///\r
21   typedef typename Allocator::difference_type   difference_type; ///\r
22   typedef T                                     value_type;     ///\r
23   typedef Allocator                             allocator_type; ///\r
24   typedef typename Allocator::pointer           pointer; ///\r
25   typedef typename Allocator::const_pointer     const_pointer; ///\r
26 #if 0\r
27   typedef std::reverse_iterator<iterator>       reverse_iterator; ///\r
28   typedef std::reverse_iterator<const_iterator> const_reverse_iterator; ///\r
29 #endif    \r
30 private:\r
31   Allocator m_allocator;                        /// \r
32   size_type m_size;                             /// \r
33   pointer m_buf;                                /// array buffer\r
34 \r
35 public:\r
36   /// constructor\r
37   explicit Array(const Allocator& i_allocator = Allocator())\r
38     : m_allocator(i_allocator), m_size(0), m_buf(NULL)  { }\r
39           \r
40   /// constructor\r
41   explicit Array(size_type i_size, const T& i_value = T(),\r
42                  const Allocator& i_allocator = Allocator())\r
43     : m_allocator(i_allocator), m_size(i_size),\r
44       m_buf(m_allocator.allocate(m_size, 0))\r
45   {\r
46     std::uninitialized_fill_n(m_buf, i_size, i_value);\r
47   }\r
48           \r
49   /// constructor\r
50   template <class InputIterator>\r
51   Array(InputIterator i_begin, InputIterator i_end,\r
52         const Allocator& i_allocator = Allocator())\r
53     : m_allocator(i_allocator), m_size(distance(i_begin, i_end)),\r
54       m_buf(Allocator::allocate(m_size, 0))\r
55   {\r
56     std::uninitialized_copy(i_begin, i_end, m_buf);\r
57   }\r
58           \r
59   /// copy constructor\r
60   Array(const Array& i_o) : m_size(0), m_buf(NULL) { operator=(i_o); }\r
61 \r
62   /// destractor\r
63   ~Array() { clear(); }\r
64 \r
65   ///\r
66   Array& operator=(const Array& i_o)\r
67   {\r
68     if (&i_o != this)\r
69     {\r
70       clear();\r
71       m_size = i_o.m_size;\r
72       m_buf = m_allocator.allocate(m_size, 0);\r
73       std::uninitialized_copy(i_o.m_buf, i_o.m_buf + m_size, m_buf);\r
74     }\r
75     return *this;\r
76   }\r
77   ///\r
78   allocator_type get_allocator() const { return Allocator(); }\r
79   /// return pointer to the array buffer\r
80   typename allocator_type::pointer get() { return m_buf; }\r
81   /// return pointer to the array buffer\r
82   typename allocator_type::const_pointer get() const { return m_buf; }\r
83   ///\r
84   iterator begin() { return m_buf; }\r
85   ///\r
86   const_iterator begin() const { return m_buf; }\r
87   ///\r
88   iterator end() { return m_buf + m_size; }\r
89   ///\r
90   const_iterator end() const { return m_buf + m_size; }\r
91 #if 0\r
92   ///\r
93   reverse_iterator rbegin() { reverse_iterator(end()); }\r
94   ///\r
95   const_reverse_iterator rbegin() const { const_reverse_iterator(end()); }\r
96   ///\r
97   reverse_iterator rend() { reverse_iterator(begin()); }\r
98   ///\r
99   const_reverse_iterator rend() const { const_reverse_iterator(begin()); }\r
100 #endif\r
101   ///\r
102   size_type size() const { return m_size; }\r
103   ///\r
104   size_type max_size() const { return -1; }\r
105   /// resize the array buffer.  NOTE: the original contents are cleared.\r
106   void resize(size_type i_size, const T& i_value = T())\r
107   {\r
108     clear();\r
109     m_size = i_size;\r
110     m_buf = m_allocator.allocate(m_size, 0);\r
111     std::uninitialized_fill_n(m_buf, i_size, i_value);\r
112   }\r
113   /// resize the array buffer.  \r
114   template <class InputIterator>\r
115   void resize(InputIterator i_begin, InputIterator i_end)\r
116   {\r
117     clear();\r
118     m_size = distance(i_begin, i_end);\r
119     m_buf = m_allocator.allocate(m_size, 0);\r
120     std::uninitialized_copy(i_begin, i_end, m_buf);\r
121   }\r
122   /// expand the array buffer. the contents of it are copied to the new one\r
123   void expand(size_type i_size, const T& i_value = T())\r
124   {\r
125     ASSERT( m_size <= i_size );\r
126     if (!m_buf)\r
127       resize(i_size, i_value);\r
128     else\r
129     {\r
130       pointer buf = m_allocator.allocate(i_size, 0);\r
131       std::uninitialized_copy(m_buf, m_buf + m_size, buf);\r
132       std::uninitialized_fill_n(buf + m_size, i_size - m_size, i_value);\r
133       clear();\r
134       m_size = i_size;\r
135       m_buf = buf;\r
136     }\r
137   }\r
138   ///\r
139   bool empty() const { return !m_buf; }\r
140   ///\r
141   reference operator[](size_type i_n) { return *(m_buf + i_n); }\r
142   ///\r
143   const_reference operator[](size_type i_n) const\r
144   { return *(m_buf + i_n); }\r
145   ///\r
146   const_reference at(size_type i_n) const\r
147   { return *(m_buf + i_n); }\r
148   ///\r
149   reference at(size_type i_n)\r
150   { return *(m_buf + i_n); }\r
151   ///\r
152   reference front() { return *m_buf; }\r
153   ///\r
154   const_reference front() const { return *m_buf; }\r
155   ///\r
156   reference back() { return *(m_buf + m_size - 1); }\r
157   ///\r
158   const_reference back() const { return *(m_buf + m_size - 1); }\r
159   ///\r
160   void swap(Array &i_o)\r
161   {\r
162     if (&i_o != this)\r
163     {\r
164       pointer buf = m_buf;\r
165       size_type size = m_size;\r
166       m_buf = i_o.m_buf;\r
167       m_size = i_o.m_size;\r
168       i_o.m_buf = buf;\r
169       i_o.m_size = size;\r
170     }\r
171   }\r
172   ///\r
173   void clear()\r
174   {\r
175     if (m_buf)\r
176     {\r
177       for (size_type i = 0; i < m_size; i ++)\r
178         m_allocator.destroy(&m_buf[i]);\r
179       m_allocator.deallocate(m_buf, m_size);\r
180       m_buf = 0;\r
181       m_size = 0;\r
182     }\r
183   }\r
184 };\r
185 \r
186 #endif // _ARRAY_H\r