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

source code of boost/boost/test/utils/runtime/argument_factory.hpp