14 #if __cplusplus>=201103L 15 # include <initializer_list> 25 namespace epics {
namespace pvData {
29 template<
typename TO,
typename FROM>
42 {
typedef const std::tr1::shared_ptr<T>&
type; };
73 #if __cplusplus>=201103L 76 :m_sdata(), m_offset(0), m_count(0), m_total(0)
81 :m_sdata(), m_offset(0), m_count(0), m_total(0)
91 m_offset = m_total = m_count = 0;
94 assert( m_offset <= ((
size_t)-1) - m_total);
102 ,m_offset(o), m_count(c), m_total(c)
106 :m_sdata(d), m_offset(o), m_count(c), m_total(c)
110 template<
typename A,
typename B>
112 :m_sdata(d,b), m_offset(o), m_count(c), m_total(c)
116 :m_sdata(O.m_sdata), m_offset(O.m_offset)
117 ,m_count(O.m_count), m_total(O.m_total)
120 #if __cplusplus >= 201103L 122 :m_sdata(std::move(O.m_sdata))
123 ,m_offset(O.m_offset)
139 ,m_offset(O.m_offset)
144 throw std::runtime_error(
"Can't freeze non-unique vector");
145 #if __cplusplus >= 201103L 146 m_sdata = std::move(O.
m_sdata);
158 ,m_offset(O.m_offset)
163 #if __cplusplus >= 201103L 164 m_sdata = std::move(std::tr1::const_pointer_cast<E>(O.
m_sdata));
183 #if __cplusplus >= 201103L 188 m_sdata=std::move(o.m_sdata);
212 m_offset = m_total = m_count = 0;
216 bool unique()
const {
return !m_sdata || m_sdata.use_count()<=1;}
220 size_t size()
const{
return m_count;}
222 bool empty()
const{
return !m_count;}
244 void slice(
size_t offset,
size_t length=(
size_t)-1)
249 const size_t max_count = m_count - offset;
255 if(length > max_count)
261 const std::tr1::shared_ptr<E>&
dataPtr()
const {
return m_sdata; }
286 template<
typename E,
class Enable>
312 #if __cplusplus>=201103L 318 #if __cplusplus>=201103L 321 :base_t(
new _E_non_const[L.size()], 0, L.size())
323 _E_non_const *raw =
const_cast<_E_non_const*
>(data());
330 :base_t(new _E_non_const[c], 0, c)
335 :base_t(new _E_non_const[c], 0, c)
337 std::fill_n((_E_non_const*)this->m_sdata.get(), this->m_count, e);
355 template<
typename E1>
366 template<
typename A,
typename B>
373 #if __cplusplus>=201103L 380 template<
typename FROM>
384 src.dataOffset()/sizeof(E),
385 src.dataCount()/sizeof(E))
401 this->base_t::operator=(o);
405 #if __cplusplus>=201103L 408 this->base_t::operator=(std::move(o));
413 size_t max_size()
const{
return ((
size_t)-1)/
sizeof(E);}
429 if(this->unique() && i<=this->m_total)
431 size_t new_count = this->m_count;
434 _E_non_const* temp=
new _E_non_const[
i];
443 this->m_count = new_count;
458 if(i==this->m_count) {
462 if(this->m_sdata && this->m_sdata.use_count()==1) {
464 if(i<=this->m_total) {
471 size_t new_total = this->m_total;
474 _E_non_const* temp=
new _E_non_const[new_total];
476 size_t n = this->size();
491 this->m_total = new_total;
499 size_t oldsize=this->size();
501 if(this->size()>oldsize) {
502 std::fill(
begin()+oldsize, end(), v);
530 _E_non_const *d =
new _E_non_const[this->m_total];
532 std::copy(this->m_sdata.get()+this->m_offset,
533 this->m_sdata.get()+this->m_offset+this->m_count,
550 inline E* base_ptr()
const {
551 #if defined(_MSC_VER) && _MSC_VER<=1600 552 return this->m_count ? this->m_sdata.get() : (E*)(
this-1);
554 return this->m_sdata.get();
560 iterator
begin()
const{
return this->base_ptr()+this->m_offset;}
563 iterator
end()
const{
return this->base_ptr()+this->m_offset+this->m_count;}
564 const_iterator
cend()
const{
return end();}
566 reverse_iterator
rbegin()
const{
return reverse_iterator(end());}
567 const_reverse_iterator
crbegin()
const{
return rbegin();}
569 reverse_iterator
rend()
const{
return reverse_iterator(
begin());}
570 const_reverse_iterator
crend()
const{
return rend();}
572 reference
front()
const{
return (*
this)[0];}
573 reference
back()
const{
return (*
this)[this->m_count-1];}
578 void _push_resize() {
579 if(this->m_count==this->m_total || !this->unique()) {
581 if(this->m_total<1024) {
583 next = this->m_total;
591 next = this->m_total+1024;
594 assert(next > this->m_total);
597 resize(this->size()+1);
610 this->slice(0, this->size()-1);
616 pointer
data()
const{
return this->m_sdata.get()+this->m_offset;}
620 reference
operator[](
size_t i)
const {
return this->m_sdata.get()[this->m_offset+
i];}
624 reference
at(
size_t i)
const 627 throw std::out_of_range(
"Index out of bounds");
670 #if __cplusplus>=201103L 683 template<
typename E1>
688 :base_t(o), m_vtype(o.m_vtype) {}
690 #if __cplusplus>=201103L 692 :base_t(std::move(o)), m_vtype(o.m_vtype) {}
697 template<
typename FROM>
701 src.dataOffset()*sizeof(FROM),
702 src.dataCount()*sizeof(FROM))
708 :base_t(O,t), m_vtype(O.m_vtype)
713 :base_t(O,t), m_vtype(O.m_vtype)
719 this->base_t::operator=(o);
725 #if __cplusplus>=201103L 729 this->base_t::operator=(std::move(o));
744 return (pointer)(((
char*)this->m_sdata.get())+this->m_offset);
752 template<
typename TO,
typename FROM,
class Enable =
void>
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> {
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> {
774 template<
typename TOFRO>
789 template<
typename TO,
typename FROM>
800 template<
typename TO,
typename FROM,
class Enable =
void>
805 std::transform(src.
begin(), src.
end(), ret.begin(), castUnsafe<TO,FROM>);
811 template<
typename TO,
typename FROM>
820 template<
typename TO,
typename FROM>
822 typename meta::_and<meta::is_void<TO>, meta::is_not_void<FROM> >
::type 831 template<
typename TO,
typename FROM>
833 typename meta::_and<meta::is_not_void<TO>, meta::is_void<FROM> >
::type 848 static_cast<void*
>(ret.data()),
850 static_cast<const void*>(src.
data()));
851 return const_shared_vector_cast<TO>(ret);
868 template<
typename TO,
typename FROM>
882 template<
typename SRC>
897 template<
typename SRC>
907 template<
typename TO,
typename FROM,
class Enable =
void>
910 template<
typename TYPE>
918 template<
typename TYPE>
926 template<
typename TYPE>
938 template<
typename TO,
typename FROM>
947 namespace ScalarTypeFunc {
952 template<ScalarType ID>
966 template<
typename A,
typename B>
977 template<
typename A,
typename B>
985 std::ostream& operator<<(std::ostream& strm, const epics::pvData::shared_vector<E>& arr)
987 strm<<
'{'<<arr.size()<<
"}[";
988 for(
size_t i=0;
i<arr.size();
i++) {
1002 #endif // SHAREDVECTOR_H meta::decorate_const< E >::type & const_reference
shared_vector_base & operator=(const shared_vector_base &o)
Copy an existing vector.
void make_unique()
Ensure (by copying) that this shared_vector is the sole owner of the data array.
void resize(size_t i)
Grow or shrink array.
meta::decorate_const< E >::type * const_pointer
#define assert(exp)
Declare that a condition should be true.
const std::tr1::shared_ptr< T > & type
size_t elementSize(ScalarType id)
gives sizeof(T) where T depends on the scalar type id.
bool empty() const
shorthand for size()==0
A holder for a contiguous piece of memory.
pointer data() const
Return Base pointer.
shared_vector()
Empty vector (not very interesting)
shared_vector(const std::tr1::shared_ptr< E1 > &d, size_t o, size_t c)
Build vector from an existing smart pointer.
const_reverse_iterator crend() const
shared_vector(size_t c, param_type e)
Allocate (with new[]) a new vector of size c and fill with value e.
shared_ptr< T > static_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
size_t m_count
Number of visible elements between m_offset and end of data.
shared_vector_base(const shared_vector_base &O)
static FORCE_INLINE shared_vector< TYPE > op(shared_vector< const TYPE > &src)
void resize(size_t i, param_type v)
Grow (and fill) or shrink array.
pvd::StructureConstPtr type
shared_vector_base(A d, B b, size_t o, size_t c)
reverse_iterator rbegin() const
TODO only here because of the Lockable.
shared_vector_base(A *v, size_t o, size_t c)
static shared_vector< TO > op(const shared_vector< FROM > &src)
static FORCE_INLINE shared_vector< TYPE > op(shared_vector< TYPE > &src)
shared_vector(A d, B b, size_t o, size_t c)
Build vector from raw pointer and cleanup function.
void clear()
Clear contents. size() becomes 0.
static shared_vector< TO > op(const shared_vector< FROM > &src)
ptrdiff_t difference_type
static shared_vector< TO > op(const shared_vector< FROM > &src)
static FORCE_INLINE shared_vector< TO > op(const shared_vector< FROM > &src)
size_t m_offset
Offset in the data array of first visible element.
void copy(PVValueArray< T > &pvFrom, size_t fromOffset, size_t fromStride, PVValueArray< T > &pvTo, size_t toOffset, size_t toStride, size_t count)
Copy a subarray from one scalar array to another.
shared_vector(shared_vector< const E > &O, detail::_shared_vector_thaw_tag t)
shared_vector & operator=(const shared_vector &o)
void push_back(param_type v)
shared_vector< typename ScalarTypeTraits< ID >::type > allocArray(size_t len)
Allocate an untyped array based on ScalarType.
const_iterator cend() const
shared_vector_base(shared_vector_base< _E_non_const > &O, _shared_vector_freeze_tag)
void swap(shared_vector_base &o)
Swap the contents of this vector with another.
bool unique() const
Data is not shared?
meta::decorate_const< E >::type * const_iterator
static FORCE_INLINE const shared_vector< TOFRO > & op(const shared_vector< TOFRO > &src)
meta::strip_const< E >::type _E_non_const
static FORCE_INLINE shared_vector< TO > op(const shared_vector< FROM > &src)
size_t dataOffset() const
std::reverse_iterator< iterator > reverse_iterator
size_t size() const
Number of elements visible through this vector.
shared_vector(shared_vector< typename base_t::_E_non_const > &O, detail::_shared_vector_freeze_tag t)
shared_vector(size_t c)
Allocate (with new[]) a new vector of size c.
shared_vector(A v, size_t o, size_t c)
Build vector from a raw pointer.
bool operator==(const PVField &left, const PVField &right)
shared_vector_base(shared_vector< const E > &O, _shared_vector_thaw_tag)
epicsShareExtern void castUnsafeV(size_t count, ScalarType to, void *dest, ScalarType from, const void *src)
shared_vector_base(const std::tr1::shared_ptr< E > &d, size_t o, size_t c)
const std::tr1::shared_ptr< E > & dataPtr() const
shared_vector(const shared_vector &o)
Copy an existing vector of same type.
static FORCE_INLINE shared_vector< TO > op(const shared_vector< FROM > &src)
reverse_iterator rend() const
void swap(shared_ptr< T > &a, shared_ptr< T > &b) BOOST_NOEXCEPT
reference operator[](size_t i) const
Member access Undefined if empty()==true.
size_t m_total
Total number of elements between m_offset and the end of data.
void slice(size_t offset, size_t length=(size_t)-1)
Reduce the view of this shared_vector.
ChannelPut::shared_pointer op
std::tr1::shared_ptr< E > shared_pointer_type
shared_ptr< T > const_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
static FORCE_INLINE shared_vector< const TYPE > op(shared_vector< TYPE > &src)
const_reverse_iterator crbegin() const
void reserve(size_t i)
Set array capacity.
const_iterator cbegin() const
std::reverse_iterator< const_iterator > const_reverse_iterator
reference at(size_t i) const
Member access.
shared_vector(const shared_vector< FROM > &src, detail::_shared_vector_cast_tag)
std::tr1::shared_ptr< E > m_sdata