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> value_interpreterboost::runtime::value_interpreter51 explicit value_interpreter( Modifiers const& ) {} 52 interpretboost::runtime::value_interpreter53 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> value_interpreterboost::runtime::value_interpreter68 explicit value_interpreter( Modifiers const& ) {} 69 interpretboost::runtime::value_interpreter70 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> value_interpreterboost::runtime::value_interpreter81 explicit value_interpreter( Modifiers const& ) {} 82 interpretboost::runtime::value_interpreter83 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> value_interpreterboost::runtime::value_interpreter94 explicit value_interpreter( Modifiers const& ) {} 95 interpretboost::runtime::value_interpreter96 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( source, s_YES ) || 111 case_ins_eq( source, s_Y ) || 112 case_ins_eq( source, s_one ) || 113 case_ins_eq( source, s_TRUE ) ) 114 return true; 115 116 if( case_ins_eq( source, s_NO ) || 117 case_ins_eq( source, s_N ) || 118 case_ins_eq( source, s_zero ) || 119 case_ins_eq( source, 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> value_interpreterboost::runtime::value_interpreter131 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 interpretboost::runtime::value_interpreter144 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> argument_factory(Modifiers const & m)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 produce_argument(cstring source,cstring param_name,arguments_store & store) const182 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 produce_default(cstring param_name,arguments_store & store) const187 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> argument_factory(Modifiers const & m)206 explicit argument_factory( Modifiers const& m ) 207 : m_interpreter( m ) 208 { 209 } 210 produce_argument(cstring source,cstring param_name,arguments_store & store) const211 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( 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 } produce_default(cstring param_name,arguments_store & store) const226 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