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
36namespace boost {
37namespace runtime {
38
39// ************************************************************************** //
40// ************** runtime::value_interpreter ************** //
41// ************************************************************************** //
42
43template<typename ValueType, bool is_enum>
44struct value_interpreter;
45
46//____________________________________________________________________________//
47
48template<typename ValueType>
49struct 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
65template<>
66struct 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
78template<>
79struct 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
91template<>
92struct 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
128template<typename EnumType>
129struct 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
155private:
156 // Data members
157 std::map<cstring,EnumType> m_name_to_value;
158};
159
160//____________________________________________________________________________//
161
162// ************************************************************************** //
163// ************** runtime::argument_factory ************** //
164// ************************************************************************** //
165
166template<typename ValueType, bool is_enum, bool repeatable>
167class argument_factory;
168
169//____________________________________________________________________________//
170
171template<typename ValueType, bool is_enum>
172class argument_factory<ValueType, is_enum, false> {
173public:
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
192private:
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
202template<typename ValueType, bool is_enum>
203class argument_factory<ValueType, is_enum, true> {
204public:
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
231private:
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

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