version bump cml to version 1.0.2
[chaz/yoink] / src / Moof / cml / core / dynamic_1D.h
1 /* -*- C++ -*- ------------------------------------------------------------
2
3 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
4
5 The Configurable Math Library (CML) is distributed under the terms of the
6 Boost Software License, v1.0 (see cml/LICENSE for details).
7
8 *-----------------------------------------------------------------------*/
9 /** @file
10 * @brief
11 */
12
13 #ifndef dynamic_1D_h
14 #define dynamic_1D_h
15
16 #include <memory>
17 #include <cml/core/common.h>
18 #include <cml/dynamic.h>
19
20 namespace cml {
21
22 /** Dynamically-sized and allocated 1D array.
23 *
24 * @note The allocator should be an STL-compatible allocator.
25 *
26 * @internal The internal array type <em>must</em> have the proper copy
27 * semantics, otherwise copy construction will fail.
28 */
29 template<typename Element, class Alloc>
30 class dynamic_1D
31 {
32 public:
33
34 /* Record the allocator type: */
35 typedef typename Alloc::template rebind<Element>::other allocator_type;
36
37 /* Record the generator: */
38 typedef dynamic<Alloc> generator_type;
39
40 /* Standard: */
41 typedef typename allocator_type::value_type value_type;
42 typedef typename allocator_type::pointer pointer;
43 typedef typename allocator_type::reference reference;
44 typedef typename allocator_type::const_reference const_reference;
45 typedef typename allocator_type::const_pointer const_pointer;
46
47 /* For matching by memory type: */
48 typedef dynamic_memory_tag memory_tag;
49
50 /* For matching by size type: */
51 typedef dynamic_size_tag size_tag;
52
53 /* For matching by resizability: */
54 typedef resizable_tag resizing_tag;
55
56 /* For matching by dimensions: */
57 typedef oned_tag dimension_tag;
58
59
60 public:
61
62 /** Dynamic arrays have no fixed size. */
63 enum { array_size = -1 };
64
65
66 public:
67
68 /** Construct a dynamic array with no size. */
69 dynamic_1D() : m_size(0), m_data(0), m_alloc() {}
70
71 /** Construct a dynamic array given the size. */
72 explicit dynamic_1D(size_t size) : m_size(0), m_data(0), m_alloc() {
73 this->resize(size);
74 }
75
76 /** Copy construct a dynamic array. */
77 dynamic_1D(const dynamic_1D& other)
78 : m_size(0), m_data(0), m_alloc()
79 {
80 this->copy(other);
81 }
82
83 ~dynamic_1D() {
84 this->destroy();
85 }
86
87
88 public:
89
90 /** Return the number of elements in the array. */
91 size_t size() const { return m_size; }
92
93 /** Access to the data as a C array.
94 *
95 * @param i a size_t index into the array.
96 * @return a mutable reference to the array value at i.
97 *
98 * @note This function does not range-check the argument.
99 */
100 reference operator[](size_t i) { return m_data[i]; }
101
102 /** Const access to the data as a C array.
103 *
104 * @param i a size_t index into the array.
105 * @return a const reference to the array value at i.
106 *
107 * @note This function does not range-check the argument.
108 */
109 const_reference operator[](size_t i) const { return m_data[i]; }
110
111 /** Return access to the data as a raw pointer. */
112 pointer data() { return &m_data[0]; }
113
114 /** Return access to the data as a raw pointer. */
115 const_pointer data() const { return &m_data[0]; }
116
117
118 public:
119
120 /** Set the array size to the given value. The previous contents are
121 * destroyed before reallocating the array. If s == size(),
122 * nothing happens.
123 *
124 * @warning This is not guaranteed to preserve the original data.
125 */
126 void resize(size_t s) {
127
128 /* Nothing to do if the size isn't changing: */
129 if(s == m_size) return;
130
131 /* Destroy the current array contents: */
132 this->destroy();
133
134 /* Set the new size if non-zero: */
135 if(s > 0) {
136 value_type* data = m_alloc.allocate(s);
137 for(size_t i = 0; i < s; ++ i)
138 m_alloc.construct(&data[i], value_type());
139
140 /* Success, save s and data: */
141 m_size = s;
142 m_data = data;
143 }
144 }
145
146 /** Copy the source array. The previous contents are destroyed before
147 * reallocating the array. If other == *this, nothing happens.
148 */
149 void copy(const dynamic_1D& other) {
150
151 /* Nothing to do if it's the same array: */
152 if(&other == this) return;
153
154 /* Destroy the current array contents: */
155 this->destroy();
156
157 /* Set the new size if non-zero: */
158 size_t s = other.size();
159 if(s > 0) {
160 value_type* data = m_alloc.allocate(s);
161 for(size_t i = 0; i < s; ++ i)
162 m_alloc.construct(&data[i], other[i]);
163
164 /* Success, so save the new array and the size: */
165 m_size = s;
166 m_data = data;
167 }
168 }
169
170
171 protected:
172
173 /** Destroy the current contents of the array. */
174 void destroy() {
175 if(m_data) {
176 for(size_t i = 0; i < m_size; ++ i)
177 m_alloc.destroy(&m_data[i]);
178 m_alloc.deallocate(m_data, m_size);
179 m_size = 0;
180 m_data = 0;
181 }
182 }
183
184
185 protected:
186
187 /** Current array size (may be 0). */
188 size_t m_size;
189
190 /** Array data (may be NULL). */
191 value_type* m_data;
192
193 /** Allocator for the array. */
194 allocator_type m_alloc;
195 };
196
197 } // namespace cml
198
199 #endif
200
201 // -------------------------------------------------------------------------
202 // vim:ft=cpp
This page took 0.037439 seconds and 4 git commands to generate.