File indexing completed on 2025-01-18 09:52:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP
0016 #define BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP
0017
0018
0019 #include <boost/test/utils/runtime/errors.hpp>
0020 #include <boost/test/utils/runtime/argument.hpp>
0021 #include <boost/test/utils/runtime/modifier.hpp>
0022
0023
0024 #include <boost/test/utils/basic_cstring/io.hpp>
0025 #include <boost/test/utils/basic_cstring/compare.hpp>
0026 #include <boost/test/utils/string_cast.hpp>
0027
0028
0029 #include <boost/function/function2.hpp>
0030
0031
0032 #include <vector>
0033
0034 #include <boost/test/detail/suppress_warnings.hpp>
0035
0036 namespace boost {
0037 namespace runtime {
0038
0039
0040
0041
0042
0043 template<typename ValueType, bool is_enum>
0044 struct value_interpreter;
0045
0046
0047
0048 template<typename ValueType>
0049 struct value_interpreter<ValueType, false> {
0050 template<typename Modifiers>
0051 explicit value_interpreter( Modifiers const& ) {}
0052
0053 ValueType interpret( cstring param_name, cstring source ) const
0054 {
0055 ValueType res;
0056 if( !unit_test::utils::string_as<ValueType>( source, res ) )
0057 BOOST_TEST_I_THROW( format_error( param_name ) << source <<
0058 " can't be interpreted as value of parameter " << param_name << "." );
0059 return res;
0060 }
0061 };
0062
0063
0064
0065 template<>
0066 struct value_interpreter<std::string, false> {
0067 template<typename Modifiers>
0068 explicit value_interpreter( Modifiers const& ) {}
0069
0070 std::string interpret( cstring, cstring source ) const
0071 {
0072 return std::string( source.begin(), source.size() );
0073 }
0074 };
0075
0076
0077
0078 template<>
0079 struct value_interpreter<cstring, false> {
0080 template<typename Modifiers>
0081 explicit value_interpreter( Modifiers const& ) {}
0082
0083 cstring interpret( cstring, cstring source ) const
0084 {
0085 return source;
0086 }
0087 };
0088
0089
0090
0091 template<>
0092 struct value_interpreter<bool, false> {
0093 template<typename Modifiers>
0094 explicit value_interpreter( Modifiers const& ) {}
0095
0096 bool interpret( cstring param_name, cstring source ) const
0097 {
0098 static cstring const s_YES( "YES" );
0099 static cstring const s_Y( "Y" );
0100 static cstring const s_NO( "NO" );
0101 static cstring const s_N( "N" );
0102 static cstring const s_TRUE( "TRUE" );
0103 static cstring const s_FALSE( "FALSE" );
0104 static cstring const s_one( "1" );
0105 static cstring const s_zero( "0" );
0106
0107 source.trim();
0108
0109 if( source.is_empty() ||
0110 case_ins_eq( source, s_YES ) ||
0111 case_ins_eq( source, s_Y ) ||
0112 case_ins_eq( source, s_one ) ||
0113 case_ins_eq( source, s_TRUE ) )
0114 return true;
0115
0116 if( case_ins_eq( source, s_NO ) ||
0117 case_ins_eq( source, s_N ) ||
0118 case_ins_eq( source, s_zero ) ||
0119 case_ins_eq( source, s_FALSE ) )
0120 return false;
0121
0122 BOOST_TEST_I_THROW( format_error( param_name ) << source << " can't be interpreted as bool value." );
0123 }
0124 };
0125
0126
0127
0128 template<typename EnumType>
0129 struct value_interpreter<EnumType, true> {
0130 template<typename Modifiers>
0131 explicit value_interpreter( Modifiers const& m )
0132 #if defined(BOOST_TEST_CLA_NEW_API)
0133 : m_name_to_value( m[enum_values<EnumType>::value] )
0134 {
0135 }
0136 #else
0137 {
0138 std::vector<std::pair<cstring,EnumType> > const& values = m[enum_values<EnumType>::value];
0139
0140 m_name_to_value.insert( values.begin(), values.end() );
0141 }
0142 #endif
0143
0144 EnumType interpret( cstring param_name, cstring source ) const
0145 {
0146 typename std::map<cstring,EnumType>::const_iterator found = m_name_to_value.find( source );
0147
0148 BOOST_TEST_I_ASSRT( found != m_name_to_value.end(),
0149 format_error( param_name ) << source <<
0150 " is not a valid enumeration value name for parameter " << param_name << "." );
0151
0152 return found->second;
0153 }
0154
0155 private:
0156
0157 std::map<cstring,EnumType> m_name_to_value;
0158 };
0159
0160
0161
0162
0163
0164
0165
0166 template<typename ValueType, bool is_enum, bool repeatable>
0167 class argument_factory;
0168
0169
0170
0171 template<typename ValueType, bool is_enum>
0172 class argument_factory<ValueType, is_enum, false> {
0173 public:
0174 template<typename Modifiers>
0175 explicit argument_factory( Modifiers const& m )
0176 : m_interpreter( m )
0177 , m_optional_value( nfp::opt_get( m, optional_value, ValueType() ) )
0178 , m_default_value( nfp::opt_get( m, default_value, ValueType() ) )
0179 {
0180 }
0181
0182 void produce_argument( cstring source, cstring param_name, arguments_store& store ) const
0183 {
0184 store.set( param_name, source.empty() ? m_optional_value : m_interpreter.interpret( param_name, source ) );
0185 }
0186
0187 void produce_default( cstring param_name, arguments_store& store ) const
0188 {
0189 store.set( param_name, m_default_value );
0190 }
0191
0192 private:
0193
0194 typedef value_interpreter<ValueType, is_enum> interp_t;
0195 interp_t m_interpreter;
0196 ValueType m_optional_value;
0197 ValueType m_default_value;
0198 };
0199
0200
0201
0202 template<typename ValueType, bool is_enum>
0203 class argument_factory<ValueType, is_enum, true> {
0204 public:
0205 template<typename Modifiers>
0206 explicit argument_factory( Modifiers const& m )
0207 : m_interpreter( m )
0208 {
0209 }
0210
0211 void produce_argument( cstring source, cstring param_name, arguments_store& store ) const
0212 {
0213 ValueType value = m_interpreter.interpret( param_name, source );
0214
0215 if( store.has( param_name ) ) {
0216 std::vector<ValueType>& values = store.get<std::vector<ValueType> >( param_name );
0217 values.push_back( value );
0218 }
0219 else {
0220 std::vector<ValueType> values( 1, value );
0221
0222 store.set( param_name, values );
0223 }
0224
0225 }
0226 void produce_default( cstring param_name, arguments_store& store ) const
0227 {
0228 store.set( param_name, std::vector<ValueType>() );
0229 }
0230
0231 private:
0232
0233 value_interpreter<ValueType, is_enum> m_interpreter;
0234 };
0235
0236
0237
0238 }
0239 }
0240
0241 #include <boost/test/detail/enable_warnings.hpp>
0242
0243 #endif