Line data Source code
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 584 : explicit value_interpreter( Modifiers const& ) {}
52 :
53 0 : ValueType interpret( cstring param_name, cstring source ) const
54 : {
55 : ValueType res;
56 0 : if( !unit_test::utils::string_as<ValueType>( source, res ) )
57 0 : BOOST_TEST_I_THROW( format_error( param_name ) << source <<
58 : " can't be interpreted as value of parameter " << param_name << "." );
59 0 : return res;
60 0 : }
61 : };
62 :
63 : //____________________________________________________________________________//
64 :
65 : template<>
66 : struct value_interpreter<std::string, false> {
67 : template<typename Modifiers>
68 2044 : explicit value_interpreter( Modifiers const& ) {}
69 :
70 146 : std::string interpret( cstring, cstring source ) const
71 : {
72 146 : 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 3796 : explicit value_interpreter( Modifiers const& ) {}
95 :
96 146 : bool interpret( cstring param_name, cstring source ) const
97 : {
98 146 : static cstring const s_YES( "YES" );
99 146 : static cstring const s_Y( "Y" );
100 146 : static cstring const s_NO( "NO" );
101 146 : static cstring const s_N( "N" );
102 146 : static cstring const s_TRUE( "TRUE" );
103 146 : static cstring const s_FALSE( "FALSE" );
104 146 : static cstring const s_one( "1" );
105 146 : static cstring const s_zero( "0" );
106 :
107 146 : source.trim();
108 :
109 292 : if( source.is_empty() ||
110 146 : case_ins_eq( source, s_YES ) ||
111 146 : case_ins_eq( source, s_Y ) ||
112 146 : case_ins_eq( source, s_one ) ||
113 146 : case_ins_eq( source, s_TRUE ) )
114 0 : return true;
115 :
116 146 : if( case_ins_eq( source, s_NO ) ||
117 0 : case_ins_eq( source, s_N ) ||
118 0 : case_ins_eq( source, s_zero ) ||
119 0 : case_ins_eq( source, s_FALSE ) )
120 146 : return false;
121 :
122 0 : BOOST_TEST_I_THROW( format_error( param_name ) << source << " can't be interpreted as bool value." );
123 146 : }
124 : };
125 :
126 : //____________________________________________________________________________//
127 :
128 : template<typename EnumType>
129 : struct value_interpreter<EnumType, true> {
130 : template<typename Modifiers>
131 1752 : explicit value_interpreter( Modifiers const& m )
132 : #if defined(BOOST_TEST_CLA_NEW_API)
133 876 : : m_name_to_value( m[enum_values<EnumType>::value] )
134 876 : {
135 1752 : }
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 146 : EnumType interpret( cstring param_name, cstring source ) const
145 : {
146 146 : typename std::map<cstring,EnumType>::const_iterator found = m_name_to_value.find( source );
147 :
148 146 : 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 146 : return found->second;
153 0 : }
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 730 : 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 7592 : explicit argument_factory( Modifiers const& m )
176 3796 : : m_interpreter( m )
177 3796 : , m_optional_value( nfp::opt_get( m, optional_value, ValueType() ) )
178 3796 : , m_default_value( nfp::opt_get( m, default_value, ValueType() ) )
179 3796 : {
180 7592 : }
181 :
182 292 : void produce_argument( cstring source, cstring param_name, arguments_store& store ) const
183 : {
184 292 : store.set( param_name, source.empty() ? m_optional_value : m_interpreter.interpret( param_name, source ) );
185 292 : }
186 :
187 2774 : void produce_default( cstring param_name, arguments_store& store ) const
188 : {
189 2774 : store.set( param_name, m_default_value );
190 2774 : }
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 584 : explicit argument_factory( Modifiers const& m )
207 292 : : m_interpreter( m )
208 292 : {
209 584 : }
210 :
211 146 : void produce_argument( cstring source, cstring param_name, arguments_store& store ) const
212 : {
213 146 : ValueType value = m_interpreter.interpret( param_name, source );
214 :
215 146 : if( store.has( param_name ) ) {
216 0 : std::vector<ValueType>& values = store.get<std::vector<ValueType> >( param_name );
217 0 : values.push_back( value );
218 0 : }
219 : else {
220 146 : std::vector<ValueType> values( 1, value );
221 :
222 146 : store.set( param_name, values );
223 146 : }
224 :
225 146 : }
226 146 : void produce_default( cstring param_name, arguments_store& store ) const
227 : {
228 146 : store.set( param_name, std::vector<ValueType>() );
229 146 : }
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
|