| 1 | /* |
| 2 | * map_vector_std.hpp |
| 3 | * |
| 4 | * Created on: Mar 8, 2015 |
| 5 | * Author: i-bird |
| 6 | */ |
| 7 | |
| 8 | #ifndef MAP_VECTOR_STD_HPP_ |
| 9 | #define MAP_VECTOR_STD_HPP_ |
| 10 | |
| 11 | #include "se_vector.hpp" |
| 12 | #include "map_vector_std_ptr.hpp" |
| 13 | |
| 14 | #define OBJECT_ADD false |
| 15 | #define VECTOR_ADD true |
| 16 | |
| 17 | //! struct to merge two vectors |
| 18 | template<bool objv, typename vect_dst> |
| 19 | struct add_prp_impl |
| 20 | { |
| 21 | /*! \brief It add the element of a source vector to this vector |
| 22 | * |
| 23 | * The number of properties in the source vector must be smaller than the destination |
| 24 | * all the properties of S must be mapped so if S has 3 properties |
| 25 | * 3 numbers for args are required |
| 26 | * |
| 27 | * \tparam S Base object of the source vector |
| 28 | * \tparam M memory type of the source vector |
| 29 | * \tparam gp Grow policy of the source vector |
| 30 | * \tparam args one or more number that define which property to set-up |
| 31 | * |
| 32 | * \param v_src source vector |
| 33 | * \param v_dst destination vector |
| 34 | * |
| 35 | */ |
| 36 | template <typename S, typename M, typename gp, unsigned int impl, unsigned int ...args> |
| 37 | inline static void add(const vector<S,M,memory_traits_lin,gp,impl> & v_src, vect_dst & v_dst) |
| 38 | { |
| 39 | //! Add the element of v |
| 40 | for (size_t i = 0 ; i < v_src.size() ; i++) |
| 41 | { |
| 42 | // Add a new element |
| 43 | v_dst.add(); |
| 44 | |
| 45 | // equal object |
| 46 | v_dst.get(v_dst.size()-1) = v_src.get(i); |
| 47 | } |
| 48 | } |
| 49 | }; |
| 50 | |
| 51 | //! struct to merge two vectors |
| 52 | template<typename vect_dst> |
| 53 | struct add_prp_impl<OBJECT_ADD,vect_dst> |
| 54 | { |
| 55 | /*! \brief It add the element of a source vector to a destination vector |
| 56 | * |
| 57 | * The number of properties in the source vector must be smaller than the destination |
| 58 | * all the properties of S must be mapped so if S has 3 properties |
| 59 | * 3 numbers for args are required |
| 60 | * |
| 61 | * \tparam S Base object of the source vector |
| 62 | * \tparam M memory type of the source vector |
| 63 | * \tparam gp Grow policy of the source vector |
| 64 | * \tparam args one or more number that define which property to set-up |
| 65 | * |
| 66 | * \param v_src vector to merge |
| 67 | * \param v_dst vector to merge and result of the merge |
| 68 | * |
| 69 | */ |
| 70 | template <typename S, typename M, typename gp, unsigned int impl, unsigned int ...args> inline static void add(const vector<S,M,memory_traits_lin,gp,impl> & v_src, vect_dst & v_dst) |
| 71 | { |
| 72 | // Add a new element |
| 73 | v_dst.add(); |
| 74 | |
| 75 | // equal object |
| 76 | v_dst.get(v_dst.size()-1) = v_src; |
| 77 | } |
| 78 | }; |
| 79 | |
| 80 | |
| 81 | /*! \brief Implementation of 1-D std::vector like structure |
| 82 | * |
| 83 | * this implementation is just a wrapper for the std::vector in the case |
| 84 | * of data where the members cannot be parsed see openFPM_data wiki for more information |
| 85 | * |
| 86 | * ### Create add and access the elements |
| 87 | * \snippet vector_test_util.hpp Create add and access stl |
| 88 | * |
| 89 | * \param T base type |
| 90 | * |
| 91 | */ |
| 92 | template<typename T, typename grow_p> |
| 93 | class vector<T,HeapMemory,memory_traits_lin,grow_p,STD_VECTOR> |
| 94 | { |
| 95 | // Memory layout |
| 96 | typedef typename memory_traits_lin<T>::type layout; |
| 97 | // Doeas not work on gcc 4.8.4 |
| 98 | // template <typename lb> using layout_base = memory_traits_lin<lb>; |
| 99 | |
| 100 | //! 1-D static grid |
| 101 | std::vector<T> base; |
| 102 | |
| 103 | //! Error code |
| 104 | size_t err_code = 0; |
| 105 | |
| 106 | public: |
| 107 | |
| 108 | //! it define that it is a vector |
| 109 | typedef int yes_i_am_vector; |
| 110 | |
| 111 | typedef memory_traits_lin<T> layout_base_; |
| 112 | |
| 113 | //! iterator for the vector |
| 114 | typedef vector_key_iterator iterator_key; |
| 115 | //! Type of the value the vector is storing |
| 116 | typedef T value_type; |
| 117 | |
| 118 | typedef void base_to_copy; |
| 119 | |
| 120 | //! growing policy of this vector |
| 121 | typedef grow_policy_double grow_policy; |
| 122 | |
| 123 | template<typename Tobj> |
| 124 | struct layout_base__ |
| 125 | { |
| 126 | typedef memory_traits_lin<Tobj> type; |
| 127 | }; |
| 128 | |
| 129 | //This file implements a pack and unpack for std vector |
| 130 | #include "vector_std_pack_unpack.ipp" |
| 131 | |
| 132 | //! return the size of the vector |
| 133 | inline size_t size() const |
| 134 | { |
| 135 | return base.size(); |
| 136 | } |
| 137 | |
| 138 | |
| 139 | /*! \ brief Resize the vector to contain n elements |
| 140 | * |
| 141 | * \param slot number of elements |
| 142 | * |
| 143 | */ |
| 144 | inline void resize(size_t slot) |
| 145 | { |
| 146 | base.resize(slot); |
| 147 | } |
| 148 | |
| 149 | /*! \brief Remove all the element from the vector |
| 150 | * |
| 151 | */ |
| 152 | inline void clear() |
| 153 | { |
| 154 | base.clear(); |
| 155 | } |
| 156 | |
| 157 | /*! \brief Fit the memory to the size of the vector |
| 158 | * |
| 159 | */ |
| 160 | inline void shrink_to_fit() |
| 161 | { |
| 162 | base.shrink_to_fit(); |
| 163 | } |
| 164 | |
| 165 | /*! \brief It insert a new object on the vector, eventually it reallocate the grid |
| 166 | * |
| 167 | * \param v element to add |
| 168 | * |
| 169 | * \warning It is not thread safe should not be used in multi-thread environment |
| 170 | * reallocation, work only on cpu |
| 171 | * |
| 172 | *vector_isel<T>::value |
| 173 | */ |
| 174 | inline void add(const T & v) |
| 175 | { |
| 176 | if (std::is_same<grow_p,openfpm::grow_policy_identity>::value == true) |
| 177 | { |
| 178 | // we reserve just one space more to avoid the capacity to increase by two |
| 179 | base.reserve(base.size()+1); |
| 180 | } |
| 181 | |
| 182 | base.push_back(v); |
| 183 | } |
| 184 | |
| 185 | /*! \brief It insert a new object on the vector, eventually it reallocate the grid |
| 186 | * |
| 187 | * \param v element to add |
| 188 | * |
| 189 | * \warning It is not thread safe should not be used in multi-thread environment |
| 190 | * reallocation, work only on cpu |
| 191 | * |
| 192 | *vector_isel<T>::value |
| 193 | */ |
| 194 | inline void add(T && v) |
| 195 | { |
| 196 | if (std::is_same<grow_p,openfpm::grow_policy_identity>::value == true) |
| 197 | { |
| 198 | // we reserve just one space more to avoid the capacity to increase by two |
| 199 | base.reserve(base.size()+1); |
| 200 | } |
| 201 | |
| 202 | base.emplace_back(v); |
| 203 | } |
| 204 | |
| 205 | /*! \brief Add an empty object (it call the default constructor () ) at the end of the vector |
| 206 | * |
| 207 | */ |
| 208 | inline void add() |
| 209 | { |
| 210 | base.emplace_back(T()); |
| 211 | } |
| 212 | |
| 213 | /*! \brief add elements to the vector |
| 214 | * |
| 215 | * \param eles elements to add |
| 216 | * |
| 217 | */ |
| 218 | template<typename Mem,template<typename> class lb,typename gp> inline void add(const openfpm::vector<T,Mem,lb,gp> & eles) |
| 219 | { |
| 220 | if (std::is_same<grow_p,openfpm::grow_policy_identity>::value == true) |
| 221 | { |
| 222 | // we reserve just one space more to avoid the capacity to increase by two |
| 223 | base.reserve(base.size() + eles.size()); |
| 224 | } |
| 225 | |
| 226 | size_t start = base.size(); |
| 227 | base.resize(base.size() + eles.size()); |
| 228 | |
| 229 | // copy the elements |
| 230 | std::copy(eles.begin(),eles.end(),base.begin()+start); |
| 231 | } |
| 232 | |
| 233 | /*! \brief It insert a new object on the vector, eventually it reallocate the object |
| 234 | * |
| 235 | * \param v element to add |
| 236 | * |
| 237 | * \warning It is not thread safe should not be used in multi-thread environment |
| 238 | * reallocation, work only on cpu |
| 239 | * |
| 240 | *vector_isel<T>::value |
| 241 | */ |
| 242 | template<typename S> inline void add(const S & v) |
| 243 | { |
| 244 | push_back_op<is_vector<T>::value,is_vector<S>::value,T,S>::push_back(base,v); |
| 245 | } |
| 246 | |
| 247 | /*! \brief It insert a new object on the vector, eventually it reallocate the grid |
| 248 | * |
| 249 | * \param v element to add |
| 250 | * |
| 251 | * \warning It is not thread safe should not be used in multi-thread environment |
| 252 | * reallocation, work only on cpu |
| 253 | * |
| 254 | *vector_isel<T>::value |
| 255 | */ |
| 256 | template<typename S> inline void add(const S && v) |
| 257 | { |
| 258 | if (std::is_same<grow_p,openfpm::grow_policy_identity>::value == true) |
| 259 | { |
| 260 | // we reserve just one space more to avoid the capacity to increase by two |
| 261 | base.reserve(base.size() + 1); |
| 262 | } |
| 263 | |
| 264 | base.push_back(v); |
| 265 | } |
| 266 | |
| 267 | /*! \brief It add the element of a source vector to this vector |
| 268 | * |
| 269 | * The number of properties in the source vector must be smaller than the destination |
| 270 | * all the properties of S must be mapped so if S has 3 properties |
| 271 | * 3 numbers for args are required |
| 272 | * |
| 273 | * \tparam S Base object of the source vector |
| 274 | * \tparam M memory type of the source vector |
| 275 | * \tparam gp Grow policy of the source vector |
| 276 | * \tparam args one or more number that define which property to set-up |
| 277 | * |
| 278 | * \param v source vector |
| 279 | * |
| 280 | */ |
| 281 | template <typename S, |
| 282 | typename M, |
| 283 | typename gp, |
| 284 | unsigned int impl, |
| 285 | template <typename> class layout_base, |
| 286 | unsigned int ...args> |
| 287 | void add_prp(const vector<S,M,layout_base,gp,impl> & v) |
| 288 | { |
| 289 | add_prp_impl<std::is_same<S,T>::value,typename std::remove_pointer<decltype(*this)>::type>::template add<S,M,gp,impl,args...>(v,*this); |
| 290 | } |
| 291 | |
| 292 | /*! \brief It add the element of a source vector to this vector |
| 293 | * |
| 294 | * The number of properties in the source vector must be smaller than the destination |
| 295 | * all the properties of S must be mapped so if S has 3 properties |
| 296 | * 3 numbers for args are required |
| 297 | * |
| 298 | * \tparam S Base object of the source vector |
| 299 | * \tparam M memory type of the source vector |
| 300 | * \tparam gp Grow policy of the source vector |
| 301 | * \tparam args one or more number that define which property to set-up |
| 302 | * |
| 303 | * \param v source vector |
| 304 | * |
| 305 | */ |
| 306 | template <typename S, |
| 307 | typename M, |
| 308 | typename gp, |
| 309 | unsigned int impl, |
| 310 | template <typename> class layout_base, |
| 311 | unsigned int ...args> |
| 312 | void add_prp_device(const vector<S,M,layout_base,gp,impl> & v) |
| 313 | { |
| 314 | add_prp_impl<std::is_same<S,T>::value,typename std::remove_pointer<decltype(*this)>::type>::template add<S,M,gp,impl,args...>(v,*this); |
| 315 | } |
| 316 | |
| 317 | /*! \brief It add the element it is equivalent to add |
| 318 | * |
| 319 | * exist to respect a general interface template parameters are unused the explanation |
| 320 | * refer to the interface specification, but is unused in this case |
| 321 | * |
| 322 | * \tparam S Base object of the source vector |
| 323 | * \tparam M memory type of the source vector |
| 324 | * \tparam gp Grow policy of the source vector |
| 325 | * \tparam args one or more number that define which property to set-up |
| 326 | * |
| 327 | * \param v source vector |
| 328 | * |
| 329 | */ |
| 330 | template <typename S, |
| 331 | typename M, |
| 332 | typename gp, |
| 333 | unsigned int impl, |
| 334 | template <typename> class layout_base, |
| 335 | unsigned int ...args> |
| 336 | void add_prp(const T & v) |
| 337 | { |
| 338 | add(v); |
| 339 | } |
| 340 | |
| 341 | /*! \brief Erase the elements from start to end |
| 342 | * |
| 343 | * \param start element |
| 344 | * \param end element |
| 345 | * |
| 346 | */ |
| 347 | void erase(typename std::vector<T>::iterator start, typename std::vector<T>::iterator end) |
| 348 | { |
| 349 | base.erase(start,end); |
| 350 | } |
| 351 | |
| 352 | /*! \brief Remove one entry from the vector |
| 353 | * |
| 354 | * \param key element to remove |
| 355 | * |
| 356 | */ |
| 357 | void remove(size_t key) |
| 358 | { |
| 359 | #ifdef SE_CLASS1 |
| 360 | vector_overflow(key); |
| 361 | #endif |
| 362 | base.erase(base.begin() + key); |
| 363 | } |
| 364 | |
| 365 | /*! \brief Remove several entries from the vector |
| 366 | * |
| 367 | * \warning the keys in the vector MUST be sorted |
| 368 | * |
| 369 | * \param keys objects id to remove |
| 370 | * \param start key starting point |
| 371 | * |
| 372 | */ |
| 373 | void remove(openfpm::vector<size_t> & keys, size_t start = 0) |
| 374 | { |
| 375 | // Nothing to remove return |
| 376 | if (keys.size() <= start ) |
| 377 | return; |
| 378 | |
| 379 | size_t a_key = start; |
| 380 | size_t d_k = keys.get(a_key); |
| 381 | size_t s_k = keys.get(a_key) + 1; |
| 382 | |
| 383 | // keys |
| 384 | while (s_k < size()) |
| 385 | { |
| 386 | // s_k should always point to a key that is not going to be deleted |
| 387 | while (a_key+1 < keys.size() && s_k == keys.get(a_key+1)) |
| 388 | { |
| 389 | a_key++; |
| 390 | s_k = keys.get(a_key) + 1; |
| 391 | } |
| 392 | |
| 393 | // In case of overflow |
| 394 | if (s_k >= size()) |
| 395 | break; |
| 396 | |
| 397 | base[d_k] = base[s_k]; |
| 398 | d_k++; |
| 399 | s_k++; |
| 400 | } |
| 401 | |
| 402 | // re-calculate the vector size |
| 403 | |
| 404 | base.resize(base.size() - (keys.size() - start)); |
| 405 | } |
| 406 | |
| 407 | /*! \brief Return an std compatible iterator to the first element |
| 408 | * |
| 409 | * \return an iterator to the first element |
| 410 | * |
| 411 | */ |
| 412 | inline auto begin() -> decltype(base.begin()) |
| 413 | { |
| 414 | return base.begin(); |
| 415 | } |
| 416 | |
| 417 | /*! \brief Return an std compatible iterator to the last element |
| 418 | * |
| 419 | * \return an iterator to the last element |
| 420 | * |
| 421 | */ |
| 422 | inline auto end() -> decltype(base.begin()) |
| 423 | { |
| 424 | return base.end(); |
| 425 | } |
| 426 | |
| 427 | /*! \brief Return an std compatible iterator to the first element |
| 428 | * |
| 429 | * \return an iterator to the first element |
| 430 | * |
| 431 | */ |
| 432 | inline auto begin() const -> const decltype(base.begin()) |
| 433 | { |
| 434 | return base.begin(); |
| 435 | } |
| 436 | |
| 437 | /*! \brief Return an std compatible iterator to the last element |
| 438 | * |
| 439 | * \return an iterator to the last element |
| 440 | * |
| 441 | */ |
| 442 | inline auto end() const -> const decltype(base.begin()) |
| 443 | { |
| 444 | return base.end(); |
| 445 | } |
| 446 | |
| 447 | /*! \brief Get the last element |
| 448 | * |
| 449 | * \return the last element as reference |
| 450 | * |
| 451 | */ |
| 452 | inline T & last() |
| 453 | { |
| 454 | #ifdef SE_CLASS1 |
| 455 | if (base.size() == 0) |
| 456 | std::cerr << "Error vector: " << __FILE__ << ":" << __LINE__ << " vector of size 0\n" ; |
| 457 | #endif |
| 458 | return base[base.size()-1]; |
| 459 | } |
| 460 | |
| 461 | /*! \brief Get the last element |
| 462 | * |
| 463 | * \return the last element as reference |
| 464 | * |
| 465 | */ |
| 466 | inline const T & last() const |
| 467 | { |
| 468 | #ifdef SE_CLASS1 |
| 469 | if (base.size() == 0) |
| 470 | std::cerr << "Error vector: " << __FILE__ << ":" << __LINE__ << " vector of size 0\n" ; |
| 471 | #endif |
| 472 | return base[base.size()-1]; |
| 473 | } |
| 474 | |
| 475 | /*! \brief Duplicate the vector |
| 476 | * |
| 477 | * \return the duplicated vector |
| 478 | * |
| 479 | */ |
| 480 | openfpm::vector<T> duplicate() const |
| 481 | { |
| 482 | return *this; |
| 483 | } |
| 484 | |
| 485 | /*! \brief swap the memory between the two vector |
| 486 | * |
| 487 | * \param v vector to swap |
| 488 | * |
| 489 | */ |
| 490 | void swap(std::vector<T> && v) |
| 491 | { |
| 492 | base.swap(v); |
| 493 | } |
| 494 | |
| 495 | /*! \brief It eliminate double entries |
| 496 | * |
| 497 | * \note The base object must have an operator== defined |
| 498 | * |
| 499 | */ |
| 500 | void unique() |
| 501 | { |
| 502 | auto it = std::unique(base.begin(),base.end()); |
| 503 | base.resize( std::distance(base.begin(),it) ); |
| 504 | } |
| 505 | |
| 506 | /*! \brief It sort the vector |
| 507 | * |
| 508 | * \note The base object must have an operator< defined |
| 509 | * |
| 510 | */ |
| 511 | void sort() |
| 512 | { |
| 513 | std::sort(base.begin(), base.end()); |
| 514 | } |
| 515 | |
| 516 | /*! \brief Get an element of the vector |
| 517 | * |
| 518 | * \tparam p must be 0 |
| 519 | * |
| 520 | * \param id element to get |
| 521 | * |
| 522 | * \return the reference to the element |
| 523 | * |
| 524 | */ |
| 525 | template <unsigned int p>inline T& get(size_t id) |
| 526 | { |
| 527 | #ifdef SE_CLASS1 |
| 528 | if (p != 0) |
| 529 | {std::cerr << "Error the property does not exist" << "\n" ;} |
| 530 | |
| 531 | vector_overflow(id); |
| 532 | #endif |
| 533 | |
| 534 | return base[id]; |
| 535 | } |
| 536 | |
| 537 | /*! \brief Get an element of the vector |
| 538 | * |
| 539 | * \tparam p must be 0 |
| 540 | * |
| 541 | * \param id element to get |
| 542 | * |
| 543 | * \return the reference to the element |
| 544 | * |
| 545 | */ |
| 546 | template <unsigned int p>inline const T& get(size_t id) const |
| 547 | { |
| 548 | #ifdef SE_CLASS1 |
| 549 | if (p != 0) |
| 550 | {std::cerr << "Error the property does not exist" << "\n" ;} |
| 551 | |
| 552 | vector_overflow(id); |
| 553 | #endif |
| 554 | |
| 555 | return base[id]; |
| 556 | } |
| 557 | |
| 558 | /*! \brief Get an element of the vector |
| 559 | * |
| 560 | * \param id element to get |
| 561 | * |
| 562 | * \return the element reference |
| 563 | * |
| 564 | */ |
| 565 | inline T & get(size_t id) |
| 566 | { |
| 567 | #ifdef SE_CLASS1 |
| 568 | vector_overflow(id); |
| 569 | #endif |
| 570 | return base[id]; |
| 571 | } |
| 572 | |
| 573 | /*! \brief Get an element of the vector |
| 574 | * |
| 575 | * \param id element to get |
| 576 | * |
| 577 | * \return the element value |
| 578 | * |
| 579 | */ |
| 580 | inline const T & get(size_t id) const |
| 581 | { |
| 582 | #ifdef SE_CLASS1 |
| 583 | vector_overflow(id); |
| 584 | #endif |
| 585 | return base[id]; |
| 586 | } |
| 587 | |
| 588 | /*! \brief it fill all the memory of fl patterns |
| 589 | * |
| 590 | * WARNING does not assign a value to each element but it fill the memory |
| 591 | * Useful to fast set the memory to zero |
| 592 | * |
| 593 | * \param fl byte to fill |
| 594 | * |
| 595 | */ |
| 596 | inline void fill(unsigned char fl) |
| 597 | { |
| 598 | memset(&base[0],fl,base.size() * sizeof(T)); |
| 599 | } |
| 600 | |
| 601 | /*! \brief reserve a memory space in advance to avoid reallocation |
| 602 | * |
| 603 | * \param ns number of element the memory has to store |
| 604 | * |
| 605 | */ |
| 606 | inline void reserve(size_t ns) |
| 607 | { |
| 608 | base.reserve(ns); |
| 609 | } |
| 610 | |
| 611 | //! Constructor, vector of size 0 |
| 612 | vector() noexcept |
| 613 | :err_code(0) |
| 614 | { |
| 615 | } |
| 616 | |
| 617 | //! Constructor, vector of size sz |
| 618 | vector(size_t sz) noexcept |
| 619 | :base(sz),err_code(0) |
| 620 | { |
| 621 | } |
| 622 | |
| 623 | //! Constructor from another vector |
| 624 | vector(const vector<T,HeapMemory,memory_traits_lin,grow_policy_double,STD_VECTOR> & v) noexcept |
| 625 | :err_code(0) |
| 626 | { |
| 627 | base = v.base; |
| 628 | } |
| 629 | |
| 630 | /*! \brief Initializer from constructor |
| 631 | * |
| 632 | * \param v Initializer list |
| 633 | * |
| 634 | */ |
| 635 | vector(const std::initializer_list<T> & v) |
| 636 | :base(v) |
| 637 | { |
| 638 | } |
| 639 | |
| 640 | //! Constructor from another vector |
| 641 | vector(vector<T,HeapMemory,memory_traits_lin,grow_policy_double,STD_VECTOR> && v) noexcept |
| 642 | :err_code(0) |
| 643 | { |
| 644 | base.swap(v.base); |
| 645 | } |
| 646 | |
| 647 | //! destructor |
| 648 | ~vector() noexcept |
| 649 | { |
| 650 | } |
| 651 | |
| 652 | /*! swap the content of the vector |
| 653 | * |
| 654 | * \param v vector to be swapped with |
| 655 | * |
| 656 | */ |
| 657 | void swap(openfpm::vector<T,HeapMemory,memory_traits_lin,grow_policy_double,STD_VECTOR> & v) |
| 658 | { |
| 659 | base.swap(v.base); |
| 660 | } |
| 661 | |
| 662 | /*! swap the content of the vector |
| 663 | * |
| 664 | * \param v vector to be swapped with |
| 665 | * |
| 666 | */ |
| 667 | void swap(openfpm::vector<T,HeapMemory,memory_traits_lin,grow_policy_double,STD_VECTOR> && v) |
| 668 | { |
| 669 | base.swap(v.base); |
| 670 | } |
| 671 | |
| 672 | /*! \brief Operator= copy the vector into another |
| 673 | * |
| 674 | * \param v vector to copy |
| 675 | * |
| 676 | * \return itself |
| 677 | * |
| 678 | */ |
| 679 | vector<T,HeapMemory,memory_traits_lin,grow_policy_double,STD_VECTOR> & operator=(const vector<T,HeapMemory,memory_traits_lin,grow_policy_double,STD_VECTOR> & v) |
| 680 | { |
| 681 | base = v.base; |
| 682 | |
| 683 | return *this; |
| 684 | } |
| 685 | |
| 686 | /*! \brief Operator= copy the vector into another |
| 687 | * |
| 688 | * \return itself |
| 689 | * |
| 690 | */ |
| 691 | template<typename Mem, typename gp> vector<T,HeapMemory,memory_traits_lin,grow_policy_double,STD_VECTOR> & operator=(const vector<T,Mem,memory_traits_lin,gp,STD_VECTOR> & v) |
| 692 | { |
| 693 | base_copy<has_base_to_copy<vector<T,Mem,memory_traits_lin,gp,STD_VECTOR>>::value, |
| 694 | decltype(*this), |
| 695 | vector<T,Mem,memory_traits_lin,gp,STD_VECTOR> >::copy(*this,v); |
| 696 | |
| 697 | return *this; |
| 698 | } |
| 699 | |
| 700 | /*! \brief Operator= copy the vector into another |
| 701 | * |
| 702 | * \param v vector to copy |
| 703 | * |
| 704 | * \return itself |
| 705 | * |
| 706 | */ |
| 707 | vector<T,HeapMemory,memory_traits_lin,grow_policy_double,STD_VECTOR> & operator=(vector<T,HeapMemory,memory_traits_lin,grow_policy_double,STD_VECTOR> && v) |
| 708 | { |
| 709 | base.swap(v.base); |
| 710 | |
| 711 | return *this; |
| 712 | } |
| 713 | |
| 714 | /*! \brief Operator= copy the vector into another |
| 715 | * |
| 716 | * \param v vector to copy |
| 717 | * |
| 718 | * \return itself |
| 719 | * |
| 720 | */ |
| 721 | template<typename Mem, typename gp> vector<T,HeapMemory,memory_traits_lin,grow_policy_double,STD_VECTOR> & operator=(vector<T,Mem,memory_traits_lin,gp,STD_VECTOR> && v) |
| 722 | { |
| 723 | base.swap(v.base); |
| 724 | |
| 725 | return *this; |
| 726 | } |
| 727 | |
| 728 | /*! \brief Check that two vectors are equal |
| 729 | * |
| 730 | * \param v vector to compare |
| 731 | * |
| 732 | * \return true if they differs |
| 733 | * |
| 734 | */ |
| 735 | bool operator!=(const vector<T, HeapMemory, memory_traits_lin,grow_policy_double,STD_VECTOR> & v) const |
| 736 | { |
| 737 | return base != v.base; |
| 738 | } |
| 739 | |
| 740 | /*! \brief Check that two vectors are not equal |
| 741 | * |
| 742 | * \param v vector to compare |
| 743 | * |
| 744 | * \return true if the vector match |
| 745 | * |
| 746 | */ |
| 747 | bool operator==(const vector<T, HeapMemory, memory_traits_lin,grow_policy_double,STD_VECTOR> & v) const |
| 748 | { |
| 749 | return base == v.base; |
| 750 | } |
| 751 | |
| 752 | /*! \brief Get an iterator over all the elements of the vector |
| 753 | * |
| 754 | * \return an iterator |
| 755 | * |
| 756 | */ |
| 757 | vector_key_iterator getIterator() const |
| 758 | { |
| 759 | return vector_key_iterator(base.size()); |
| 760 | } |
| 761 | |
| 762 | /*! \brief Get iterator until a specified element |
| 763 | * |
| 764 | * \param k key |
| 765 | * |
| 766 | * \return an iterator |
| 767 | * |
| 768 | */ |
| 769 | vector_key_iterator getIteratorTo(size_t k) const |
| 770 | { |
| 771 | return vector_key_iterator(k); |
| 772 | } |
| 773 | |
| 774 | /*! \brief Calculate the memory size required to allocate n elements |
| 775 | * |
| 776 | * Calculate the total size required to store n-elements in a vector |
| 777 | * |
| 778 | * \param n number of elements |
| 779 | * \param e unused |
| 780 | * |
| 781 | * \return the size of the allocation number e |
| 782 | * |
| 783 | */ |
| 784 | template<int ... prp> inline size_t packMem(size_t n, size_t e) const |
| 785 | { |
| 786 | if (n == 0) |
| 787 | return 0; |
| 788 | else |
| 789 | { |
| 790 | packMem_cond<has_packMem<T>::type::value, openfpm::vector<T, HeapMemory, memory_traits_lin, grow_policy_double>, prp...> cm; |
| 791 | return cm.packMemory(*this,n,0); |
| 792 | } |
| 793 | } |
| 794 | |
| 795 | /*! \brief Calculate the memory size required to allocate n elements |
| 796 | * |
| 797 | * Calculate the total size required to store n-elements in a vector |
| 798 | * |
| 799 | * \param n number of elements |
| 800 | * \param e unused |
| 801 | * |
| 802 | * \return the size of the allocation number e |
| 803 | * |
| 804 | */ |
| 805 | inline static size_t calculateMemDummy(size_t n, size_t e) |
| 806 | { |
| 807 | return n*sizeof(T); |
| 808 | } |
| 809 | |
| 810 | /*! \brief How many allocation are required to create n-elements |
| 811 | * |
| 812 | * \param n number of elements |
| 813 | * |
| 814 | * \return the number of allocations |
| 815 | * |
| 816 | */ |
| 817 | inline static size_t calculateNMem(size_t n) |
| 818 | { |
| 819 | |
| 820 | return 1; |
| 821 | } |
| 822 | |
| 823 | /*! \brief Return the pointer to the chunk of memory |
| 824 | * |
| 825 | * \return the pointer to the chunk of memory |
| 826 | * |
| 827 | */ |
| 828 | void * getPointer() |
| 829 | { |
| 830 | return &base[0]; |
| 831 | } |
| 832 | |
| 833 | /*! \brief Do nothing |
| 834 | * |
| 835 | */ |
| 836 | template<unsigned int ... prp> void hostToDevice() |
| 837 | {} |
| 838 | |
| 839 | /*! \brief Do nothing |
| 840 | * |
| 841 | */ |
| 842 | template<unsigned int ... prp> void deviceToHost() |
| 843 | {} |
| 844 | |
| 845 | /*! \brief Do nothing |
| 846 | * |
| 847 | * |
| 848 | */ |
| 849 | template<unsigned int ... prp> void deviceToHost(size_t start, size_t stop) |
| 850 | {} |
| 851 | |
| 852 | /*! \brief Do nothing |
| 853 | * |
| 854 | * |
| 855 | */ |
| 856 | template<unsigned int ... prp> void hostToDevice(size_t start, size_t stop) |
| 857 | {} |
| 858 | |
| 859 | /*! \brief Return the pointer to the chunk of memory |
| 860 | * |
| 861 | * \return the pointer to the chunk of memory |
| 862 | * |
| 863 | */ |
| 864 | const void * getPointer() const |
| 865 | { |
| 866 | return &base[0]; |
| 867 | } |
| 868 | |
| 869 | /*! \brief This class has pointer inside |
| 870 | * |
| 871 | * \return false |
| 872 | * |
| 873 | */ |
| 874 | static bool noPointers() |
| 875 | { |
| 876 | return false; |
| 877 | } |
| 878 | |
| 879 | /*! \brief Return the last error |
| 880 | * |
| 881 | * \return erro code |
| 882 | * |
| 883 | */ |
| 884 | size_t getLastError() |
| 885 | { |
| 886 | return err_code; |
| 887 | } |
| 888 | |
| 889 | /*! \brief check that the id does not overflow the buffer |
| 890 | * |
| 891 | * \param v1 id to check |
| 892 | * |
| 893 | */ |
| 894 | inline void vector_overflow(size_t v1) const |
| 895 | { |
| 896 | if (v1 >= base.size()) |
| 897 | { |
| 898 | std::cerr << "Error vector: " << __FILE__ << ":" << __LINE__ << " overflow id: " << v1 << "\n" ;\ |
| 899 | size_t * err_code_pointer = (size_t *)&this->err_code;\ |
| 900 | *err_code_pointer = 2001;\ |
| 901 | |
| 902 | ACTION_ON_ERROR(VECTOR_ERROR_OBJECT);\ |
| 903 | } |
| 904 | } |
| 905 | }; |
| 906 | |
| 907 | /*! \brief Implementation of 1-D std::vector like structure |
| 908 | * |
| 909 | * this implementation is just a wrapper for the std::vector. It work a little different from vector. |
| 910 | * In general for a normal vector of objects A vector<A> if you resize to zero, the destructor of |
| 911 | * the object A is called.This vector differ in this behaviour. the destructor is not called. This give the possibility |
| 912 | * to have a set of fully retained objects. This class is just a simple wrapper for the normal openfpm::vector where |
| 913 | * size and resize are redefined to change the behaviour. A destructive resize is callable with resize_base(), and the internal |
| 914 | * size of the base vactor can be queried with size_base() |
| 915 | * |
| 916 | * \param T base type |
| 917 | * |
| 918 | */ |
| 919 | template<typename T> |
| 920 | class vector_fr |
| 921 | :private vector<T,HeapMemory,memory_traits_lin,grow_policy_double,STD_VECTOR> |
| 922 | { |
| 923 | typedef vector<T,HeapMemory,memory_traits_lin,grow_policy_double,STD_VECTOR> base_type; |
| 924 | |
| 925 | //! size of the vector |
| 926 | size_t v_size = 0; |
| 927 | |
| 928 | public: |
| 929 | |
| 930 | /*! \brief return the size of the vector |
| 931 | * |
| 932 | * \return the size |
| 933 | * |
| 934 | */ |
| 935 | size_t size() |
| 936 | { |
| 937 | return v_size; |
| 938 | } |
| 939 | |
| 940 | /*! \brief return the base size of the vector |
| 941 | * |
| 942 | * \return the size |
| 943 | * |
| 944 | */ |
| 945 | size_t size_base() |
| 946 | { |
| 947 | return base_type::size(); |
| 948 | } |
| 949 | |
| 950 | /*! \brief resize the vector retaining the objects |
| 951 | * |
| 952 | * \param new size of the vector |
| 953 | * |
| 954 | */ |
| 955 | void resize(size_t sz) |
| 956 | { |
| 957 | if (sz <= base_type::size()) |
| 958 | { |
| 959 | v_size = sz; |
| 960 | return; |
| 961 | } |
| 962 | |
| 963 | base_type::resize(sz); |
| 964 | |
| 965 | v_size = sz; |
| 966 | } |
| 967 | |
| 968 | /*! \brief Eliminate all elements |
| 969 | * |
| 970 | * |
| 971 | */ |
| 972 | void clear() |
| 973 | { |
| 974 | resize(0); |
| 975 | } |
| 976 | |
| 977 | /*! \brief Add another element |
| 978 | * |
| 979 | * |
| 980 | */ |
| 981 | void add() |
| 982 | { |
| 983 | resize(v_size+1); |
| 984 | } |
| 985 | |
| 986 | /*! \brief resize the base vector (this kill the objects) |
| 987 | * |
| 988 | * \param new size of the vector |
| 989 | * |
| 990 | */ |
| 991 | void resize_base(size_t sz) |
| 992 | { |
| 993 | base_type::resize(sz); |
| 994 | v_size = sz; |
| 995 | } |
| 996 | |
| 997 | /*! \brief Get an element of the vector |
| 998 | * |
| 999 | * \param id element to get |
| 1000 | * |
| 1001 | * \return the element reference |
| 1002 | * |
| 1003 | */ |
| 1004 | inline T & get(size_t id) |
| 1005 | { |
| 1006 | return base_type::get(id); |
| 1007 | } |
| 1008 | |
| 1009 | /*! \brief Get an element of the vector |
| 1010 | * |
| 1011 | * \param id element to get |
| 1012 | * |
| 1013 | * \return the element reference |
| 1014 | * |
| 1015 | */ |
| 1016 | inline T & last() |
| 1017 | { |
| 1018 | return base_type::get(size()-1); |
| 1019 | } |
| 1020 | |
| 1021 | /*! swap the content of the vector |
| 1022 | * |
| 1023 | * \param v vector to be swapped with |
| 1024 | * |
| 1025 | */ |
| 1026 | void swap(openfpm::vector_fr<T> & v) |
| 1027 | { |
| 1028 | size_t v_size_tmp = v.v_size; |
| 1029 | v.v_size = v_size; |
| 1030 | v_size = v_size_tmp; |
| 1031 | |
| 1032 | base_type::swap(v); |
| 1033 | } |
| 1034 | }; |
| 1035 | |
| 1036 | #endif /* MAP_VECTOR_STD_HPP_ */ |
| 1037 | |