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