1 // templated sized array class
2 // Copyright (C) 2009 Tim Blechmann
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; see the file COPYING. If not, write to
16 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 // Boston, MA 02111-1307, USA.
19 #ifndef UTILITIES_SIZED_ARRAY_HPP
20 #define UTILITIES_SIZED_ARRAY_HPP
23 #include <memory> /* std::allocator */
27 #include <boost/mpl/if.hpp>
28 #include <boost/type_traits/is_integral.hpp>
29 #include <boost/move/move.hpp>
34 /** dynamically sized array
36 * array class, inspired by boost.array, where the size is specified
37 * during the time of the construction.
38 * in contrary to std::vector, it is guaranteed to use continuous
39 * memory. the memory is allocated in the constructor an freed in the
40 * destructor, these are the only places, where the allocator
41 * functions are called.
45 class Alloc
= std::allocator
<T
> >
47 private Alloc::template rebind
<T
>::other
49 typedef typename
Alloc::template rebind
<T
>::other Allocator
;
51 BOOST_MOVABLE_BUT_NOT_COPYABLE(sized_array
)
57 typedef const T
* const_iterator
;
58 typedef std::reverse_iterator
<iterator
> reverse_iterator
;
59 typedef std::reverse_iterator
<const_iterator
> const_reverse_iterator
;
61 typedef const T
& const_reference
;
62 typedef std::size_t size_type
;
63 typedef std::ptrdiff_t difference_type
;
65 // construct/copy/destruct
66 explicit sized_array(size_type size
= 0, T
const & def
= T()):
67 data_(Allocator::allocate(size
)), size_(size
)
69 for (size_type i
= 0; i
!= size
; ++i
)
70 Allocator::construct(data_
+ i
, def
);
74 template <typename int_type
>
75 void init_from_int(int_type size
)
77 data_
= Allocator::allocate(size
);
79 for (size_type i
= 0; i
!= size_
; ++i
)
80 Alloc::construct(data_
+ i
, T());
83 template <typename Container
>
84 void init_from_container(Container
const & container
)
86 data_
= Allocator::allocate(container
.size());
87 size_
= container
.size();
90 typedef typename
Container::const_iterator iterator
;
91 for (iterator it
= container
.begin(); it
!= container
.end(); ++it
)
92 Allocator::construct(data_
+ index
++, *it
);
93 assert(index
== size());
98 template <typename int_type
>
99 static void init(sized_array
& array
, int_type
const & i
)
101 array
.init_from_int
<int_type
>(i
);
105 struct call_container_ctor
107 template <typename Container
>
108 static void init(sized_array
& array
, Container
const & c
)
110 array
.init_from_container
<Container
>(c
);
115 template<typename Constructor_arg
>
116 explicit sized_array(Constructor_arg
const & arg
)
118 typedef typename
boost::mpl::if_
<boost::is_integral
<Constructor_arg
>,
120 call_container_ctor
>::type ctor
;
121 ctor::init(*this, arg
);
124 #ifdef BOOST_HAS_RVALUE_REFS
125 explicit sized_array(sized_array
&& arg
)
133 /** move assignment */
134 sized_array
& operator=(sized_array
&& arg
)
143 explicit sized_array(BOOST_RV_REF(sized_array
) arg
)
148 /** move assignment */
149 sized_array
& operator=(BOOST_RV_REF(sized_array
) arg
)
161 for (size_type i
= 0; i
!= size(); ++i
)
162 Allocator::destroy(data_
+ i
);
164 Allocator::deallocate(data_
, size());
173 const_iterator
begin() const
180 return data_
+ size();
183 const_iterator
end() const
185 return data_
+ size();
188 // reverse iterator support
189 reverse_iterator
rbegin()
191 return reverse_iterator(data_
+ size());
194 const_reverse_iterator
rbegin() const
196 return const_reverse_iterator(data_
+ size());
199 reverse_iterator
rend()
201 return reverse_iterator(data_
);
204 const_reverse_iterator
rend() const
206 return const_reverse_iterator(data_
);
210 size_type
size() const
220 size_type
max_size() const
226 reference
operator[](size_type i
)
231 const_reference
operator[](size_type i
) const
236 reference
at(size_type i
)
241 const_reference
at(size_type i
) const
251 const_reference
front() const
258 return data_
[size_
- 1];
261 const_reference
back() const
263 return data_
[size_
- 1];
266 const T
* data() const
277 void assign(const T
& t
)
279 for (size_type i
= 0; i
!= size_
; ++i
)
283 void resize(size_type new_size
, T
const & t
= T())
285 T
* new_data
= Allocator::allocate(new_size
);
287 for (size_type i
= 0; i
!= new_size
; ++i
)
288 Allocator::construct(new_data
+i
, t
);
290 std::copy(data_
, data_
+std::min(new_size
, size_
), new_data
);
292 T
* old_data
= data_
;
294 for (size_type i
= 0; i
!= size_
; ++i
)
295 Allocator::destroy(old_data
+i
);
297 Allocator::deallocate(old_data
, size_
);
306 } /* namespace nova */
308 #endif /* UTILITIES_SIZED_ARRAY_HPP */