iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DynamicArray.H
Go to the documentation of this file.
1 /*! @file
2  @author Shane Grant
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 
36 #ifndef INCLUDE_NRT_CORE_MEMORY_DYNAMICARRAY_H
37 #define INCLUDE_NRT_CORE_MEMORY_DYNAMICARRAY_H
38 
39 #include <vector>
40 #include <memory>
41 #include <nrt/External/cereal/types/memory.hpp>
42 
43 namespace nrt
44 {
45  //! A dynamic-length version of the Array class
46  /*! The data held by this DynamicArray is held by a copy-on-write policy, so that assignments are extremely fast -
47  costing essentialy a pointer assignment and integer increment. Inspecting elements is also fast, so long as it is
48  done through a constant access method. Access through a non const method may cause a deep copy of the underlying
49  data if there are multiple references to it. Therefore, users should strive to use the const methods whenever
50  possible.
51 
52  @tparam T The underlying type to hold
53  @tparam Allocator The allocator to use for type T
54 
55  \ingroup arrays */
56  template <class T, class Allocator = std::allocator<T>>
58  {
59  typedef std::vector<T, Allocator> VectorType;
60 
61  public:
62  typedef typename VectorType::value_type value_type;
63 
64  //! Default empty constructor
65  DynamicArray();
66 
67  //! Construct a DynamicArray of a specific size, filling it with the default value for T
68  explicit DynamicArray( size_t size );
69 
70  //! Construct a DynamicArray of a specific size, and fill it with a value
71  explicit DynamicArray( size_t size, T value );
72 
73  //! Construct a DynamicArray from some range of existing elements
74  template <class InputIt>
75  DynamicArray( InputIt first, InputIt last );
76 
77  //! Copy constructor
78  /*! This constructor performs a shallow copy, meaning that no deep-copy is performed and instead we simply
79  increment reference counts */
80  DynamicArray( DynamicArray const & other );
81 
82  //! Move constructor
83  /*! Constructs a new DynamicArray, invalidating the older DynamicArray.
84  The other array used to construct this should no longer be used; using it
85  will result in undefined behavior. */
86  DynamicArray( DynamicArray && other );
87 
88  //! Construct from an initializer list
89  DynamicArray( std::initializer_list<T> vals );
90 
91  //! Destructor
92  /*! Decrements ref count and deletes data if we are the only owner */
93  ~DynamicArray();
94 
95  //! Assignment operator
97 
98  //! Move Assignment operator
99  /*! The array move assigned to this one will become invalid after this operation;
100  any use of an invalid array will result in undefined behavior */
102 
103  //! @name Element Access
104  /*! Functions providing access to individual elements. Non const access will
105  incur a deep copy if not the sole owner of the data. */
106  //! @{
107 
108  //! Individual element access - may incur a deep copy
109  T & operator[]( size_t index );
110 
111  //! Individual element access
112  T const & operator[]( size_t index ) const;
113 
114  //! Constant access method
115  T const & at( size_t index ) const;
116 
117  //! Gets a reference to the front element - may incur a deep copy
118  T & front();
119 
120  //! Gets a constant reference to the front element
121  T const & front() const;
122 
123  //! Gets a reference to the back element - may incur a deep copy
124  T & back();
125 
126  //! Gets a constant reference to the back element
127  T const & back() const;
128 
129  //! Gets a pointer to the underlying data - may incur a deep copy
130  T * data();
131 
132  //! Gets a pointer to the constant underlying data
133  T const * data() const;
134 
135  //! @}
136 
137  //! @name Iterators
138  /*! Provides iterator level access to elements */
139  //! @{
140 
141  //! The type for an iterator
142  typedef typename VectorType::iterator iterator;
143  //! The type for a constant iterator
144  typedef typename VectorType::const_iterator const_iterator;
145  //! The type for a reverse iterator
146  typedef typename VectorType::reverse_iterator reverse_iterator;
147  //! The type for a constant reverse iterator
148  typedef typename VectorType::const_reverse_iterator const_reverse_iterator;
149 
150  //! Gets an iterator to the beginning of data - may incur a deep copy
151  iterator begin();
152 
153  //! Gets a constant iterator to the beginning of data
154  const_iterator begin() const;
155 
156  //! Gets a constant iterator to the beginning of data
157  const_iterator const_begin() const;
158 
159  //! Gets an iterator to the end of data - may incur a deep copy
160  iterator end();
161 
162  //! Gets a constant iterator to the end of data
163  const_iterator end() const;
164 
165  //! Gets a constant iterator to the end of data
166  const_iterator const_end() const;
167 
168  //! Get a reverse iterator to the beginning
170 
171  //! Get a reverse iterator to the beginning
173 
174  //! Get a reverse iterator to the beginning
176 
177  //! Get a reverse iterator to the end
179 
180  //! Get a reverse iterator to the end
182 
183  //! Get a reverse iterator to the end
185 
186  //! @}
187  //! @name Capacity
188  /*! Functionality for querying and adjusting capacity */
189  //! @{
190 
191  //! Checks whether the array is empty
192  bool empty() const;
193 
194  //! Returns the current number of elements stored
195  size_t size() const;
196 
197  //! Requests the capacity of the underlying storage to be at least enough to store n elements
198  void reserve( size_t n );
199 
200  //! Returns the number of elements that can be held in currently allocated storage
201  size_t capacity() const;
202 
203  //! Shrinks memory usage by freeing unused memory
204  void shrink_to_fit();
205 
206  //! @}
207  //! @name Modifiers
208  /*! Functionality for modifying the data inside of the array */
209  //! @{
210 
211  //! Clears all data associated with this array
212  void clear();
213 
214  //! Insert immediately before some iterator position
215  iterator insert( iterator pos, T const & data );
216 
217  //! Insert immediately before some iterator position
218  iterator insert( const_iterator pos, T const & data );
219 
220  //! Insert immediately before some iterator position
221  iterator insert( const_iterator pos, T && data );
222 
223  //! Insert count copies of data immediately before some iterator position
224  void insert( iterator pos, size_t count, T const & data );
225 
226  //! Insert count copies of data immediately before some iterator position
227  iterator insert( const_iterator pos, size_t count, T const & data );
228 
229  //! Insert all values in the iterator range before some iterator position
230  template <class InputIt>
231  void insert( iterator pos, InputIt first, InputIt last );
232 
233  //! Insert all values in the iterator range before some iterator position
234  template <class InputIt>
235  iterator insert( const_iterator pos, InputIt first, InputIt last );
236 
237  //! Insert the values of some initializer list before some iterator position
238  iterator insert( const_iterator pos, std::initializer_list<T> ilist );
239 
240  //! Inserts a new element into the container directly before pos, constructing in place
241  template <class ... Args >
242  iterator emplace( const_iterator pos, Args && ... args );
243 
244  //! Remove an element at a position
245  iterator erase( iterator pos );
246 
247  //! Remove an element at a position
249 
250  //! Remove a range of elements
251  iterator erase( iterator first, iterator last );
252 
253  //! Remove a range of elements
255 
256  //! Adds a new element to the back of the array
257  void push_back( T const & data );
258 
259  //! Adds a new element to the back of the array
260  void push_back( T && data );
261 
262  //! Construct a new element in place at the back of the array
263  template <class ... Args>
264  void emplace_back( Args && ... args );
265 
266  //! Removes the tail element in the array
267  void pop_back();
268 
269  //! Removes the item at the selected index (O(n) operation)
270  /*! @deprecated - use erase instead */
271  void remove( size_t index );
272 
273  //! Remoes the item at the selected index (O(1), does not guarantee preserving ordering )
274  void quickRemove( size_t index );
275 
276  //! Resizes the underlying storage to be exactly n elements, dropping anything > n
277  void resize( size_t n );
278  //! @}
279 
280  //! Concatenate another array with this one
282 
283  //! Concatenate two arrays together
285 
286  //! Performs a deep copy of the underlying data if not a unique owner
287  void deepCopy();
288 
289  private:
290  // forward decl for internal storage
291  class Memory;
292 
293  //! The actual data stored
294  std::shared_ptr<Memory> itsMemory;
295 
296  friend class cereal::access;
297  template <class Archive>
298  void serialize( Archive & ar )
299  {
300  ar( itsMemory );
301  }
302  }; //class DynamicArray
303 } // namespace nrt
304 
305 //! If you #define NRT_DYNAMICARRAY_DEEPCOPY_THROWS then an exception gets thrown after each call to deepCopy()
306 /*! The deepCopy() will still occur as planned, just you will need to catch the exception if you don't want your
307  program to crash. This can be used to debug cases when a deepCopy() should or should not occur. */
308 #ifdef NRT_DYNAMICARRAY_DEEPCOPY_THROWS
309 namespace nrt
310 {
311  namespace exception
312  {
313  //! An exception to indicate that a deep copy occurred in DynamicArray
314  /*! you need to #define NRT_DYNAMICARRAY_DEEPCOPY_THROWS for this execption to get thrown. Use only for debugging
315  and optimizing. See example in \link test-ImageCopy.C \endlink
316  \relates DynamicArray */
317  template <class T, class Allocator>
318  class DynamicArrayDeepCopyException : public Exception
319  {
320  public:
321  DynamicArrayDeepCopyException( nrt::DynamicArray<T, Allocator> const * dynArr );
322  virtual ~DynamicArrayDeepCopyException() throw();
323  virtual char const * what() const throw();
324 
325  private:
326  std::string const itsWhat;
327  };
328  } // namespace exception
329 } // namespace nrt
330 #endif // NRT_DYNAMICARRAY_DEEPCOPY_THROWS
331 
333 
334 #endif // NRT_POINTCLOUD_CORE_DYNAMICARRAY_H_