-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathgenerictagfield.h
304 lines (261 loc) · 8.16 KB
/
generictagfield.h
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
#ifndef TAG_PARSER_TAGFIELD_H
#define TAG_PARSER_TAGFIELD_H
#include "./tagvalue.h"
namespace TagParser {
template <class implementationType> class TagField;
/*!
* \class TagParser::TagFieldTraits
* \brief Defines traits for the specified \a ImplementationType.
*
* A template specialization for each TagField subclass must be provided.
*/
template <typename ImplementationType> class TagFieldTraits {};
/*!
* \brief The TagField class is used by FieldMapBasedTag to store the fields.
*
* A TagField consists of an identifier and a value. An additional type info
* might be assigned as well. The usage of the type info depends on the
* particular tag implementation.
*
* \tparam ImplementationType Specifies the type of the actual implementation.
* \remarks This template class is intended to be subclassed using
* with the "Curiously recurring template pattern".
*/
template <class ImplementationType> class TAG_PARSER_EXPORT TagField {
friend class TagFieldTraits<ImplementationType>;
public:
using IdentifierType = typename TagFieldTraits<ImplementationType>::IdentifierType;
using TypeInfoType = typename TagFieldTraits<ImplementationType>::TypeInfoType;
TagField();
TagField(const IdentifierType &id, const TagValue &value);
~TagField();
IdentifierType &id();
const IdentifierType &id() const;
std::string idToString() const;
void setId(const IdentifierType &id);
void clearId();
TagValue &value();
const TagValue &value() const;
void setValue(const TagValue &value);
void clearValue();
const TypeInfoType &typeInfo() const;
void setTypeInfo(const TypeInfoType &typeInfo);
void removeTypeInfo();
bool isTypeInfoAssigned() const;
bool isDefault() const;
void setDefault(bool isDefault);
void clear();
bool isAdditionalTypeInfoUsed() const;
const std::vector<ImplementationType> &nestedFields() const;
std::vector<ImplementationType> &nestedFields();
bool supportsNestedFields() const;
protected:
void internallyClearValue();
void internallyClearFurtherData();
private:
IdentifierType m_id;
TagValue m_value;
TypeInfoType m_typeInfo;
bool m_typeInfoAssigned;
bool m_default;
std::vector<ImplementationType> m_nestedFields;
};
/*!
* \brief Constructs an empty TagField.
*/
template <class ImplementationType>
TagField<ImplementationType>::TagField()
: m_id(IdentifierType())
, m_value(TagValue())
, m_typeInfo(TypeInfoType())
, m_typeInfoAssigned(false)
, m_default(false)
{
}
/*!
* \brief Constructs a new TagField with the specified \a id and \a value.
*/
template <class ImplementationType>
TagField<ImplementationType>::TagField(const IdentifierType &id, const TagValue &value)
: m_id(id)
, m_value(value)
, m_typeInfo(TypeInfoType())
, m_typeInfoAssigned(false)
, m_default(false)
{
}
/*!
* \brief Destroys the TagField.
*/
template <class ImplementationType> TagField<ImplementationType>::~TagField()
{
}
/*!
* \brief Returns the id of the current TagField.
*/
template <class ImplementationType> inline typename TagField<ImplementationType>::IdentifierType &TagField<ImplementationType>::id()
{
return m_id;
}
/*!
* \brief Returns the id of the current TagField.
*/
template <class ImplementationType> inline const typename TagField<ImplementationType>::IdentifierType &TagField<ImplementationType>::id() const
{
return m_id;
}
/*!
* \brief Returns the id of the current TagField as string.
*/
template <class ImplementationType> inline std::string TagField<ImplementationType>::idToString() const
{
return ImplementationType::fieldIdToString(m_id);
}
/*!
* \brief Sets the id of the current Tag Field.
*/
template <class ImplementationType> inline void TagField<ImplementationType>::setId(const IdentifierType &id)
{
m_id = id;
}
/*!
* \brief Clears the id of the current TagField.
*/
template <class ImplementationType> inline void TagField<ImplementationType>::clearId()
{
m_id = IdentifierType();
}
/*!
* \brief Returns the value of the current TagField.
*/
template <class ImplementationType> inline TagValue &TagField<ImplementationType>::value()
{
return m_value;
}
/*!
* \brief Returns the value of the current TagField.
*/
template <class ImplementationType> inline const TagValue &TagField<ImplementationType>::value() const
{
return m_value;
}
/*!
* \brief Sets the value of the current TagField.
*/
template <class ImplementationType> inline void TagField<ImplementationType>::setValue(const TagValue &value)
{
m_value = value;
}
/*!
* \brief Clears the value of the current TagField.
*/
template <class ImplementationType> inline void TagField<ImplementationType>::clearValue()
{
static_cast<ImplementationType *>(this)->internallyClearValue();
}
/*!
* \brief Returns the type info of the current TagField.
*/
template <class ImplementationType> inline const typename TagField<ImplementationType>::TypeInfoType &TagField<ImplementationType>::typeInfo() const
{
return m_typeInfo;
}
/*!
* \brief Sets the type info of the current TagField.
*/
template <class ImplementationType> inline void TagField<ImplementationType>::setTypeInfo(const TypeInfoType &typeInfo)
{
m_typeInfo = typeInfo;
m_typeInfoAssigned = true;
}
/*!
* \brief Removes the type info from the current TagField.
*/
template <class ImplementationType> inline void TagField<ImplementationType>::removeTypeInfo()
{
m_typeInfo = TypeInfoType();
m_typeInfoAssigned = false;
}
/*!
* \brief Returns an indication whether a type info is assigned.
*/
template <class ImplementationType> inline bool TagField<ImplementationType>::isTypeInfoAssigned() const
{
return m_typeInfoAssigned;
}
/*!
* \brief Returns an indication whether the field is labeled as default.
*/
template <class ImplementationType> inline bool TagField<ImplementationType>::isDefault() const
{
return m_default;
}
/*!
* \brief Sets whether the field is labeled as default.
*/
template <class ImplementationType> inline void TagField<ImplementationType>::setDefault(bool isDefault)
{
m_default = isDefault;
}
/*!
* \brief Clears id, value, type info, sets default flag to false and resets further implementation specific values.
*/
template <class ImplementationType> void TagField<ImplementationType>::clear()
{
clearId();
clearValue();
static_cast<ImplementationType *>(this)->internallyClearFurtherData();
m_typeInfo = TypeInfoType();
m_typeInfoAssigned = false;
m_default = true;
}
/*!
* \brief Returns an indication whether the additional type info is used.
*
* The default implementation always returns false. The method might be reimplemented
* when subclassing.
*/
template <class ImplementationType> inline bool TagField<ImplementationType>::isAdditionalTypeInfoUsed() const
{
return static_cast<ImplementationType *>(this)->isAdditionalTypeInfoUsed();
}
/*!
* \brief Returns the nested fields.
*/
template <class ImplementationType> const std::vector<ImplementationType> &TagField<ImplementationType>::nestedFields() const
{
return m_nestedFields;
}
/*!
* \brief Returns the nested fields.
* \remarks Might be modified. Not all implementations support nested fields.
* \sa supportsNestedFields()
*/
template <class ImplementationType> inline std::vector<ImplementationType> &TagField<ImplementationType>::nestedFields()
{
return m_nestedFields;
}
/*!
* \brief Returns whether nested fields are supported by the implementation.
*/
template <class ImplementationType> inline bool TagField<ImplementationType>::supportsNestedFields() const
{
return static_cast<ImplementationType *>(this)->supportsNestedFields();
}
/*!
* \brief Clears the assigned value; called via clearValue() and clear().
* \remarks Shadow when subclassing to customize clearning a value.
*/
template <class ImplementationType> void TagField<ImplementationType>::internallyClearValue()
{
m_value.clearDataAndMetadata();
}
/*!
* \brief Clears further data; called via clear().
* \remarks Shadow when subclassing to clear further data the subclass has.
*/
template <class ImplementationType> void TagField<ImplementationType>::internallyClearFurtherData()
{
}
} // namespace TagParser
#endif // TAG_PARSER_TAGFIELD_H