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 | |