-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathValue.hpp
153 lines (139 loc) · 3.35 KB
/
Value.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#ifndef VALUE_HPP_INCLUDE_GUARD_5790364856093
#define VALUE_HPP_INCLUDE_GUARD_5790364856093
#include "VR.hpp"
#include "boost/any.hpp"
#include "boost/shared_ptr.hpp"
namespace dicom
{
//!Represents the Value of an attribute in a data set.
/*!
See 3.5, section 7.1.
dicom::Value represents a DataElement, excluding the Tag.
Data is internally managed using a boost::shared_ptr. This means
that copying Value objects is not expensive. Access to the underlying
data is only permitted via the const Get function, and you cannot modify
a Value object once it has been constructed, i.e. it's immutable. This way
it's safe to share references to the same underlying data.
*/
struct Value
{
private:
//!Value Representation, see Part 5 section 6.2
VR vr_;
public:
const VR vr()const
{
return vr_;
}
/*
Unfortunately we cant do
template<typename T,VR vr>
Value(T& data){...}
because the language provides no way of implicitly CALLING such a constructor!!
*/
//!Constructor
/*!
\param vr The value representation of this Value.
\param data This must be of the type specified by VR, else an exception will be thrown.
*/
template<typename T>
Value(VR vr,const T& data)
:vr_(vr)
{
DynamicVRCheck<T>(vr);
data_=boost::shared_ptr<boost::any>(new boost::any(data));
}
//!Constructor
/*! This constructor allows a empty data_ object
*/
Value(VR vr)
:vr_(vr)
{
data_=boost::shared_ptr<boost::any>(new boost::any());
}
//!Query
/*! empty() query if data_ is NULL.
*/
bool empty()const
{
bool is_empty = false;
std::string s;
UID uid;
switch(vr_)
{
case VR_CS:
case VR_AE:
case VR_AS:
case VR_DA:
case VR_DS:
case VR_DT:
case VR_IS:
case VR_LO:
case VR_LT:
case VR_PN:
case VR_SH:
case VR_ST:
case VR_TM:
case VR_UT:
Get(s);
is_empty=(s.length()==0);
break;
case VR_UI:
Get(uid);
s=uid.str();
is_empty=(s.length()==0);
break;
default:
is_empty=data_->empty();
}
return is_empty;
}
//could also have a Get() parametrized on VR:
//template<VR vr>
//void Get()
//!Accesor function
/*!
\param t This will receive a copy of the underlying data. It
must be of the correct type, else a BadVR exception will be thrown
*/
template<typename T>
void Get(T& t) const
{
DynamicVRCheck<T>(vr_); //check we have the right value representation.
t=boost::any_cast<T>(*(data_));
}
//!Another Get function
/*!
This form accesses the underlying data as a const reference.
It will be faster than the first form, as no copying is involved, but
you need to explicitly state the item type within the template
parameter
*/
template<typename T>
const T& Get() const
{
DynamicVRCheck<T>(vr_);
const boost::any& a = *data_;
const T* pT=boost::any_cast<T>(&a);//this form returns a pointer, see 'any' documentation.
return *pT;
}
//!right shift operator provided for convenience
/*!
using this one can write:
\code
Value v=(something);
int i;
v >> i;
\endcode
*/
template<typename T>
void operator >> (T& t) const
{
Get(t);
}
private:
//!The data itself, implemented using BOOST utilities.
boost::shared_ptr<boost::any> data_;
};
}
#endif //VALUE_HPP_INCLUDE_GUARD_5790364856093