PVData C++
8.0.9
Toggle main menu visibility
Loading...
Searching...
No Matches
misc
pv
anyscalar.h
1
#ifndef PV_ANYSCALAR_H
2
#define PV_ANYSCALAR_H
3
4
#if __cplusplus>=201103L
5
# include <
type_traits
>
6
#endif
7
8
#include <
ostream
>
9
#include <
exception
>
10
#include <
map
>
11
12
#include <epicsAssert.h>
13
14
#include <pv/templateMeta.h>
15
#include <pv/typeCast.h>
16
#include <pv/pvIntrospect.h>
/* for ScalarType enum */
17
18
namespace
epics
{
namespace
pvData
{
19
namespace
detail {
20
21
// special mangling for AnyScalar ctor to map from argument type to storage type.
22
// allow construction from constants.
23
template
<
typename
T>
24
struct
any_storage_type
{
typedef
T type; };
25
template
<>
struct
any_storage_type
<int> {
typedef
int32
type; };
26
template
<>
struct
any_storage_type
<unsigned> {
typedef
uint32
type; };
27
template
<>
struct
any_storage_type
<char*> {
typedef
std::string
type; };
28
template
<>
struct
any_storage_type
<const char*> {
typedef
std::string
type; };
29
30
#if __cplusplus>=201103L
31
// std::max() isn't constexpr until c++14 :(
32
constexpr
size_t
cmax(
size_t
A,
size_t
B) {
33
return
A>B ? A : B;
34
}
35
#endif
36
37
}
// namespace detail
38
51
class
epicsShareClass
AnyScalar
{
52
public
:
53
struct
bad_cast :
public
std::exception
{
54
#if __cplusplus>=201103L
55
bad_cast()
noexcept
{}
56
virtual
~bad_cast()
noexcept
{}
57
virtual
const
char
* what()
const
noexcept
58
#else
59
bad_cast()
throw
() {}
60
virtual
~bad_cast()
throw
() {}
61
virtual
const
char
* what()
const
throw
()
62
#endif
63
{
return
"bad_cast() type mis-match"
; }
64
};
65
66
private
:
67
ScalarType
_stype;
68
69
// always reserve enough storage for std::string or double (assumed worst case)
70
#if __cplusplus>=201103L
71
72
struct
wrap_t {
73
typename
std::aligned_storage
<detail::cmax(
sizeof
(
std::string
),
sizeof
(
double
)),
74
detail::cmax(
alignof
(
std::string
),
alignof
(
double
))
75
>
::type
blob[1];
76
} _wrap;
77
#else
78
struct
wrap_t {
79
union
blob_t
{
80
char
data[
sizeof
(
std::string
)];
81
double
align_f;
// assume std::string alignment <= 8
82
} blob[1];
83
} _wrap;
84
#endif
85
86
// assumed largest non-string type
87
typedef
double
_largest_blob;
88
89
template
<
typename
T>
90
inline
T& _as() {
91
return
*
reinterpret_cast<
T*
>
(_wrap.blob);
92
}
93
template
<
typename
T>
94
inline
const
T& _as()
const
{
95
return
*
reinterpret_cast<
const
T*
>
(_wrap.blob);
96
}
97
public
:
100
AnyScalar
() : _stype((
ScalarType
)-1) {}
101
103
template
<
typename
T>
104
explicit
AnyScalar
(T v)
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
}
117
121
AnyScalar
(
ScalarType
type
,
const
void
*buf);
122
123
AnyScalar
(
const
AnyScalar
& o);
124
125
#if __cplusplus>=201103L
126
AnyScalar
(
AnyScalar
&& o)
noexcept
;
127
#endif
128
129
inline
~AnyScalar
() {
clear
();}
130
131
inline
AnyScalar
&
operator=
(
const
AnyScalar
& o) {
132
AnyScalar
(o).swap(*
this
);
133
return
*
this
;
134
}
135
136
template
<
typename
T>
137
inline
AnyScalar&
operator=
(T v) {
138
AnyScalar(v).swap(*
this
);
139
return
*
this
;
140
}
141
142
#if __cplusplus>=201103L
143
inline
AnyScalar&
operator=
(AnyScalar&& o)
noexcept
{
144
clear();
145
swap
(o);
146
return
*
this
;
147
}
148
#endif
149
153
void
clear
();
154
155
void
swap(
AnyScalar
& o);
156
158
inline
ScalarType
type
()
const
{
159
return
_stype;
160
}
161
162
inline
void
* unsafe() {
return
_wrap.blob; }
163
inline
const
void
* unsafe()
const
{
return
_wrap.blob; }
164
165
inline
bool
empty
()
const
{
return
_stype==(ScalarType)-1; }
166
167
#if __cplusplus>=201103L
168
explicit
operator
bool()
const
{
return
!
empty
(); }
169
#else
170
private
:
171
typedef
void (AnyScalar::*bool_type)(AnyScalar&);
172
public
:
173
operator
bool_type()
const
{
return
!
empty
() ? &AnyScalar::swap : 0; }
174
#endif
175
179
const
void
*
bufferUnsafe
()
const
;
180
190
template
<
typename
T>
191
inline
192
// T -> strip_const -> map to storage type -> add reference
193
typename
detail::any_storage_type<typename meta::strip_const<T>::type
>
::type
&
194
ref
() {
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
}
202
211
template
<
typename
T>
212
inline
213
// T -> strip_const -> map to storage type -> add const reference
214
typename
meta::decorate_const<typename detail::any_storage_type<typename meta::strip_const<T>::type
>::type>::type&
215
ref
()
const
{
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
}
223
228
template
<
typename
T>
229
inline
230
T
as
()
const
{
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
}
241
242
private
:
243
friend
epicsShareFunc
std::ostream
& operator<<(
std::ostream
& strm,
const
AnyScalar
& v);
244
};
245
246
epicsShareExtern
247
std::ostream
&
operator<<
(
std::ostream
& strm,
const
AnyScalar& v);
248
249
}}
// namespace epics::pvData
250
251
#endif
// PV_ANYSCALAR_H
exception
map
ostream
type_traits
operator=
constexpr complex< _Tp > & operator=(const _Tp &)
std::ostream
basic_ostream< char > ostream
std::string
basic_string< char > string
swap
void swap(any &__x, any &__y) noexcept
operator<<
basic_ostream< _CharT, _Traits > & operator<<(basic_ostream< _CharT, _Traits > &__os, const basic_string< _CharT, _Traits, _Alloc > &__str)
empty
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
std::aligned_storage
std::exception
epics::pvData::AnyScalar
Definition
anyscalar.h:51
epics::pvData::AnyScalar::type
ScalarType type() const
Type code of contained value. Or (ScalarType)-1 is empty.
Definition
anyscalar.h:158
epics::pvData::AnyScalar::ref
meta::decorate_const< typenamedetail::any_storage_type< typenamemeta::strip_const< T >::type >::type >::type & ref() const
Definition
anyscalar.h:215
epics::pvData::AnyScalar::AnyScalar
AnyScalar()
Definition
anyscalar.h:100
epics::pvData::AnyScalar::AnyScalar
AnyScalar(ScalarType type, const void *buf)
epics::pvData::AnyScalar::clear
void clear()
epics::pvData::AnyScalar::bufferUnsafe
const void * bufferUnsafe() const
epics::pvData::AnyScalar::ref
detail::any_storage_type< typenamemeta::strip_const< T >::type >::type & ref()
Definition
anyscalar.h:194
epics::pvData::AnyScalar::AnyScalar
AnyScalar(T v)
Construct from provided value.
Definition
anyscalar.h:104
epics::pvData::AnyScalar::as
T as() const
Definition
anyscalar.h:230
epics::pvData
pvData
Definition
convert.h:21
epics::pvData::uint32
uint32_t uint32
Definition
pvType.h:99
epics::pvData::int32
int32_t int32
Definition
pvType.h:83
epics::pvData::ScalarType
ScalarType
Definition
pvIntrospect.h:221
epics
epics
Definition
convert.h:21
epics::pvData::AnyScalar::bad_cast
Definition
anyscalar.h:53
epics::pvData::ScalarTypeID
Definition
pvIntrospect.h:1423
epics::pvData::detail::any_storage_type
Definition
anyscalar.h:24
epics::pvData::meta::decorate_const
Definition
templateMeta.h:34
epics::pvData::AnyScalar::wrap_t::blob_t
Definition
anyscalar.h:79
Generated on
for PVData C++ by
1.17.0