1 /*
2  *  Copyright 2008-2018 NVIDIA Corporation
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16 
17 
18 /*! \file host_vector.h
19  *  \brief A dynamically-sizable array of elements which reside in the "host" memory space
20  */
21 
22 #pragma once
23 
24 #include <thrust/detail/config.h>
25 #include <memory>
26 #include <thrust/detail/vector_base.h>
27 #include <vector>
28 #include <utility>
29 
30 namespace thrust
31 {
32 
33 // forward declaration of device_vector
34 template<typename T, typename Alloc> class device_vector;
35 
36 /*! \addtogroup container_classes Container Classes
37  *  \addtogroup host_containers Host Containers
38  *  \ingroup container_classes
39  *  \{
40  */
41 
42 /*! A \p host_vector is a container that supports random access to elements,
43  *  constant time removal of elements at the end, and linear time insertion
44  *  and removal of elements at the beginning or in the middle. The number of
45  *  elements in a \p host_vector may vary dynamically; memory management is
46  *  automatic. The memory associated with a \p host_vector resides in the memory
47  *  space of the host associated with a parallel device.
48  *
49  *  \see http://www.sgi.com/tech/stl/Vector.html
50  *  \see device_vector
51  */
52 template<typename T, typename Alloc = std::allocator<T> >
53   class host_vector
54     : public detail::vector_base<T,Alloc>
55 {
56   private:
57     typedef detail::vector_base<T,Alloc> Parent;
58 
59   public:
60     /*! \cond
61      */
62     typedef typename Parent::size_type  size_type;
63     typedef typename Parent::value_type value_type;
64     /*! \endcond
65      */
66 
67     /*! This constructor creates an empty \p host_vector.
68      */
69     __host__
host_vector(void)70     host_vector(void)
71       :Parent() {}
72 
73     /*! This constructor creates an empty \p host_vector.
74      *  \param alloc The allocator to use by this vector_base.
75      */
76     __host__
host_vector(const Alloc & alloc)77     host_vector(const Alloc &alloc)
78       :Parent(alloc) {}
79 
80     /*! The destructor erases the elements.
81      */
82     //  Define an empty destructor to explicitly specify
83     //  its execution space qualifier, as a workaround for nvcc warning
84     __host__
~host_vector(void)85     ~host_vector(void) {}
86 
87     /*! This constructor creates a \p host_vector with the given
88      *  size.
89      *  \param n The number of elements to initially create.
90      */
91     __host__
host_vector(size_type n)92     explicit host_vector(size_type n)
93       :Parent(n) {}
94 
95     /*! This constructor creates a \p host_vector with the given
96      *  size.
97      *  \param n The number of elements to initially create.
98      *  \param alloc The allocator to use by this vector_base.
99      */
100     __host__
host_vector(size_type n,const Alloc & alloc)101     explicit host_vector(size_type n, const Alloc &alloc)
102       :Parent(n,alloc) {}
103 
104     /*! This constructor creates a \p host_vector with copies
105      *  of an exemplar element.
106      *  \param n The number of elements to initially create.
107      *  \param value An element to copy.
108      */
109     __host__
host_vector(size_type n,const value_type & value)110     explicit host_vector(size_type n, const value_type &value)
111       :Parent(n,value) {}
112 
113     /*! This constructor creates a \p host_vector with copies
114      *  of an exemplar element.
115      *  \param n The number of elements to initially create.
116      *  \param value An element to copy.
117      *  \param alloc The allocator to use by this vector_base.
118      */
119     __host__
host_vector(size_type n,const value_type & value,const Alloc & alloc)120     explicit host_vector(size_type n, const value_type &value, const Alloc &alloc)
121       :Parent(n,value,alloc) {}
122 
123     /*! Copy constructor copies from an exemplar \p host_vector.
124      *  \param v The \p host_vector to copy.
125      */
126     __host__
host_vector(const host_vector & v)127     host_vector(const host_vector &v)
128       :Parent(v) {}
129 
130     /*! Copy constructor copies from an exemplar \p host_vector.
131      *  \param v The \p host_vector to copy.
132      *  \param alloc The allocator to use by this vector_base.
133      */
134     __host__
host_vector(const host_vector & v,const Alloc & alloc)135     host_vector(const host_vector &v, const Alloc &alloc)
136       :Parent(v,alloc) {}
137 
138   #if __cplusplus >= 201103L
139     /*! Move constructor moves from another host_vector.
140      *  \param v The host_vector to move.
141      */
142      __host__
host_vector(host_vector && v)143     host_vector(host_vector &&v)
144       :Parent(std::move(v)) {}
145 
146     /*! Move constructor moves from another host_vector.
147      *  \param v The host_vector to move.
148      *  \param alloc The allocator to use by this vector_base.
149      */
150      __host__
host_vector(host_vector && v,const Alloc & alloc)151     host_vector(host_vector &&v, const Alloc &alloc)
152       :Parent(std::move(v),alloc) {}
153   #endif
154 
155   /*! Assign operator copies from an exemplar \p host_vector.
156    *  \param v The \p host_vector to copy.
157    */
158   __host__
159   host_vector &operator=(const host_vector &v)
160   { Parent::operator=(v); return *this; }
161 
162   #if __cplusplus >= 201103L
163     /*! Move assign operator moves from another host_vector.
164      *  \param v The host_vector to move.
165      */
166      __host__
167      host_vector &operator=(host_vector &&v)
168      { Parent::operator=(std::move(v)); return *this; }
169   #endif
170 
171     /*! Copy constructor copies from an exemplar \p host_vector with different type.
172      *  \param v The \p host_vector to copy.
173      */
174     template<typename OtherT, typename OtherAlloc>
175     __host__
host_vector(const host_vector<OtherT,OtherAlloc> & v)176     host_vector(const host_vector<OtherT,OtherAlloc> &v)
177       :Parent(v) {}
178 
179     /*! Assign operator copies from an exemplar \p host_vector with different type.
180      *  \param v The \p host_vector to copy.
181      */
182     template<typename OtherT, typename OtherAlloc>
183     __host__
184     host_vector &operator=(const host_vector<OtherT,OtherAlloc> &v)
185     { Parent::operator=(v); return *this; }
186 
187     /*! Copy constructor copies from an exemplar <tt>std::vector</tt>.
188      *  \param v The <tt>std::vector</tt> to copy.
189      */
190     template<typename OtherT, typename OtherAlloc>
191     __host__
host_vector(const std::vector<OtherT,OtherAlloc> & v)192     host_vector(const std::vector<OtherT,OtherAlloc> &v)
193       :Parent(v) {}
194 
195     /*! Assign operator copies from an exemplar <tt>std::vector</tt>.
196      *  \param v The <tt>std::vector</tt> to copy.
197      */
198     template<typename OtherT, typename OtherAlloc>
199     __host__
200     host_vector &operator=(const std::vector<OtherT,OtherAlloc> &v)
201     { Parent::operator=(v); return *this;}
202 
203     /*! Copy constructor copies from an exemplar \p device_vector with possibly different type.
204      *  \param v The \p device_vector to copy.
205      */
206     template<typename OtherT, typename OtherAlloc>
207     __host__
208     host_vector(const device_vector<OtherT,OtherAlloc> &v);
209 
210     /*! Assign operator copies from an exemplar \p device_vector.
211      *  \param v The \p device_vector to copy.
212      */
213     template<typename OtherT, typename OtherAlloc>
214     __host__
215     host_vector &operator=(const device_vector<OtherT,OtherAlloc> &v)
216     { Parent::operator=(v); return *this; }
217 
218     /*! This constructor builds a \p host_vector from a range.
219      *  \param first The beginning of the range.
220      *  \param last The end of the range.
221      */
222     template<typename InputIterator>
223     __host__
host_vector(InputIterator first,InputIterator last)224     host_vector(InputIterator first, InputIterator last)
225       :Parent(first, last) {}
226 
227     /*! This constructor builds a \p host_vector from a range.
228      *  \param first The beginning of the range.
229      *  \param last The end of the range.
230      *  \param alloc The allocator to use by this vector_base.
231      */
232     template<typename InputIterator>
233     __host__
host_vector(InputIterator first,InputIterator last,const Alloc & alloc)234     host_vector(InputIterator first, InputIterator last, const Alloc &alloc)
235       :Parent(first, last, alloc) {}
236 
237 // declare these members for the purpose of Doxygenating them
238 // they actually exist in a derived-from class
239 #if 0
240     /*! \brief Resizes this vector to the specified number of elements.
241      *  \param new_size Number of elements this vector should contain.
242      *  \param x Data with which new elements should be populated.
243      *  \throw std::length_error If n exceeds max_size().
244      *
245      *  This method will resize this vector to the specified number of
246      *  elements.  If the number is smaller than this vector's current
247      *  size this vector is truncated, otherwise this vector is
248      *  extended and new elements are populated with given data.
249      */
250     void resize(size_type new_size, const value_type &x = value_type());
251 
252     /*! Returns the number of elements in this vector.
253      */
254     size_type size(void) const;
255 
256     /*! Returns the size() of the largest possible vector.
257      *  \return The largest possible return value of size().
258      */
259     size_type max_size(void) const;
260 
261     /*! \brief If n is less than or equal to capacity(), this call has no effect.
262      *         Otherwise, this method is a request for allocation of additional memory. If
263      *         the request is successful, then capacity() is greater than or equal to
264      *         n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
265      *  \throw std::length_error If n exceeds max_size().
266      */
267     void reserve(size_type n);
268 
269     /*! Returns the number of elements which have been reserved in this
270      *  vector.
271      */
272     size_type capacity(void) const;
273 
274     /*! This method shrinks the capacity of this vector to exactly
275      *  fit its elements.
276      */
277     void shrink_to_fit(void);
278 
279     /*! \brief Subscript access to the data contained in this vector_dev.
280      *  \param n The index of the element for which data should be accessed.
281      *  \return Read/write reference to data.
282      *
283      *  This operator allows for easy, array-style, data access.
284      *  Note that data access with this operator is unchecked and
285      *  out_of_range lookups are not defined.
286      */
287     reference operator[](size_type n);
288 
289     /*! \brief Subscript read access to the data contained in this vector_dev.
290      *  \param n The index of the element for which data should be accessed.
291      *  \return Read reference to data.
292      *
293      *  This operator allows for easy, array-style, data access.
294      *  Note that data access with this operator is unchecked and
295      *  out_of_range lookups are not defined.
296      */
297     const_reference operator[](size_type n) const;
298 
299     /*! This method returns an iterator pointing to the beginning of
300      *  this vector.
301      *  \return mStart
302      */
303     iterator begin(void);
304 
305     /*! This method returns a const_iterator pointing to the beginning
306      *  of this vector.
307      *  \return mStart
308      */
309     const_iterator begin(void) const;
310 
311     /*! This method returns a const_iterator pointing to the beginning
312      *  of this vector.
313      *  \return mStart
314      */
315     const_iterator cbegin(void) const;
316 
317     /*! This method returns a reverse_iterator pointing to the beginning of
318      *  this vector's reversed sequence.
319      *  \return A reverse_iterator pointing to the beginning of this
320      *          vector's reversed sequence.
321      */
322     reverse_iterator rbegin(void);
323 
324     /*! This method returns a const_reverse_iterator pointing to the beginning of
325      *  this vector's reversed sequence.
326      *  \return A const_reverse_iterator pointing to the beginning of this
327      *          vector's reversed sequence.
328      */
329     const_reverse_iterator rbegin(void) const;
330 
331     /*! This method returns a const_reverse_iterator pointing to the beginning of
332      *  this vector's reversed sequence.
333      *  \return A const_reverse_iterator pointing to the beginning of this
334      *          vector's reversed sequence.
335      */
336     const_reverse_iterator crbegin(void) const;
337 
338     /*! This method returns an iterator pointing to one element past the
339      *  last of this vector.
340      *  \return begin() + size().
341      */
342     iterator end(void);
343 
344     /*! This method returns a const_iterator pointing to one element past the
345      *  last of this vector.
346      *  \return begin() + size().
347      */
348     const_iterator end(void) const;
349 
350     /*! This method returns a const_iterator pointing to one element past the
351      *  last of this vector.
352      *  \return begin() + size().
353      */
354     const_iterator cend(void) const;
355 
356     /*! This method returns a reverse_iterator pointing to one element past the
357      *  last of this vector's reversed sequence.
358      *  \return rbegin() + size().
359      */
360     reverse_iterator rend(void);
361 
362     /*! This method returns a const_reverse_iterator pointing to one element past the
363      *  last of this vector's reversed sequence.
364      *  \return rbegin() + size().
365      */
366     const_reverse_iterator rend(void) const;
367 
368     /*! This method returns a const_reverse_iterator pointing to one element past the
369      *  last of this vector's reversed sequence.
370      *  \return rbegin() + size().
371      */
372     const_reverse_iterator crend(void) const;
373 
374     /*! This method returns a const_reference referring to the first element of this
375      *  vector.
376      *  \return The first element of this vector.
377      */
378     const_reference front(void) const;
379 
380     /*! This method returns a reference pointing to the first element of this
381      *  vector.
382      *  \return The first element of this vector.
383      */
384     reference front(void);
385 
386     /*! This method returns a const reference pointing to the last element of
387      *  this vector.
388      *  \return The last element of this vector.
389      */
390     const_reference back(void) const;
391 
392     /*! This method returns a reference referring to the last element of
393      *  this vector_dev.
394      *  \return The last element of this vector.
395      */
396     reference back(void);
397 
398     /*! This method returns a pointer to this vector's first element.
399      *  \return A pointer to the first element of this vector.
400      */
401     pointer data(void);
402 
403     /*! This method returns a const_pointer to this vector's first element.
404      *  \return a const_pointer to the first element of this vector.
405      */
406     const_pointer data(void) const;
407 
408     /*! This method resizes this vector to 0.
409      */
410     void clear(void);
411 
412     /*! This method returns true iff size() == 0.
413      *  \return true if size() == 0; false, otherwise.
414      */
415     bool empty(void) const;
416 
417     /*! This method appends the given element to the end of this vector.
418      *  \param x The element to append.
419      */
420     void push_back(const value_type &x);
421 
422     /*! This method erases the last element of this vector, invalidating
423      *  all iterators and references to it.
424      */
425     void pop_back(void);
426 
427     /*! This method swaps the contents of this vector_base with another vector.
428      *  \param v The vector with which to swap.
429      */
430     void swap(host_vector &v);
431 
432     /*! This method removes the element at position pos.
433      *  \param pos The position of the element of interest.
434      *  \return An iterator pointing to the new location of the element that followed the element
435      *          at position pos.
436      */
437     iterator erase(iterator pos);
438 
439     /*! This method removes the range of elements [first,last) from this vector.
440      *  \param first The beginning of the range of elements to remove.
441      *  \param last The end of the range of elements to remove.
442      *  \return An iterator pointing to the new location of the element that followed the last
443      *          element in the sequence [first,last).
444      */
445     iterator erase(iterator first, iterator last);
446 
447     /*! This method inserts a single copy of a given exemplar value at the
448      *  specified position in this vector.
449      *  \param position The insertion position.
450      *  \param x The exemplar element to copy & insert.
451      *  \return An iterator pointing to the newly inserted element.
452      */
453     iterator insert(iterator position, const T &x);
454 
455     /*! This method inserts a copy of an exemplar value to a range at the
456      *  specified position in this vector.
457      *  \param position The insertion position
458      *  \param n The number of insertions to perform.
459      *  \param x The value to replicate and insert.
460      */
461     void insert(iterator position, size_type n, const T &x);
462 
463     /*! This method inserts a copy of an input range at the specified position
464      *  in this vector.
465      *  \param position The insertion position.
466      *  \param first The beginning of the range to copy.
467      *  \param last  The end of the range to copy.
468      *
469      *  \tparam InputIterator is a model of <a href="http://www.sgi.com/tech/stl/InputIterator.html>Input Iterator</a>,
470      *                        and \p InputIterator's \c value_type is a model of <a href="http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>.
471      */
472     template<typename InputIterator>
473     void insert(iterator position, InputIterator first, InputIterator last);
474 
475     /*! This version of \p assign replicates a given exemplar
476      *  \p n times into this vector.
477      *  \param n The number of times to copy \p x.
478      *  \param x The exemplar element to replicate.
479      */
480     void assign(size_type n, const T &x);
481 
482     /*! This version of \p assign makes this vector a copy of a given input range.
483      *  \param first The beginning of the range to copy.
484      *  \param last  The end of the range to copy.
485      *
486      *  \tparam InputIterator is a model of <a href="http://www.sgi.com/tech/stl/InputIterator">Input Iterator</a>.
487      */
488     template<typename InputIterator>
489     void assign(InputIterator first, InputIterator last);
490 
491     /*! This method returns a copy of this vector's allocator.
492      *  \return A copy of the alloctor used by this vector.
493      */
494     allocator_type get_allocator(void) const;
495 #endif // end doxygen-only members
496 }; // end host_vector
497 
498 template<typename T, typename Alloc>
swap(host_vector<T,Alloc> & a,host_vector<T,Alloc> & b)499   void swap(host_vector<T,Alloc> &a, host_vector<T,Alloc> &b)
500 {
501   a.swap(b);
502 } // end swap()
503 
504 /*! \}
505  */
506 
507 } // end thrust
508 
509 #include <thrust/detail/host_vector.inl>
510 
511