PVData C++  8.0.6
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
sharedVector.h
1 /* sharedVector.h */
2 /*
3  * Copyright information and license terms for this software can be
4  * found in the file LICENSE that is included with the distribution
5  */
6 #ifndef SHAREDVECTOR_H
7 #define SHAREDVECTOR_H
8 
9 #include <ostream>
10 #include <algorithm>
11 #include <stdexcept>
12 #include <iterator>
13 
14 #if __cplusplus>=201103L
15 # include <initializer_list>
16 #endif
17 
18 #include <cassert>
19 
20 #include "pv/sharedPtr.h"
21 #include "pv/pvIntrospect.h"
22 #include "pv/typeCast.h"
23 #include "pv/templateMeta.h"
24 
25 namespace epics { namespace pvData {
26 
27 template<typename E, class Enable = void> class shared_vector;
28 
29 template<typename TO, typename FROM>
30 static FORCE_INLINE
32 const_shared_vector_cast(shared_vector<FROM>& src);
33 
34 namespace detail {
35  template<typename E>
36  struct default_array_deleter {void operator()(E a){delete[] a;}};
37 
38  // How values should be passed as arguments to shared_vector methods
39  // really should use boost::call_traits
40  template<typename T> struct call_with { typedef T type; };
41  template<typename T> struct call_with<std::tr1::shared_ptr<T> >
42  { typedef const std::tr1::shared_ptr<T>& type; };
43  template<> struct call_with<std::string> { typedef const std::string& type; };
44 
48 
49  /* All the parts of shared_vector which
50  * don't need special handling for E=void
51  */
52  template<typename E>
54  {
55  // allow specialization for all E to be friends
56  template<typename E1> friend class shared_vector_base;
57  protected:
58  // NOTE: Do no use m_data, since VxWorks has a 'm_data' macro defined
59  std::tr1::shared_ptr<E> m_sdata;
61  size_t m_offset;
63  size_t m_count;
65  size_t m_total;
66 
67  /* invariants
68  * m_count <= m_total (enforced)
69  * m_offset + m_total <= (size_t)-1 (checked w/ assert())
70  */
71 
72  public:
73 #if __cplusplus>=201103L
74  constexpr shared_vector_base() noexcept
76  :m_sdata(), m_offset(0), m_count(0), m_total(0)
77  {}
78 #else
81  :m_sdata(), m_offset(0), m_count(0), m_total(0)
82  {}
83 #endif
84 
85  protected:
86  // helper for constructors
87  // Ensure that offset and size are zero when we are constructed with NULL
88  void _null_input()
89  {
90  if(!m_sdata) {
91  m_offset = m_total = m_count = 0;
92  } else {
93  // ensure we won't have integer overflows later
94  assert( m_offset <= ((size_t)-1) - m_total);
95  }
96  }
97  public:
98 
99  template<typename A>
100  shared_vector_base(A* v, size_t o, size_t c)
101  :m_sdata(v, detail::default_array_deleter<A*>())
102  ,m_offset(o), m_count(c), m_total(c)
103  {_null_input();}
104 
105  shared_vector_base(const std::tr1::shared_ptr<E>& d, size_t o, size_t c)
106  :m_sdata(d), m_offset(o), m_count(c), m_total(c)
107  {_null_input();}
108 
109 
110  template<typename A, typename B>
111  shared_vector_base(A d, B b, size_t o, size_t c)
112  :m_sdata(d,b), m_offset(o), m_count(c), m_total(c)
113  {_null_input();}
114 
116  :m_sdata(O.m_sdata), m_offset(O.m_offset)
118  {}
119 
120 #if __cplusplus >= 201103L
122  :m_sdata(std::move(O.m_sdata))
123  ,m_offset(O.m_offset)
124  ,m_count(O.m_count)
125  ,m_total(O.m_total)
126  {
127  O.clear();
128  }
129 #endif
130 
131  protected:
132  typedef typename meta::strip_const<E>::type _E_non_const;
133  public:
138  :m_sdata()
139  ,m_offset(O.m_offset)
140  ,m_count(O.m_count)
141  ,m_total(O.m_total)
142  {
143  if(!O.unique())
144  throw std::runtime_error("Can't freeze non-unique vector");
145 #if __cplusplus >= 201103L
146  m_sdata = std::move(O.m_sdata);
147 #else
148  m_sdata = O.m_sdata;
149 #endif
150  O.clear();
151  }
152 
157  :m_sdata()
158  ,m_offset(O.m_offset)
159  ,m_count(O.m_count)
160  ,m_total(O.m_total)
161  {
162  O.make_unique();
163 #if __cplusplus >= 201103L
164  m_sdata = std::move(std::tr1::const_pointer_cast<E>(O.m_sdata));
165 #else
166  m_sdata = std::tr1::const_pointer_cast<E>(O.m_sdata);
167 #endif
168  O.clear();
169  }
170 
173  {
174  if(&o!=this) {
175  m_sdata=o.m_sdata;
176  m_offset=o.m_offset;
177  m_count=o.m_count;
178  m_total=o.m_total;
179  }
180  return *this;
181  }
182 
183 #if __cplusplus >= 201103L
186  {
187  if(&o!=this) {
188  m_sdata=std::move(o.m_sdata);
189  m_offset=o.m_offset;
190  m_count=o.m_count;
191  m_total=o.m_total;
192  o.clear();
193  }
194  return *this;
195  }
196 #endif
197 
200  if(&o!=this) {
201  m_sdata.swap(o.m_sdata);
205  }
206  }
207 
210  void clear() {
211  m_sdata.reset();
212  m_offset = m_total = m_count = 0;
213  }
214 
216  bool unique() const {return !m_sdata || m_sdata.use_count()<=1;}
217 
218 
220  size_t size() const{return m_count;}
222  bool empty() const{return !m_count;}
223 
224 
244  void slice(size_t offset, size_t length=(size_t)-1)
245  {
246  if(offset>m_count)
247  offset = m_count; // will slice down to zero length
248 
249  const size_t max_count = m_count - offset;
250 
251  m_offset += offset;
252 
253  m_total -= offset;
254 
255  if(length > max_count)
256  length = max_count;
257  m_count = length;
258  }
259 
260  // Access to members.
261  const std::tr1::shared_ptr<E>& dataPtr() const { return m_sdata; }
262  size_t dataOffset() const { return m_offset; }
263  size_t dataCount() const { return m_count; }
264  size_t dataTotal() const { return m_total; }
265  };
266 }
267 
286 template<typename E, class Enable>
287 class shared_vector : public detail::shared_vector_base<E>
288 {
289  typedef detail::shared_vector_base<E> base_t;
290  typedef typename detail::call_with<E>::type param_type;
291  typedef typename meta::strip_const<E>::type _E_non_const;
292 public:
293  typedef E value_type;
294  typedef E& reference;
295  typedef typename meta::decorate_const<E>::type& const_reference;
296  typedef E* pointer;
297  typedef typename meta::decorate_const<E>::type* const_pointer;
298  typedef E* iterator;
299  typedef std::reverse_iterator<iterator> reverse_iterator;
300  typedef typename meta::decorate_const<E>::type* const_iterator;
301  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
302  typedef ptrdiff_t difference_type;
303  typedef size_t size_type;
304 
305  typedef E element_type;
306  typedef std::tr1::shared_ptr<E> shared_pointer_type;
307 
308  // allow specialization for all E to be friends
309  template<typename E1, class Enable1> friend class shared_vector;
310 
312 #if __cplusplus>=201103L
313  constexpr shared_vector() noexcept :base_t() {}
314 #else
316 #endif
317 
318 #if __cplusplus>=201103L
319  template<typename A>
321  :base_t(new _E_non_const[L.size()], 0, L.size())
322  {
323  _E_non_const *raw = const_cast<_E_non_const*>(data());
324  std::copy(L.begin(), L.end(), raw);
325  }
326 #endif
327 
329  explicit shared_vector(size_t c)
330  :base_t(new _E_non_const[c], 0, c)
331  {}
332 
334  shared_vector(size_t c, param_type e)
335  :base_t(new _E_non_const[c], 0, c)
336  {
337  std::fill_n((_E_non_const*)this->m_sdata.get(), this->m_count, e);
338  }
339 
346  template<typename A>
347  shared_vector(A v, size_t o, size_t c) :base_t(v,o,c) {}
348 
355  template<typename E1>
356  shared_vector(const std::tr1::shared_ptr<E1>& d, size_t o, size_t c)
357  :base_t(d,o,c) {}
358 
366  template<typename A, typename B>
367  shared_vector(A d, B b, size_t o, size_t c)
368  :base_t(d,b,o,c) {}
369 
372 
373 #if __cplusplus>=201103L
374  shared_vector(shared_vector&& o) :base_t(std::move(o)) {}
376 #endif
377 
380  template<typename FROM>
381  shared_vector(const shared_vector<FROM> &src,
382  detail::_shared_vector_cast_tag)
383  :base_t(std::tr1::static_pointer_cast<E>(src.dataPtr()),
384  src.dataOffset()/sizeof(E),
385  src.dataCount()/sizeof(E))
386  {}
387 
388 
389  shared_vector(shared_vector<typename base_t::_E_non_const>& O,
390  detail::_shared_vector_freeze_tag t)
391  :base_t(O,t)
392  {}
393 
394  shared_vector(shared_vector<const E>& O,
395  detail::_shared_vector_thaw_tag t)
396  :base_t(O,t)
397  {}
398 
399  inline shared_vector& operator=(const shared_vector& o)
400  {
401  this->base_t::operator=(o);
402  return *this;
403  }
404 
405 #if __cplusplus>=201103L
407  {
408  this->base_t::operator=(std::move(o));
409  return *this;
410  }
411 #endif
412 
413  size_t max_size() const{return ((size_t)-1)/sizeof(E);}
414 
415  size_t capacity() const { return this->m_total; }
416 
428  void reserve(size_t i) {
429  if(this->unique() && i<=this->m_total)
430  return;
431  size_t new_count = this->m_count;
432  if(new_count > i)
433  new_count = i;
434  _E_non_const* temp=new _E_non_const[i];
435  try{
436  std::copy(begin(), begin()+new_count, temp);
437  }catch(...){
438  delete[] temp;
439  throw;
440  }
441  this->m_sdata.reset(temp, detail::default_array_deleter<E*>());
442  this->m_offset = 0;
443  this->m_count = new_count;
444  this->m_total = i;
445  }
446 
457  void resize(size_t i) {
458  if(i==this->m_count) {
459  make_unique();
460  return;
461  }
462  if(this->m_sdata && this->m_sdata.use_count()==1) {
463  // we have data and exclusive ownership of it
464  if(i<=this->m_total) {
465  // We have room to grow (or shrink)!
466  this->m_count = i;
467  return;
468  }
469  }
470  // must re-allocate :(
471  size_t new_total = this->m_total;
472  if(new_total < i)
473  new_total = i;
474  _E_non_const* temp=new _E_non_const[new_total];
475  try{
476  size_t n = this->size();
477  if(n > i)
478  n = i;
479  // Copy as much as possible from old,
480  // remaining elements are uninitialized.
481  std::copy(begin(),
482  begin()+n,
483  temp);
484  }catch(...){
485  delete[] temp;
486  throw;
487  }
488  this->m_sdata.reset(temp, detail::default_array_deleter<pointer>());
489  this->m_offset= 0;
490  this->m_count = i;
491  this->m_total = new_total;
492  }
493 
498  void resize(size_t i, param_type v) {
499  size_t oldsize=this->size();
500  resize(i);
501  if(this->size()>oldsize) {
502  std::fill(begin()+oldsize, end(), v);
503  }
504  }
505 
526  void make_unique() {
527  if(this->unique())
528  return;
529  // at this point we know that !!m_sdata, so get()!=NULL
530  _E_non_const *d = new _E_non_const[this->m_total];
531  try {
532  std::copy(this->m_sdata.get()+this->m_offset,
533  this->m_sdata.get()+this->m_offset+this->m_count,
534  d);
535  }catch(...){
536  delete[] d;
537  throw;
538  }
539  this->m_sdata.reset(d, detail::default_array_deleter<E*>());
540  this->m_offset=0;
541  }
542 
543 private:
544  /* Hack alert.
545  * For reasons of simplicity and efficiency, we want to use raw pointers for iteration.
546  * However, shared_ptr::get() isn't defined when !m_sdata, although practically it gives NULL.
547  * Unfortunately, many of the MSVC (<= VS 2013) STL methods assert() that iterators are never NULL.
548  * So we fudge here by abusing 'this' so that our iterators are always !NULL.
549  */
550  inline E* base_ptr() const {
551 #if defined(_MSC_VER) && _MSC_VER<=1800
552  return this->m_count ? this->m_sdata.get() : (E*)(this-1);
553 #else
554  return this->m_sdata.get();
555 #endif
556  }
557 public:
558  // STL iterators
559 
560  iterator begin() const{return this->base_ptr()+this->m_offset;}
561  const_iterator cbegin() const{return begin();}
562 
563  iterator end() const{return this->base_ptr()+this->m_offset+this->m_count;}
564  const_iterator cend() const{return end();}
565 
566  reverse_iterator rbegin() const{return reverse_iterator(end());}
567  const_reverse_iterator crbegin() const{return rbegin();}
568 
569  reverse_iterator rend() const{return reverse_iterator(begin());}
570  const_reverse_iterator crend() const{return rend();}
571 
572  reference front() const{return (*this)[0];}
573  reference back() const{return (*this)[this->m_count-1];}
574 
575  // Modifications
576 
577 private:
578  void _push_resize() {
579  if(this->m_count==this->m_total || !this->unique()) {
580  size_t next;
581  if(this->m_total<1024) {
582  // round m_total+1 up to the next power of 2
583  next = this->m_total;
584  next |= next >> 1;
585  next |= next >> 2;
586  next |= next >> 4;
587  next |= next >> 8;
588  next++;
589  } else {
590  // pad m_total up to the next multiple of 1024
591  next = this->m_total+1024;
592  next &= ~0x3ff;
593  }
594  assert(next > this->m_total);
595  reserve(next);
596  }
597  resize(this->size()+1);
598  }
599 
600 public:
601 
602  void push_back(param_type v)
603  {
604  _push_resize();
605  back() = v;
606  }
607 
608  void pop_back()
609  {
610  this->slice(0, this->size()-1);
611  }
612 
613  // data access
614 
616  pointer data() const{return this->m_sdata.get()+this->m_offset;}
617 
620  reference operator[](size_t i) const {return this->m_sdata.get()[this->m_offset+i];}
621 
624  reference at(size_t i) const
625  {
626  if(i>this->m_count)
627  throw std::out_of_range("Index out of bounds");
628  return (*this)[i];
629  }
630 
631 };
632 
653 template<typename E>
654 class shared_vector<E, typename meta::is_void<E>::type >
655  : public detail::shared_vector_base<E>
656 {
658  ScalarType m_vtype;
659 
660  // allow specialization for all E to be friends
661  template<typename E1, class Enable1> friend class shared_vector;
662 public:
663  typedef E value_type;
664  typedef E* pointer;
665  typedef ptrdiff_t difference_type;
666  typedef size_t size_type;
667 
668  typedef std::tr1::shared_ptr<E> shared_pointer_type;
669 
670 #if __cplusplus>=201103L
671  constexpr shared_vector() noexcept :base_t(), m_vtype((ScalarType)-1) {}
672 #else
673  shared_vector() :base_t(), m_vtype((ScalarType)-1) {}
674 #endif
675 
676  shared_vector(pointer v, size_t o, size_t c)
677  :base_t(v,o,c), m_vtype((ScalarType)-1) {}
678 
679  template<typename B>
680  shared_vector(pointer d, B b, size_t o, size_t c)
681  :base_t(d,b,o,c), m_vtype((ScalarType)-1) {}
682 
683  template<typename E1>
684  shared_vector(const std::tr1::shared_ptr<E1>& d, size_t o, size_t c)
685  :base_t(d,o,c), m_vtype((ScalarType)-1) {}
686 
687  shared_vector(const shared_vector& o)
688  :base_t(o), m_vtype(o.m_vtype) {}
689 
690 #if __cplusplus>=201103L
692  :base_t(std::move(o)), m_vtype(o.m_vtype) {}
693 #endif
694 
697  template<typename FROM>
700  :base_t(std::tr1::static_pointer_cast<E>(src.dataPtr()),
701  src.dataOffset()*sizeof(FROM),
702  src.dataCount()*sizeof(FROM))
704  {}
705 
708  :base_t(O,t), m_vtype(O.m_vtype)
709  {}
710 
713  :base_t(O,t), m_vtype(O.m_vtype)
714  {}
715 
717  {
718  if(&o!=this) {
719  this->base_t::operator=(o);
720  m_vtype = o.m_vtype;
721  }
722  return *this;
723  }
724 
725 #if __cplusplus>=201103L
727  {
728  if(&o!=this) {
729  this->base_t::operator=(std::move(o));
730  m_vtype = o.m_vtype;
731  }
732  return *this;
733  }
734 #endif
735 
736  void swap(shared_vector& o) {
737  base_t::swap(o);
738  std::swap(m_vtype, o.m_vtype);
739  }
740 
741  size_t max_size() const{return (size_t)-1;}
742 
743  pointer data() const{
744  return (pointer)(((char*)this->m_sdata.get())+this->m_offset);
745  }
746 
747  shared_vector& set_original_type(ScalarType t) { m_vtype=t; return *this; }
748  ScalarType original_type() const {return m_vtype;}
749 };
750 
751 namespace detail {
752  template<typename TO, typename FROM, class Enable = void>
753  struct static_shared_vector_caster { /* no default */ };
754  // from void to non-void with same const-ness
755  template<typename TO, typename FROM>
757  typename meta::_and<meta::_and<meta::is_not_void<TO>, meta::is_void<FROM> >,
758  meta::same_const<TO,FROM> >::type> {
759  static inline shared_vector<TO> op(const shared_vector<FROM>& src) {
761  }
762  };
763  // from non-void to void with same const-ness
764  template<typename TO, typename FROM>
766  typename meta::_and<meta::_and<meta::is_void<TO>, meta::is_not_void<FROM> >,
767  meta::same_const<TO,FROM> >::type> {
768  static FORCE_INLINE shared_vector<TO> op(const shared_vector<FROM>& src) {
770  }
771  };
772 
773  // cast to same type, no-op
774  template<typename TOFRO>
775  struct static_shared_vector_caster<TOFRO,TOFRO,void> {
776  static FORCE_INLINE const shared_vector<TOFRO>& op(const shared_vector<TOFRO>& src) {
777  return src;
778  }
779  };
780 } // namespace detail
781 
789 template<typename TO, typename FROM>
790 static FORCE_INLINE
792 static_shared_vector_cast(const shared_vector<FROM>& src)
793 {
795 }
796 
797 namespace detail {
798 
799  // Default to type conversion using castUnsafe (C++ type casting) on each element
800  template<typename TO, typename FROM, class Enable = void>
802  static inline shared_vector<TO> op(const shared_vector<FROM>& src)
803  {
804  shared_vector<TO> ret(src.size());
805  std::transform(src.begin(), src.end(), ret.begin(), castUnsafe<TO,FROM>);
806  return ret;
807  }
808  };
809 
810  // copy reference when types are the same (excluding const qualifiers)
811  template<typename TO, typename FROM>
812  struct shared_vector_converter<TO,FROM, typename meta::same_root<TO,FROM>::type > {
813  static FORCE_INLINE shared_vector<TO> op(const shared_vector<FROM>& src) {
814  return src;
815  }
816  };
817 
818  // "convert" to 'void' or 'const void from non-void
819  // is an alias for shared_vector_cast<void>()
820  template<typename TO, typename FROM>
821  struct shared_vector_converter<TO,FROM,
822  typename meta::_and<meta::is_void<TO>, meta::is_not_void<FROM> >::type
823  >
824  {
825  static FORCE_INLINE shared_vector<TO> op(const shared_vector<FROM>& src) {
827  }
828  };
829 
830  // convert from void uses original type or throws an exception.
831  template<typename TO, typename FROM>
832  struct shared_vector_converter<TO,FROM,
833  typename meta::_and<meta::is_not_void<TO>, meta::is_void<FROM> >::type
834  >
835  {
836  static shared_vector<TO> op(const shared_vector<FROM>& src) {
837  typedef typename meta::strip_const<TO>::type to_t;
838  ScalarType stype = src.original_type(),
840  if(src.empty()) {
841  return shared_vector<TO>();
842 
843  } else if(stype==dtype) {
844  // no convert needed
846 
847  } else {
848  // alloc and convert
849  shared_vector<to_t> ret(src.size()/ScalarTypeFunc::elementSize(stype));
850  castUnsafeV(ret.size(),
851  dtype,
852  static_cast<void*>(ret.data()),
853  stype,
854  static_cast<const void*>(src.data()));
855  return const_shared_vector_cast<TO>(ret);
856  }
857  }
858  };
859 }
860 
872 template<typename TO, typename FROM>
873 static FORCE_INLINE
875 shared_vector_convert(const shared_vector<FROM>& src)
876 {
878 }
879 
886 template<typename SRC>
887 static FORCE_INLINE
888 shared_vector<typename meta::decorate_const<typename SRC::value_type>::type>
889 freeze(SRC& src)
890 {
891  typedef typename meta::decorate_const<typename SRC::value_type>::type const_value;
892  return shared_vector<const_value>(src, detail::_shared_vector_freeze_tag());
893 }
894 
901 template<typename SRC>
902 static FORCE_INLINE
903 shared_vector<typename meta::strip_const<typename SRC::value_type>::type>
904 thaw(SRC& src)
905 {
906  typedef typename meta::strip_const<typename SRC::value_type>::type value;
907  return shared_vector<value>(src, detail::_shared_vector_thaw_tag());
908 }
909 
910 namespace detail {
911  template<typename TO, typename FROM, class Enable = void>
912  struct const_caster {};
913 
914  template<typename TYPE>
915  struct const_caster<TYPE,const TYPE> {
916  static FORCE_INLINE shared_vector<TYPE> op(shared_vector<const TYPE>& src)
917  {
918  return thaw(src);
919  }
920  };
921 
922  template<typename TYPE>
923  struct const_caster<const TYPE,TYPE> {
924  static FORCE_INLINE shared_vector<const TYPE> op(shared_vector<TYPE>& src)
925  {
926  return freeze(src);
927  }
928  };
929 
930  template<typename TYPE>
931  struct const_caster<TYPE,TYPE> {
932  static FORCE_INLINE shared_vector<TYPE> op(shared_vector<TYPE>& src)
933  {
934  shared_vector<TYPE> ret(src);
935  src.clear();
936  return ret;
937  }
938  };
939 }
940 
942 template<typename TO, typename FROM>
943 static FORCE_INLINE
945 const_shared_vector_cast(shared_vector<FROM>& src)
946 {
948 }
949 
950 
951 namespace ScalarTypeFunc {
953  epicsShareFunc shared_vector<void> allocArray(ScalarType id, size_t len);
954 
956  template<ScalarType ID>
957  inline
958  shared_vector<typename ScalarTypeTraits<ID>::type>
959  allocArray(size_t len)
960  {
961  shared_vector<void> raw(allocArray(ID, len));
962  return static_shared_vector_cast<typename ScalarTypeTraits<ID>::type>(raw);
963  }
964 }
965 
966 }} // namespace epics::pvData
967 
968 // Global operators for shared_vector
969 
970 template<typename A, typename B>
973 {
974  if(a.size() != b.size())
975  return false;
976  if(a.dataOffset()==b.dataOffset() && a.dataPtr().get()==b.dataPtr().get())
977  return true;
978  return std::equal(a.begin(), a.end(), b.begin());
979 }
980 
981 template<typename A, typename B>
984 {
985  return !(a==b);
986 }
987 
988 template<typename E>
989 std::ostream& operator<<(std::ostream& strm, const epics::pvData::shared_vector<E>& arr)
990 {
991  strm<<'{'<<arr.size()<<"}[";
992  for(size_t i=0; i<arr.size(); i++) {
993  if(i>10) {
994  strm<<"...";
995  break;
996  }
997  strm<<arr[i];
998  if(i+1<arr.size())
999  strm<<", ";
1000  }
1001  strm<<']';
1002  return strm;
1003 }
1004 
1005 
1006 #endif // SHAREDVECTOR_H
1007 
shared_vector_base & operator=(const shared_vector_base &o)
Copy an existing vector.
Definition: sharedVector.h:172
A holder for a contiguous piece of memory.
Definition: sharedVector.h:27
shared_vector(size_t c, param_type e)
Allocate (with new[]) a new vector of size c and fill with value e.
Definition: sharedVector.h:334
shared_vector_base(shared_vector< const E > &O, _shared_vector_thaw_tag)
Definition: sharedVector.h:155
directory_iterator end(directory_iterator) noexcept
constexpr bool equal(_II1 __first1, _II1 __last1, _II2 __first2)
size_t size() const
Number of elements visible through this vector.
Definition: sharedVector.h:220
void swap(shared_vector_base &o)
Swap the contents of this vector with another.
Definition: sharedVector.h:199
shared_ptr< _Tp > const_pointer_cast(const shared_ptr< _Up > &__r) noexcept
directory_iterator begin(directory_iterator __iter) noexcept
void resize(size_t i)
Grow or shrink array.
Definition: sharedVector.h:457
shared_vector(A d, B b, size_t o, size_t c)
Build vector from raw pointer and cleanup function.
Definition: sharedVector.h:367
shared_vector< void > allocArray(ScalarType id, size_t len)
Allocate an untyped array based on ScalarType.
reference at(size_t i) const
Member access.
Definition: sharedVector.h:624
bool empty() const
shorthand for size()==0
Definition: sharedVector.h:222
constexpr complex< _Tp > & operator=(const _Tp &)
constexpr _OI move(_II __first, _II __last, _OI __result)
pointer data() const
Return Base pointer.
Definition: sharedVector.h:616
basic_string< char > string
constexpr _Require< __not_< __is_tuple_like< _Tp > >, is_move_constructible< _Tp >, is_move_assignable< _Tp > > swap(_Tp &, _Tp &) noexcept(__and_< is_nothrow_move_constructible< _Tp >, is_nothrow_move_assignable< _Tp > >::value)
void reserve(size_t i)
Set array capacity.
Definition: sharedVector.h:428
constexpr const _Tp * begin(initializer_list< _Tp > __ils) noexcept
shared_vector(const std::tr1::shared_ptr< E1 > &d, size_t o, size_t c)
Build vector from an existing smart pointer.
Definition: sharedVector.h:356
void slice(size_t offset, size_t length=(size_t)-1)
Reduce the view of this shared_vector.
Definition: sharedVector.h:244
shared_ptr< _Tp > static_pointer_cast(const shared_ptr< _Up > &__r) noexcept
shared_vector(size_t c)
Allocate (with new[]) a new vector of size c.
Definition: sharedVector.h:329
constexpr _OutputIterator transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __unary_op)
constexpr _OI copy(_II __first, _II __last, _OI __result)
constexpr _OI fill_n(_OI __first, _Size __n, const _Tp &__value)
reference operator[](size_t i) const
Member access Undefined if empty()==true.
Definition: sharedVector.h:620
shared_vector(const shared_vector &o)
Copy an existing vector of same type.
Definition: sharedVector.h:371
shared_vector()
Empty vector (not very interesting)
Definition: sharedVector.h:315
constexpr void fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp &__value)
constexpr bool operator==(const allocator< _T1 > &, const allocator< _T2 > &) noexcept
void resize(size_t i, param_type v)
Grow (and fill) or shrink array.
Definition: sharedVector.h:498
size_t m_offset
Offset in the data array of first visible element.
Definition: sharedVector.h:61
size_t elementSize(ScalarType id)
gives sizeof(T) where T depends on the scalar type id.
void make_unique()
Ensure (by copying) that this shared_vector is the sole owner of the data array.
Definition: sharedVector.h:526
size_t m_total
Total number of elements between m_offset and the end of data.
Definition: sharedVector.h:65
constexpr const _Tp * end(initializer_list< _Tp > __ils) noexcept
shared_vector_base(shared_vector_base< _E_non_const > &O, _shared_vector_freeze_tag)
Definition: sharedVector.h:136
size_t m_count
Number of visible elements between m_offset and end of data.
Definition: sharedVector.h:63
void clear()
Clear contents. size() becomes 0.
Definition: sharedVector.h:210
shared_vector(A v, size_t o, size_t c)
Build vector from a raw pointer.
Definition: sharedVector.h:347
bool operator!=(const std::bernoulli_distribution &__d1, const std::bernoulli_distribution &__d2)
bool unique() const
Data is not shared?
Definition: sharedVector.h:216
shared_vector_base()
Empty vector (not very interesting)
Definition: sharedVector.h:80