This is Unofficial EPICS BASE Doxygen Site
epics::pvData::AnyScalar Class Reference

#include "anyscalar.h"

Classes

struct  bad_cast
 

Public Member Functions

 AnyScalar ()
 
template<typename T >
 AnyScalar (T v)
 Construct from provided value. More...
 
 AnyScalar (ScalarType type, const void *buf)
 
 AnyScalar (const AnyScalar &o)
 
 ~AnyScalar ()
 
AnyScalaroperator= (const AnyScalar &o)
 
template<typename T >
AnyScalaroperator= (T v)
 
void clear ()
 
void swap (AnyScalar &o)
 
ScalarType type () const
 Type code of contained value. Or (ScalarType)-1 is empty. More...
 
void * unsafe ()
 
const void * unsafe () const
 
bool empty () const
 
 operator bool_type () const
 
const void * bufferUnsafe () const
 
template<typename T >
detail::any_storage_type< typename meta::strip_const< T >::type >::typeref ()
 
template<typename T >
meta::decorate_const< typename detail::any_storage_type< typename meta::strip_const< T >::type >::type >::typeref () const
 
template<typename T >
as () const
 

Friends

epicsShareFunc std::ostream & operator<< (std::ostream &strm, const AnyScalar &v)
 

Detailed Description

A type-safe variant union capable of holding any of the PVD scalar types (POD or string)

AnyScalar A(5);
assert(A.type()==pvInt);
assert(A.ref<int32>()==5);
assert(A.as<int32>()==5);
assert(A.as<double>()==5.0);
assert(A.ref<double>()==5.0); // throws AnyScalar::bad_cast

Definition at line 51 of file anyscalar.h.

Constructor & Destructor Documentation

epics::pvData::AnyScalar::AnyScalar ( )
inline

Construct empty

Postcondition
empty()==true

Definition at line 100 of file anyscalar.h.

100 : _stype((ScalarType)-1) {}
template<typename T >
epics::pvData::AnyScalar::AnyScalar ( v)
inlineexplicit

Construct from provided value.

Definition at line 104 of file anyscalar.h.

105  {
106  typedef typename meta::strip_const<T>::type T2;
107  typedef typename detail::any_storage_type<T2>::type TT;
108 
109  STATIC_ASSERT(sizeof(TT)<=sizeof(_wrap.blob));
110 
111  new (_wrap.blob) TT(v);
112 
113  // this line fails to compile when type T can't be mapped to one of
114  // the PVD scalar types.
115  _stype = (ScalarType)ScalarTypeID<TT>::value;
116  }
#define STATIC_ASSERT(expr)
Declare a condition that should be true at compile-time.
Definition: epicsAssert.h:86
epics::pvData::AnyScalar::AnyScalar ( ScalarType  type,
const void *  buf 
)

Construct from un-typed pointer. Caller is responsible to ensure that buf actually points to the provided type

Version
Added after 7.0.0

Definition at line 11 of file anyscalar.cpp.

12 {
13  if(type==pvString) {
14  new (_wrap.blob) std::string(*static_cast<const std::string*>(buf));
15 
16  } else {
17  memcpy(_wrap.blob, buf, ScalarTypeFunc::elementSize(type));
18  }
19 
20  _stype = type;
21 }
size_t elementSize(ScalarType id)
gives sizeof(T) where T depends on the scalar type id.
Definition: TypeFunc.cpp:82
ScalarType type() const
Type code of contained value. Or (ScalarType)-1 is empty.
Definition: anyscalar.h:158
epics::pvData::AnyScalar::AnyScalar ( const AnyScalar o)

Definition at line 23 of file anyscalar.cpp.

24  :_stype(o._stype)
25 {
26  if(o._stype==pvString) {
27  new (_wrap.blob) std::string(o._as<std::string>());
28  } else if(o._stype!=(ScalarType)-1) {
29  memcpy(_wrap.blob, o._wrap.blob, sizeof(_largest_blob));
30  }
31 }
epics::pvData::AnyScalar::~AnyScalar ( )
inline

Definition at line 129 of file anyscalar.h.

129 {clear();}

Member Function Documentation

template<typename T >
T epics::pvData::AnyScalar::as ( ) const
inline

copy out wrapped value, with a value conversion.

Exceptions
bad_castwhen empty()==true

Definition at line 230 of file anyscalar.h.

230  {
231  typedef typename meta::strip_const<T>::type T2;
232  typedef typename detail::any_storage_type<T2>::type TT;
233 
234  if(_stype==(ScalarType)-1)
235  throw bad_cast();
236  TT ret;
237  castUnsafeV(1, (ScalarType)ScalarTypeID<T2>::value, &ret,
238  _stype, _wrap.blob);
239  return ret;
240  }
epicsShareExtern void castUnsafeV(size_t count, ScalarType to, void *dest, ScalarType from, const void *src)
Definition: typeCast.cpp:72
const void * epics::pvData::AnyScalar::bufferUnsafe ( ) const

Provide read-only access to underlying buffer. For a string this is std::string::c_str().

Version
Added after 7.0.0

Definition at line 137 of file anyscalar.cpp.

137  {
138  if(_stype==pvString) {
139  return as<std::string>().c_str();
140  } else {
141  return _wrap.blob;
142  }
143 }
void epics::pvData::AnyScalar::clear ( )

Reset internal state.

Version
Added after 7.0.0
Postcondition
empty()==true

Definition at line 49 of file anyscalar.cpp.

49  {
50  if(_stype==pvString) {
51  typedef std::string string;
52  _as<string>().~string();
53  }
54  // other types need no cleanup
55  _stype = (ScalarType)-1;
56 }
bool epics::pvData::AnyScalar::empty ( ) const
inline

Definition at line 165 of file anyscalar.h.

165 { return _stype==(ScalarType)-1; }
epics::pvData::AnyScalar::operator bool_type ( ) const
inline

Definition at line 173 of file anyscalar.h.

173 { return !empty() ? &AnyScalar::swap : 0; }
bool empty() const
Definition: anyscalar.h:165
void swap(AnyScalar &o)
Definition: anyscalar.cpp:58
AnyScalar& epics::pvData::AnyScalar::operator= ( const AnyScalar o)
inline

Definition at line 131 of file anyscalar.h.

131  {
132  AnyScalar(o).swap(*this);
133  return *this;
134  }
template<typename T >
AnyScalar& epics::pvData::AnyScalar::operator= ( v)
inline

Definition at line 137 of file anyscalar.h.

137  {
138  AnyScalar(v).swap(*this);
139  return *this;
140  }
template<typename T >
detail::any_storage_type<typename meta::strip_const<T>::type>::type& epics::pvData::AnyScalar::ref ( )
inline

Return typed reference to wrapped value. Non-const reference allows value modification

Exceptions
bad_castwhen the requested type does not match the stored type
AnyScalar v(42);
v.ref<uint32>() = 43;
assert(v.ref<uint32>() == 43);

Definition at line 194 of file anyscalar.h.

194  {
195  typedef typename meta::strip_const<T>::type T2;
196  typedef typename detail::any_storage_type<T2>::type TT;
197 
198  if(_stype!=(ScalarType)ScalarTypeID<TT>::value)
199  throw bad_cast();
200  return reinterpret_cast<TT&>(_wrap.blob);
201  }
template<typename T >
meta::decorate_const<typename detail::any_storage_type<typename meta::strip_const<T>::type>::type>::type& epics::pvData::AnyScalar::ref ( ) const
inline

Return typed reference to wrapped value. Const reference does not allow modification.

Exceptions
bad_castwhen the requested type does not match the stored type
const AnyScalar v(42);
assert(v.ref<uint32>() == 42);

Definition at line 215 of file anyscalar.h.

215  {
216  typedef typename meta::strip_const<T>::type T2;
217  typedef typename detail::any_storage_type<T2>::type TT;
218 
219  if(_stype!=(ScalarType)ScalarTypeID<TT>::value)
220  throw bad_cast();
221  return reinterpret_cast<typename meta::decorate_const<TT>::type&>(_wrap.blob);
222  }
void epics::pvData::AnyScalar::swap ( AnyScalar o)

Definition at line 58 of file anyscalar.cpp.

58  {
59  typedef std::string string;
60  switch((int)_stype) {
61  case -1:
62  switch((int)o._stype) {
63  case -1:
64  // nil <-> nil
65  break;
66  case pvString:
67  // nil <-> string
68  new (_wrap.blob) std::string();
69  _as<std::string>().swap(o._as<std::string>());
70  o._as<std::string>().~string();
71  break;
72  default:
73  // nil <-> non-string
74  memcpy(_wrap.blob, o._wrap.blob, sizeof(_largest_blob));
75  break;
76  }
77  break;
78  case pvString:
79  switch((int)o._stype) {
80  case -1:
81  // string <-> nil
82  new (o._wrap.blob) std::string();
83  _as<std::string>().swap(o._as<std::string>());
84  _as<std::string>().~string();
85  break;
86  case pvString:
87  // string <-> string
88  _as<std::string>().swap(o._as<std::string>());
89  break;
90  default: {
91  // string <-> non-string
92  std::string temp;
93  temp.swap(_as<std::string>());
94 
95  _as<std::string>().~string();
96 
97  memcpy(_wrap.blob, o._wrap.blob, sizeof(_largest_blob));
98 
99  new (o._wrap.blob) std::string();
100  temp.swap(o._as<std::string>());
101  }
102  break;
103  }
104  break;
105  default:
106  switch((int)o._stype) {
107  case -1:
108  // non-string <-> nil
109  memcpy(o._wrap.blob, _wrap.blob, sizeof(_largest_blob));
110  break;
111  case pvString: {
112  // non-string <-> string
113  std::string temp;
114  temp.swap(o._as<std::string>());
115 
116  o._as<std::string>().~string();
117 
118  memcpy(o._wrap.blob, _wrap.blob, sizeof(_largest_blob));
119 
120  new (_wrap.blob) std::string();
121  temp.swap(_as<std::string>());
122  }
123  break;
124  default:
125  // non-string <-> non-string
126  _largest_blob temp;
127  memcpy(&temp, _wrap.blob, sizeof(_largest_blob));
128  memcpy(_wrap.blob, o._wrap.blob, sizeof(_largest_blob));
129  memcpy(o._wrap.blob, &temp, sizeof(_largest_blob));
130  // std::swap(o._wrap.blob, _wrap.blob); // gcc <=4.3 doesn't like this
131  break;
132  }
133  break;
134  }
135  std::swap(_stype, o._stype);
136 }
void swap(shared_ptr< T > &a, shared_ptr< T > &b) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:783
void swap(AnyScalar &o)
Definition: anyscalar.cpp:58
ScalarType epics::pvData::AnyScalar::type ( ) const
inline

Type code of contained value. Or (ScalarType)-1 is empty.

Definition at line 158 of file anyscalar.h.

158  {
159  return _stype;
160  }
void* epics::pvData::AnyScalar::unsafe ( )
inline

Definition at line 162 of file anyscalar.h.

162 { return _wrap.blob; }
const void* epics::pvData::AnyScalar::unsafe ( ) const
inline

Definition at line 163 of file anyscalar.h.

163 { return _wrap.blob; }

Friends And Related Function Documentation

epicsShareFunc std::ostream& operator<< ( std::ostream &  strm,
const AnyScalar v 
)
friend

Definition at line 145 of file anyscalar.cpp.

146 {
147  switch(v.type()) {
148 #define CASE(BASETYPE, PVATYPE, DBFTYPE, PVACODE) case pv ## PVACODE: strm<<v._as<PVATYPE>(); break;
149 #define CASE_REAL_INT64
150 #define CASE_STRING
151 #include "pv/typemap.h"
152 #undef CASE
153 #undef CASE_REAL_INT64
154 #undef CASE_STRING
155  default:
156  strm<<"(nil)"; break;
157  }
158  return strm;
159 }

The documentation for this class was generated from the following files: