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