14 #if __cplusplus>=201103L
21 #include "pv/pvIntrospect.h"
22 #include "pv/typeCast.h"
23 #include "pv/templateMeta.h"
25 namespace epics {
namespace pvData {
29 template<
typename TO,
typename FROM>
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; };
59 std::tr1::shared_ptr<E> m_sdata;
73 #if __cplusplus>=201103L
101 :m_sdata(v, detail::default_array_deleter<A*>())
110 template<
typename A,
typename B>
120 #if __cplusplus >= 201103L
122 :m_sdata(std::
move(O.m_sdata))
132 typedef typename meta::strip_const<E>::type _E_non_const;
145 #if __cplusplus >= 201103L
163 #if __cplusplus >= 201103L
164 m_sdata =
std::move(std::tr1::const_pointer_cast<E>(O.m_sdata));
183 #if __cplusplus >= 201103L
201 m_sdata.swap(o.m_sdata);
216 bool unique()
const {
return !m_sdata || m_sdata.use_count()<=1;}
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; }
262 size_t dataOffset()
const {
return m_offset; }
263 size_t dataCount()
const {
return m_count; }
264 size_t dataTotal()
const {
return m_total; }
286 template<
typename E,
class Enable>
287 class shared_vector :
public detail::shared_vector_base<E>
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;
293 typedef E value_type;
294 typedef E& reference;
295 typedef typename meta::decorate_const<E>::type& const_reference;
297 typedef typename meta::decorate_const<E>::type* const_pointer;
300 typedef typename meta::decorate_const<E>::type* const_iterator;
302 typedef ptrdiff_t difference_type;
303 typedef size_t size_type;
305 typedef E element_type;
306 typedef std::tr1::shared_ptr<E> shared_pointer_type;
309 template<
typename E1,
class Enable1>
friend class shared_vector;
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)
355 template<
typename E1>
366 template<
typename A,
typename B>
373 #if __cplusplus>=201103L
380 template<
typename FROM>
382 detail::_shared_vector_cast_tag)
384 src.dataOffset()/sizeof(E),
385 src.dataCount()/sizeof(E))
389 shared_vector(shared_vector<typename base_t::_E_non_const>& O,
390 detail::_shared_vector_freeze_tag t)
395 detail::_shared_vector_thaw_tag t)
405 #if __cplusplus>=201103L
413 size_t max_size()
const{
return ((
size_t)-1)/
sizeof(E);}
415 size_t capacity()
const {
return this->
m_total; }
431 size_t new_count = this->
m_count;
434 _E_non_const* temp=
new _E_non_const[i];
462 if(this->m_sdata && this->m_sdata.use_count()==1) {
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();
499 size_t oldsize=this->
size();
501 if(this->
size()>oldsize) {
530 _E_non_const *d =
new _E_non_const[this->
m_total];
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);
554 return this->m_sdata.get();
560 iterator
begin()
const{
return this->base_ptr()+this->
m_offset;}
561 const_iterator cbegin()
const{
return begin();}
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() {
602 void push_back(param_type v)
624 reference
at(
size_t i)
const
661 template<
typename E1,
class Enable1>
friend class shared_vector;
663 typedef E value_type;
665 typedef ptrdiff_t difference_type;
666 typedef size_t size_type;
668 typedef std::tr1::shared_ptr<E> shared_pointer_type;
670 #if __cplusplus>=201103L
683 template<
typename E1>
684 shared_vector(
const std::tr1::shared_ptr<E1>& d,
size_t o,
size_t c)
688 :
base_t(o), m_vtype(o.m_vtype) {}
690 #if __cplusplus>=201103L
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))
708 :
base_t(O,t), m_vtype(O.m_vtype)
713 :
base_t(O,t), m_vtype(O.m_vtype)
725 #if __cplusplus>=201103L
741 size_t max_size()
const{
return (
size_t)-1;}
743 pointer
data()
const{
744 return (pointer)(((
char*)this->m_sdata.get())+this->
m_offset);
748 ScalarType original_type()
const {
return m_vtype;}
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
837 typedef typename meta::strip_const<TO>::type to_t;
843 }
else if(stype==dtype) {
850 castUnsafeV(ret.size(),
852 static_cast<void*
>(ret.data()),
854 static_cast<const void*>(src.data()));
855 return const_shared_vector_cast<TO>(ret);
872 template<
typename TO,
typename FROM>
886 template<
typename SRC>
888 shared_vector<typename meta::decorate_const<typename SRC::value_type>::type>
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());
901 template<
typename SRC>
903 shared_vector<typename meta::strip_const<typename SRC::value_type>::type>
906 typedef typename meta::strip_const<typename SRC::value_type>::type value;
907 return shared_vector<value>(src, detail::_shared_vector_thaw_tag());
911 template<
typename TO,
typename FROM,
class Enable =
void>
914 template<
typename TYPE>
922 template<
typename TYPE>
930 template<
typename TYPE>
942 template<
typename TO,
typename FROM>
951 namespace ScalarTypeFunc {
956 template<ScalarType ID>
958 shared_vector<typename ScalarTypeTraits<ID>::type>
970 template<
typename A,
typename B>
976 if(a.dataOffset()==b.dataOffset() && a.dataPtr().get()==b.dataPtr().get())
978 return std::equal(a.begin(), a.end(), b.begin());
981 template<
typename A,
typename B>
989 std::ostream& operator<<(std::ostream& strm, const epics::pvData::shared_vector<E>& arr)
991 strm<<
'{'<<arr.size()<<
"}[";
992 for(
size_t i=0; i<arr.size(); i++) {
1006 #endif // SHAREDVECTOR_H
shared_vector_base & operator=(const shared_vector_base &o)
Copy an existing vector.
A holder for a contiguous piece of memory.
shared_vector(size_t c, param_type e)
Allocate (with new[]) a new vector of size c and fill with value e.
shared_vector_base(shared_vector< const E > &O, _shared_vector_thaw_tag)
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.
void swap(shared_vector_base &o)
Swap the contents of this vector with another.
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.
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.
reference at(size_t i) const
Member access.
bool empty() const
shorthand for size()==0
constexpr complex< _Tp > & operator=(const _Tp &)
constexpr _OI move(_II __first, _II __last, _OI __result)
pointer data() const
Return Base pointer.
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.
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.
void slice(size_t offset, size_t length=(size_t)-1)
Reduce the view of this shared_vector.
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.
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.
shared_vector(const shared_vector &o)
Copy an existing vector of same type.
shared_vector()
Empty vector (not very interesting)
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.
size_t m_offset
Offset in the data array of first visible element.
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.
size_t m_total
Total number of elements between m_offset and the end of data.
constexpr const _Tp * end(initializer_list< _Tp > __ils) noexcept
shared_vector_base(shared_vector_base< _E_non_const > &O, _shared_vector_freeze_tag)
size_t m_count
Number of visible elements between m_offset and end of data.
void clear()
Clear contents. size() becomes 0.
shared_vector(A v, size_t o, size_t c)
Build vector from a raw pointer.
bool operator!=(const std::bernoulli_distribution &__d1, const std::bernoulli_distribution &__d2)
bool unique() const
Data is not shared?
shared_vector_base()
Empty vector (not very interesting)