1 | // (C) Copyright Gennadiy Rozental 2001. |
2 | // Distributed under the Boost Software License, Version 1.0. |
3 | // (See accompanying file LICENSE_1_0.txt or copy at |
4 | // http://www.boost.org/LICENSE_1_0.txt) |
5 | |
6 | // See http://www.boost.org/libs/test for the library home page. |
7 | // |
8 | // File : $RCSfile$ |
9 | // |
10 | // Version : $Revision$ |
11 | // |
12 | // Description : argument factories for different kinds of parameters |
13 | // *************************************************************************** |
14 | |
15 | #ifndef BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP |
16 | #define BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP |
17 | |
18 | // Boost.Test Runtime parameters |
19 | #include <boost/test/utils/runtime/errors.hpp> |
20 | #include <boost/test/utils/runtime/argument.hpp> |
21 | #include <boost/test/utils/runtime/modifier.hpp> |
22 | |
23 | // Boost.Test |
24 | #include <boost/test/utils/basic_cstring/io.hpp> |
25 | #include <boost/test/utils/basic_cstring/compare.hpp> |
26 | #include <boost/test/utils/string_cast.hpp> |
27 | |
28 | // Boost |
29 | #include <boost/function/function2.hpp> |
30 | |
31 | // STL |
32 | #include <vector> |
33 | |
34 | #include <boost/test/detail/suppress_warnings.hpp> |
35 | |
36 | namespace boost { |
37 | namespace runtime { |
38 | |
39 | // ************************************************************************** // |
40 | // ************** runtime::value_interpreter ************** // |
41 | // ************************************************************************** // |
42 | |
43 | template<typename ValueType, bool is_enum> |
44 | struct value_interpreter; |
45 | |
46 | //____________________________________________________________________________// |
47 | |
48 | template<typename ValueType> |
49 | struct value_interpreter<ValueType, false> { |
50 | template<typename Modifiers> |
51 | explicit value_interpreter( Modifiers const& ) {} |
52 | |
53 | ValueType interpret( cstring param_name, cstring source ) const |
54 | { |
55 | ValueType res; |
56 | if( !unit_test::utils::string_as<ValueType>( source, res ) ) |
57 | BOOST_TEST_I_THROW( format_error( param_name ) << source << |
58 | " can't be interpreted as value of parameter " << param_name << "." ); |
59 | return res; |
60 | } |
61 | }; |
62 | |
63 | //____________________________________________________________________________// |
64 | |
65 | template<> |
66 | struct value_interpreter<std::string, false> { |
67 | template<typename Modifiers> |
68 | explicit value_interpreter( Modifiers const& ) {} |
69 | |
70 | std::string interpret( cstring, cstring source ) const |
71 | { |
72 | return std::string( source.begin(), source.size() ); |
73 | } |
74 | }; |
75 | |
76 | //____________________________________________________________________________// |
77 | |
78 | template<> |
79 | struct value_interpreter<cstring, false> { |
80 | template<typename Modifiers> |
81 | explicit value_interpreter( Modifiers const& ) {} |
82 | |
83 | cstring interpret( cstring, cstring source ) const |
84 | { |
85 | return source; |
86 | } |
87 | }; |
88 | |
89 | //____________________________________________________________________________// |
90 | |
91 | template<> |
92 | struct value_interpreter<bool, false> { |
93 | template<typename Modifiers> |
94 | explicit value_interpreter( Modifiers const& ) {} |
95 | |
96 | bool interpret( cstring param_name, cstring source ) const |
97 | { |
98 | static cstring const s_YES( "YES" ); |
99 | static cstring const s_Y( "Y" ); |
100 | static cstring const s_NO( "NO" ); |
101 | static cstring const s_N( "N" ); |
102 | static cstring const s_TRUE( "TRUE" ); |
103 | static cstring const s_FALSE( "FALSE" ); |
104 | static cstring const s_one( "1" ); |
105 | static cstring const s_zero( "0" ); |
106 | |
107 | source.trim(); |
108 | |
109 | if( source.is_empty() || |
110 | case_ins_eq( x: source, y: s_YES ) || |
111 | case_ins_eq( x: source, y: s_Y ) || |
112 | case_ins_eq( x: source, y: s_one ) || |
113 | case_ins_eq( x: source, y: s_TRUE ) ) |
114 | return true; |
115 | |
116 | if( case_ins_eq( x: source, y: s_NO ) || |
117 | case_ins_eq( x: source, y: s_N ) || |
118 | case_ins_eq( x: source, y: s_zero ) || |
119 | case_ins_eq( x: source, y: s_FALSE ) ) |
120 | return false; |
121 | |
122 | BOOST_TEST_I_THROW( format_error( param_name ) << source << " can't be interpreted as bool value." ); |
123 | } |
124 | }; |
125 | |
126 | //____________________________________________________________________________// |
127 | |
128 | template<typename EnumType> |
129 | struct value_interpreter<EnumType, true> { |
130 | template<typename Modifiers> |
131 | explicit value_interpreter( Modifiers const& m ) |
132 | #if defined(BOOST_TEST_CLA_NEW_API) |
133 | : m_name_to_value( m[enum_values<EnumType>::value] ) |
134 | { |
135 | } |
136 | #else |
137 | { |
138 | std::vector<std::pair<cstring,EnumType> > const& values = m[enum_values<EnumType>::value]; |
139 | |
140 | m_name_to_value.insert( values.begin(), values.end() ); |
141 | } |
142 | #endif |
143 | |
144 | EnumType interpret( cstring param_name, cstring source ) const |
145 | { |
146 | typename std::map<cstring,EnumType>::const_iterator found = m_name_to_value.find( source ); |
147 | |
148 | BOOST_TEST_I_ASSRT( found != m_name_to_value.end(), |
149 | format_error( param_name ) << source << |
150 | " is not a valid enumeration value name for parameter " << param_name << "." ); |
151 | |
152 | return found->second; |
153 | } |
154 | |
155 | private: |
156 | // Data members |
157 | std::map<cstring,EnumType> m_name_to_value; |
158 | }; |
159 | |
160 | //____________________________________________________________________________// |
161 | |
162 | // ************************************************************************** // |
163 | // ************** runtime::argument_factory ************** // |
164 | // ************************************************************************** // |
165 | |
166 | template<typename ValueType, bool is_enum, bool repeatable> |
167 | class argument_factory; |
168 | |
169 | //____________________________________________________________________________// |
170 | |
171 | template<typename ValueType, bool is_enum> |
172 | class argument_factory<ValueType, is_enum, false> { |
173 | public: |
174 | template<typename Modifiers> |
175 | explicit argument_factory( Modifiers const& m ) |
176 | : m_interpreter( m ) |
177 | , m_optional_value( nfp::opt_get( m, optional_value, ValueType() ) ) |
178 | , m_default_value( nfp::opt_get( m, default_value, ValueType() ) ) |
179 | { |
180 | } |
181 | |
182 | void produce_argument( cstring source, cstring param_name, arguments_store& store ) const |
183 | { |
184 | store.set( param_name, source.empty() ? m_optional_value : m_interpreter.interpret( param_name, source ) ); |
185 | } |
186 | |
187 | void produce_default( cstring param_name, arguments_store& store ) const |
188 | { |
189 | store.set( param_name, m_default_value ); |
190 | } |
191 | |
192 | private: |
193 | // Data members |
194 | typedef value_interpreter<ValueType, is_enum> interp_t; |
195 | interp_t m_interpreter; |
196 | ValueType m_optional_value; |
197 | ValueType m_default_value; |
198 | }; |
199 | |
200 | //____________________________________________________________________________// |
201 | |
202 | template<typename ValueType, bool is_enum> |
203 | class argument_factory<ValueType, is_enum, true> { |
204 | public: |
205 | template<typename Modifiers> |
206 | explicit argument_factory( Modifiers const& m ) |
207 | : m_interpreter( m ) |
208 | { |
209 | } |
210 | |
211 | void produce_argument( cstring source, cstring param_name, arguments_store& store ) const |
212 | { |
213 | ValueType value = m_interpreter.interpret( param_name, source ); |
214 | |
215 | if( store.has( parameter_name: param_name ) ) { |
216 | std::vector<ValueType>& values = store.get<std::vector<ValueType> >( param_name ); |
217 | values.push_back( value ); |
218 | } |
219 | else { |
220 | std::vector<ValueType> values( 1, value ); |
221 | |
222 | store.set( param_name, values ); |
223 | } |
224 | |
225 | } |
226 | void produce_default( cstring param_name, arguments_store& store ) const |
227 | { |
228 | store.set( param_name, std::vector<ValueType>() ); |
229 | } |
230 | |
231 | private: |
232 | // Data members |
233 | value_interpreter<ValueType, is_enum> m_interpreter; |
234 | }; |
235 | |
236 | //____________________________________________________________________________// |
237 | |
238 | } // namespace runtime |
239 | } // namespace boost |
240 | |
241 | #include <boost/test/detail/enable_warnings.hpp> |
242 | |
243 | #endif // BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP |
244 | |