PVData C++ 8.0.7
Loading...
Searching...
No Matches
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
25namespace epics { namespace pvData {
26
27template<typename E, class Enable = void> class shared_vector;
28
29template<typename TO, typename FROM>
30static FORCE_INLINE
31shared_vector<TO>
32const_shared_vector_cast(shared_vector<FROM>& src);
33
34namespace 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
75 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
115 shared_vector_base(const shared_vector_base& O)
116 :m_sdata(O.m_sdata), m_offset(O.m_offset)
118 {}
119
120#if __cplusplus >= 201103L
121 shared_vector_base(shared_vector_base &&O)
122 :m_sdata(std::move(O.m_sdata))
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()
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()
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;
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
286template<typename E, class Enable>
288{
290 typedef typename detail::call_with<E>::type param_type;
291 typedef typename meta::strip_const<E>::type _E_non_const;
292public:
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;
300 typedef typename meta::decorate_const<E>::type* const_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
375 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
406 inline shared_vector& operator=(shared_vector&& o)
407 {
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
543private:
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 }
557public:
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
577private:
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
600public:
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
653template<typename E>
654class shared_vector<E, typename meta::is_void<E>::type >
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;
662public:
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
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) {
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
751namespace 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
789template<typename TO, typename FROM>
790static FORCE_INLINE
792static_shared_vector_cast(const shared_vector<FROM>& src)
793{
795}
796
797namespace 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>
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>
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
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
872template<typename TO, typename FROM>
873static FORCE_INLINE
875shared_vector_convert(const shared_vector<FROM>& src)
876{
878}
879
886template<typename SRC>
887static FORCE_INLINE
888shared_vector<typename meta::decorate_const<typename SRC::value_type>::type>
889freeze(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
901template<typename SRC>
902static FORCE_INLINE
903shared_vector<typename meta::strip_const<typename SRC::value_type>::type>
904thaw(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
910namespace 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
942template<typename TO, typename FROM>
943static FORCE_INLINE
945const_shared_vector_cast(shared_vector<FROM>& src)
946{
948}
949
950
951namespace ScalarTypeFunc {
953 epicsShareFunc shared_vector<void> allocArray(ScalarType id, size_t len);
954
956 template<ScalarType ID>
957 inline
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
970template<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
981template<typename A, typename B>
984{
985 return !(a==b);
986}
987
988template<typename E>
989std::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
constexpr complex< _Tp > & operator=(const _Tp &)
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)
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
slice()
constexpr void fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp &__value)
constexpr _OI copy(_II __first, _II __last, _OI __result)
constexpr _OutputIterator transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __unary_op)
constexpr _OI move(_II __first, _II __last, _OI __result)
constexpr _OI fill_n(_OI __first, _Size __n, const _Tp &__value)
constexpr bool equal(_II1 __first1, _II1 __last1, _II2 __first2)
basic_string< char > string
bool operator!=(const multimap< _Key, _Tp, _Compare, _Alloc > &__x, const multimap< _Key, _Tp, _Compare, _Alloc > &__y)
basic_ostream< _CharT, _Traits > & operator<<(basic_ostream< _CharT, _Traits > &__os, const basic_string< _CharT, _Traits, _Alloc > &__str)
__shared_ptr< _Tp, _Lp > static_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
constexpr bool operator==(const basic_string< _CharT, _Traits, _Alloc > &__lhs, const _CharT *__rhs)
constexpr const _Tp * begin(initializer_list< _Tp > __ils) noexcept
constexpr const _Tp * end(initializer_list< _Tp > __ils) noexcept
size_t size() const
Number of elements visible through this vector.
size_t m_total
Total number of elements between m_offset and the end of data.
shared_vector_base()
Empty vector (not very interesting)
shared_vector_base(shared_vector_base< _E_non_const > &O, _shared_vector_freeze_tag)
shared_vector_base & operator=(const shared_vector_base &o)
Copy an existing vector.
bool unique() const
Data is not shared?
void swap(shared_vector_base &o)
Swap the contents of this vector with another.
shared_vector_base(shared_vector< const E > &O, _shared_vector_thaw_tag)
size_t m_count
Number of visible elements between m_offset and end of data.
bool empty() const
shorthand for size()==0
void slice(size_t offset, size_t length=(size_t) -1)
Reduce the view of this shared_vector.
size_t m_offset
Offset in the data array of first visible element.
void clear()
Clear contents. size() becomes 0.
A holder for a contiguous piece of memory.
shared_vector()
Empty vector (not very interesting)
pointer data() const
Return Base pointer.
void make_unique()
Ensure (by copying) that this shared_vector is the sole owner of the data array.
void resize(size_t i, param_type v)
Grow (and fill) or shrink array.
reference at(size_t i) const
Member access.
shared_vector(A v, size_t o, size_t c)
Build vector from a raw pointer.
shared_vector(const std::tr1::shared_ptr< E1 > &d, size_t o, size_t c)
Build vector from an existing smart pointer.
shared_vector(const shared_vector &o)
Copy an existing vector of same type.
void reserve(size_t i)
Set array capacity.
void resize(size_t i)
Grow or shrink array.
shared_vector(size_t c)
Allocate (with new[]) a new vector of size c.
shared_vector(size_t c, param_type e)
Allocate (with new[]) a new vector of size c and fill with value e.
reference operator[](size_t i) const
Member access Undefined if empty()==true.
shared_vector(A d, B b, size_t o, size_t c)
Build vector from raw pointer and cleanup function.
shared_vector< void > allocArray(ScalarType id, size_t len)
Allocate an untyped array based on ScalarType.
size_t elementSize(ScalarType id)
gives sizeof(T) where T depends on the scalar type id.
epics
Definition convert.h:21