1 //! \file
2 //! \brief ������ ����, ��������������� ��������� ��������� ��������.
3
4 #if !defined( CLS_3_SCALAR_TAG_SCALAR_HPP )
5 #define CLS_3_SCALAR_TAG_SCALAR_HPP
6
7 #include <string>
8
9 #include <cls_3/tags/h/tag.hpp>
10 #include <cls_3/tags/scalar/constraints/h/constraint.hpp>
11 #include <cls_3/tags/scalar/format/h/format.hpp>
12
13 namespace cls_3
14 {
15
16 namespace tags
17 {
18
19 ///
20 /// tag_scalar_t
21 ///
22
23 //! \brief ������ ���� ��������������� ��������� ��������� ��������.
24 template< class T, class Format = scalar_format_t< T > >
25 class tag_scalar_t : public tag_t
26 {
27 public :
28 typedef T value_type_t;
29 typedef Format format_type_t;
30 typedef scalar_constraints::scalar_constraint_t< T > constraint_type_t;
31
32 public :
33 //! ����������� �����������.
34 tag_scalar_t(
35 const std::string &name,
36 bool is_mandatory
37 );
38
39 //! ����������� ��� ������, ����� ��� ��������
40 //! ����������� �����.
41 /*! \since v.2.6.2 */
42 tag_scalar_t(
43 //! ��������, � �������� �� ����� ������������� ���������.
44 tag_t & owner,
45 const std::string &name,
46 bool is_mandatory
47 );
48
49 virtual ~tag_scalar_t();
50
51 //! �������� �������� �������������� ����.
52 virtual void
53 on_start( const parser_context_info_t &parser_context_info );
54
55 //! \throws scalar_value_missed_ex_t ���� ��� �� ��� ���������.
56 virtual void
57 on_finish( const parser_context_info_t &parser_context_info );
58
59 virtual void
60 on_tok_nonspace(
61 const parser_context_info_t &parser_context_info,
62 const std::string &tok_value
63 );
64
65 virtual void
66 on_tok_string(
67 const parser_context_info_t &parser_context_info,
68 const std::string &tok_value
69 );
70
71 virtual void
72 on_tok_verbatim_string(
73 const parser_context_info_t &parser_context_info,
74 const std::string &start_marker,
75 const std::string &tok_contents,
76 const std::string &end_marker
77 );
78
79 virtual bool
80 is_mandatory() const;
81
82 virtual bool
83 is_defined() const;
84
85 virtual void
86 reset();
87
88 //! ������� ������������ �������� ����.
89 /*!
90 ������������ ������������ ��� ��������� ������� NONSPACE ��� STRING,
91 � ������ �������������� �������� ����������� �������������
92 ��������������� ����������.
93 */
94 constraint_type_t *
95 set_constraint(
96 // May be null
97 constraint_type_t * constraint
98 );
99
100 //! �������� ������������ ����� ������������.
101 constraint_type_t *
102 query_constraint() const;
103
104 const T &
105 query_value() const;
106
107 //! ����������� ���� ��������� ���������.
108 void
109 make_defined( const T & v );
110
111 //! �������� �������� ��������������� ���������.
112 /*!
113 �������� ��������� �������� �������������� ���������.
114 ������� ���������, ��������� �� ���, � ���� ���������,
115 ��������� ��� �������� � ��������� ����������.
116 �.�. �������� ���������� � receiver ������ ����
117 is_defined() ���������� true.
118 */
119 void
120 query_opt_value( T &receiver ) const;
121
122 protected :
123 T m_value;
124
125 constraint_type_t *m_constraint;
126
127 bool m_is_mandatory;
128 bool m_is_defined;
129
130 //! �������� �������������� ����.
131 //! \throws tag_already_defined_ex_t ���� ��� ��� ���������.
132 void
133 check_definition( const parser_context_info_t &parser_context_info );
134
135 //! ������������ ������� format() ��� ������ �������� ����.
136 virtual void
137 on_format( tag_formatter_t &fmt );
138 };
139
140 ///
141 /// tag_scalar_t implementation
142 ///
143
144 template< class T, class Format >
tag_scalar_t(const std::string & name,bool mandatory)145 tag_scalar_t< T, Format >::tag_scalar_t(
146 const std::string &name,
147 bool mandatory
148 )
149 : tag_t( name ),
150 m_constraint( 0 ),
151 m_is_mandatory( mandatory ),
152 m_is_defined( false )
153 {
154 }
155
156 template< class T, class Format >
tag_scalar_t(tag_t & owner,const std::string & name,bool mandatory)157 tag_scalar_t< T, Format >::tag_scalar_t(
158 tag_t &owner,
159 const std::string &name,
160 bool mandatory
161 )
162 : tag_t( owner, name ),
163 m_constraint( 0 ),
164 m_is_mandatory( mandatory ),
165 m_is_defined( false )
166 {
167 }
168
169 template< class T, class Format >
~tag_scalar_t()170 tag_scalar_t< T, Format >::~tag_scalar_t()
171 {
172 }
173
174 template< class T, class Format >
175 void
on_start(const parser_context_info_t & parser_context_info)176 tag_scalar_t< T, Format >::on_start(
177 const parser_context_info_t &parser_context_info
178 )
179 {
180 tag_t::on_start( parser_context_info );
181 check_definition( parser_context_info );
182 }
183
184 template< class T, class Format >
185 void
on_finish(const parser_context_info_t & parser_context_info)186 tag_scalar_t< T, Format >::on_finish(
187 const parser_context_info_t &parser_context_info
188 )
189 {
190 tag_t::on_finish( parser_context_info );
191
192 if( !m_is_defined )
193 {
194 throw scalar_value_missed_ex_t( query_name() );
195 }
196 }
197
198 template< class T, class Format >
199 void
on_tok_nonspace(const parser_context_info_t & parser_context_info,const std::string & tok_value)200 tag_scalar_t< T, Format >::on_tok_nonspace(
201 const parser_context_info_t &parser_context_info,
202 const std::string &tok_value
203 )
204 {
205 check_definition( parser_context_info );
206
207 T tmp;
208
209 // �������� ���������� invalid_value_ex_t, unexpected_nonspace_token_ex_t
210 Format::on_tok_nonspace( parser_context_info, tok_value, tmp );
211
212 if( m_constraint )
213 {
214 // �������� ���������� value_out_of_range_ex_t
215 m_constraint->check( parser_context_info, tmp );
216 }
217
218 m_value = tmp;
219 m_is_defined = true;
220 }
221
222 template< class T, class Format >
223 void
on_tok_string(const parser_context_info_t & parser_context_info,const std::string & tok_value)224 tag_scalar_t< T, Format >::on_tok_string(
225 const parser_context_info_t &parser_context_info,
226 const std::string &tok_value
227 )
228 {
229 check_definition( parser_context_info );
230
231 T tmp;
232
233 // �������� ���������� unexpected_string_token_ex_t
234 Format::on_tok_string( parser_context_info, tok_value, tmp );
235
236 if( m_constraint )
237 {
238 // �������� ���������� value_out_of_range_ex_t
239 m_constraint->check( parser_context_info, tmp );
240 }
241
242 m_value = tmp;
243 m_is_defined = true;
244
245 }
246
247 template< class T, class Format >
248 void
on_tok_verbatim_string(const parser_context_info_t & parser_context_info,const std::string &,const std::string & tok_contents,const std::string &)249 tag_scalar_t< T, Format >::on_tok_verbatim_string(
250 const parser_context_info_t & parser_context_info,
251 const std::string & /*start_marker*/,
252 const std::string & tok_contents,
253 const std::string & /*end_marker*/ )
254 {
255 check_definition( parser_context_info );
256
257 T tmp;
258
259 // �������� ���������� unexpected_string_token_ex_t
260 Format::on_tok_string( parser_context_info, tok_contents, tmp );
261
262 if( m_constraint )
263 {
264 // �������� ���������� value_out_of_range_ex_t
265 m_constraint->check( parser_context_info, tmp );
266 }
267
268 m_value = tmp;
269 m_is_defined = true;
270 }
271
272 template< class T, class Format >
273 bool
is_mandatory() const274 tag_scalar_t< T, Format >::is_mandatory() const
275 {
276 return m_is_mandatory;
277 }
278
279 template< class T, class Format >
280 bool
is_defined() const281 tag_scalar_t< T, Format >::is_defined() const
282 {
283 return m_is_defined;
284 }
285
286 template< class T, class Format >
287 void
reset()288 tag_scalar_t< T, Format >::reset()
289 {
290 tag_t::reset();
291
292 m_is_defined = false;
293 m_value = T();
294 }
295
296 template< class T, class Format >
297 scalar_constraints::scalar_constraint_t< T > *
set_constraint(constraint_type_t * constraint)298 tag_scalar_t< T, Format >::set_constraint( constraint_type_t * constraint )
299 {
300 constraint_type_t * old = m_constraint;
301 m_constraint = constraint;
302
303 return old;
304 }
305
306 template< class T, class Format >
307 scalar_constraints::scalar_constraint_t< T > *
query_constraint() const308 tag_scalar_t< T, Format >::query_constraint() const
309 {
310 return m_constraint;
311 }
312
313 template< class T, class Format >
314 const T &
query_value() const315 tag_scalar_t< T, Format >::query_value() const
316 {
317 return m_value;
318 }
319
320 template< class T, class Format >
321 void
make_defined(const T & v)322 tag_scalar_t< T, Format >::make_defined( const T & v )
323 {
324 m_value = v;
325 m_is_defined = true;
326 }
327
328 template< class T, class Format >
329 void
query_opt_value(T & receiver) const330 tag_scalar_t< T, Format >::query_opt_value( T & receiver ) const
331 {
332 if( is_defined() )
333 receiver = query_value();
334 }
335
336 template< class T, class Format >
337 void
check_definition(const parser_context_info_t &)338 tag_scalar_t< T, Format >::check_definition(
339 const parser_context_info_t & /*parser_context_info*/ )
340 {
341 if( m_is_defined )
342 {
343 throw tag_already_defined_ex_t( query_name() );
344 }
345 }
346
347 template< class T, class Format >
348 void
on_format(tag_formatter_t & fmt)349 tag_scalar_t< T, Format >::on_format( tag_formatter_t & fmt )
350 {
351 fmt.out_value( Format::format( query_value() ) );
352 }
353
354 } // namespace tags
355
356 } /* namespace cls_3 */
357
358 #endif
359