243 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			243 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | //  (C) Copyright Gennadiy Rozental 2001. | ||
|  | //  Distributed under the Boost Software License, Version 1.0. | ||
|  | //  (See accompanying file LICENSE_1_0.txt or copy at | ||
|  | //  http://www.boost.org/LICENSE_1_0.txt) | ||
|  | 
 | ||
|  | //  See http://www.boost.org/libs/test for the library home page. | ||
|  | // | ||
|  | //  File        : $RCSfile$ | ||
|  | // | ||
|  | //  Version     : $Revision$ | ||
|  | // | ||
|  | //  Description : argument factories for different kinds of parameters | ||
|  | // *************************************************************************** | ||
|  | 
 | ||
|  | #ifndef BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP | ||
|  | #define BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP | ||
|  | 
 | ||
|  | // Boost.Test Runtime parameters | ||
|  | #include <boost/test/utils/runtime/errors.hpp> | ||
|  | #include <boost/test/utils/runtime/argument.hpp> | ||
|  | 
 | ||
|  | // Boost.Test | ||
|  | #include <boost/test/utils/basic_cstring/io.hpp> | ||
|  | #include <boost/test/utils/basic_cstring/compare.hpp> | ||
|  | #include <boost/test/utils/string_cast.hpp> | ||
|  | 
 | ||
|  | // Boost | ||
|  | #include <boost/function/function2.hpp> | ||
|  | 
 | ||
|  | // STL | ||
|  | #include <vector> | ||
|  | 
 | ||
|  | #include <boost/test/detail/suppress_warnings.hpp> | ||
|  | 
 | ||
|  | namespace boost { | ||
|  | namespace runtime { | ||
|  | 
 | ||
|  | // ************************************************************************** // | ||
|  | // **************          runtime::value_interpreter          ************** // | ||
|  | // ************************************************************************** // | ||
|  | 
 | ||
|  | template<typename ValueType, bool is_enum> | ||
|  | struct value_interpreter; | ||
|  | 
 | ||
|  | //____________________________________________________________________________// | ||
|  | 
 | ||
|  | template<typename ValueType> | ||
|  | struct value_interpreter<ValueType, false> { | ||
|  |     template<typename Modifiers> | ||
|  |     explicit    value_interpreter( Modifiers const& ) {} | ||
|  | 
 | ||
|  |     ValueType interpret( cstring param_name, cstring source ) const | ||
|  |     { | ||
|  |         ValueType res; | ||
|  |         if( !unit_test::utils::string_as<ValueType>( source, res ) ) | ||
|  |             BOOST_TEST_I_THROW( format_error( param_name ) << source << | ||
|  |                                 " can't be interpreted as value of parameter " << param_name << "." ); | ||
|  |         return res; | ||
|  |     } | ||
|  | }; | ||
|  | 
 | ||
|  | //____________________________________________________________________________// | ||
|  | 
 | ||
|  | template<> | ||
|  | struct value_interpreter<std::string, false> { | ||
|  |     template<typename Modifiers> | ||
|  |     explicit    value_interpreter( Modifiers const& ) {} | ||
|  | 
 | ||
|  |     std::string interpret( cstring, cstring source ) const | ||
|  |     { | ||
|  |         return std::string( source.begin(), source.size() ); | ||
|  |     } | ||
|  | }; | ||
|  | 
 | ||
|  | //____________________________________________________________________________// | ||
|  | 
 | ||
|  | template<> | ||
|  | struct value_interpreter<cstring, false> { | ||
|  |     template<typename Modifiers> | ||
|  |     explicit    value_interpreter( Modifiers const& ) {} | ||
|  | 
 | ||
|  |     cstring interpret( cstring, cstring source ) const | ||
|  |     { | ||
|  |         return source; | ||
|  |     } | ||
|  | }; | ||
|  | 
 | ||
|  | //____________________________________________________________________________// | ||
|  | 
 | ||
|  | template<> | ||
|  | struct value_interpreter<bool, false> { | ||
|  |     template<typename Modifiers> | ||
|  |     explicit    value_interpreter( Modifiers const& ) {} | ||
|  | 
 | ||
|  |     bool    interpret( cstring param_name, cstring source ) const | ||
|  |     { | ||
|  |         static cstring const s_YES( "YES" ); | ||
|  |         static cstring const s_Y( "Y" ); | ||
|  |         static cstring const s_NO( "NO" ); | ||
|  |         static cstring const s_N( "N" ); | ||
|  |         static cstring const s_TRUE( "TRUE" ); | ||
|  |         static cstring const s_FALSE( "FALSE" ); | ||
|  |         static cstring const s_one( "1" ); | ||
|  |         static cstring const s_zero( "0" ); | ||
|  | 
 | ||
|  |         source.trim(); | ||
|  | 
 | ||
|  |         if( source.is_empty() || | ||
|  |             case_ins_eq( source, s_YES ) || | ||
|  |             case_ins_eq( source, s_Y ) || | ||
|  |             case_ins_eq( source, s_one ) || | ||
|  |             case_ins_eq( source, s_TRUE ) ) | ||
|  |             return true; | ||
|  | 
 | ||
|  |         if( case_ins_eq( source, s_NO ) || | ||
|  |             case_ins_eq( source, s_N ) || | ||
|  |             case_ins_eq( source, s_zero ) || | ||
|  |             case_ins_eq( source, s_FALSE ) ) | ||
|  |             return false; | ||
|  | 
 | ||
|  |         BOOST_TEST_I_THROW( format_error( param_name ) << source << " can't be interpreted as bool value." ); | ||
|  |     } | ||
|  | }; | ||
|  | 
 | ||
|  | //____________________________________________________________________________// | ||
|  | 
 | ||
|  | template<typename EnumType> | ||
|  | struct value_interpreter<EnumType, true> { | ||
|  |     template<typename Modifiers> | ||
|  |     explicit        value_interpreter( Modifiers const& m ) | ||
|  | #if defined(BOOST_TEST_CLA_NEW_API) | ||
|  |     : m_name_to_value( m[enum_values<EnumType>::value] ) | ||
|  |     { | ||
|  |     } | ||
|  | #else | ||
|  |     { | ||
|  |         std::vector<std::pair<cstring,EnumType> > const& values = m[enum_values<EnumType>::value]; | ||
|  | 
 | ||
|  |         m_name_to_value.insert( values.begin(), values.end() ); | ||
|  |     } | ||
|  | #endif | ||
|  | 
 | ||
|  |     EnumType        interpret( cstring param_name, cstring source ) const | ||
|  |     { | ||
|  |         typename std::map<cstring,EnumType>::const_iterator found = m_name_to_value.find( source ); | ||
|  | 
 | ||
|  |         BOOST_TEST_I_ASSRT( found != m_name_to_value.end(), | ||
|  |                             format_error( param_name ) << source << | ||
|  |                             " is not a valid enumeration value name for parameter " << param_name << "." ); | ||
|  | 
 | ||
|  |         return found->second; | ||
|  |     } | ||
|  | 
 | ||
|  | private: | ||
|  |     // Data members | ||
|  |     std::map<cstring,EnumType>  m_name_to_value; | ||
|  | }; | ||
|  | 
 | ||
|  | //____________________________________________________________________________// | ||
|  | 
 | ||
|  | // ************************************************************************** // | ||
|  | // **************           runtime::argument_factory          ************** // | ||
|  | // ************************************************************************** // | ||
|  | 
 | ||
|  | template<typename ValueType, bool is_enum, bool repeatable> | ||
|  | class argument_factory; | ||
|  | 
 | ||
|  | //____________________________________________________________________________// | ||
|  | 
 | ||
|  | template<typename ValueType, bool is_enum> | ||
|  | class argument_factory<ValueType, is_enum, false> { | ||
|  | public: | ||
|  |     template<typename Modifiers> | ||
|  |     explicit    argument_factory( Modifiers const& m ) | ||
|  |     : m_interpreter( m ) | ||
|  |     , m_optional_value( nfp::opt_get( m, optional_value, ValueType() ) ) | ||
|  |     , m_default_value( nfp::opt_get( m, default_value, ValueType() ) ) | ||
|  |     { | ||
|  |     } | ||
|  | 
 | ||
|  |     void        produce_argument( cstring source, cstring param_name, arguments_store& store ) const | ||
|  |     { | ||
|  |         store.set( param_name, source.empty() ? m_optional_value : m_interpreter.interpret( param_name, source ) ); | ||
|  |     } | ||
|  | 
 | ||
|  |     void        produce_default( cstring param_name, arguments_store& store ) const | ||
|  |     { | ||
|  |         store.set( param_name, m_default_value ); | ||
|  |     } | ||
|  | 
 | ||
|  | private: | ||
|  |     // Data members | ||
|  |     typedef value_interpreter<ValueType, is_enum> interp_t; | ||
|  |     interp_t    m_interpreter; | ||
|  |     ValueType   m_optional_value; | ||
|  |     ValueType   m_default_value; | ||
|  | }; | ||
|  | 
 | ||
|  | //____________________________________________________________________________// | ||
|  | 
 | ||
|  | template<typename ValueType, bool is_enum> | ||
|  | class argument_factory<ValueType, is_enum, true> { | ||
|  | public: | ||
|  |     template<typename Modifiers> | ||
|  |     explicit    argument_factory( Modifiers const& m ) | ||
|  |     : m_interpreter( m ) | ||
|  |     { | ||
|  |     } | ||
|  | 
 | ||
|  |     void        produce_argument( cstring source, cstring param_name, arguments_store& store ) const | ||
|  |     { | ||
|  |         ValueType value = m_interpreter.interpret( param_name, source ); | ||
|  | 
 | ||
|  |         if( store.has( param_name ) ) { | ||
|  |             std::vector<ValueType>& values = store.get<std::vector<ValueType> >( param_name ); | ||
|  |             values.push_back( value ); | ||
|  |         } | ||
|  |         else { | ||
|  |             std::vector<ValueType> values( 1, value ); | ||
|  | 
 | ||
|  |             store.set( param_name, values ); | ||
|  |         } | ||
|  | 
 | ||
|  |     } | ||
|  |     void        produce_default( cstring param_name, arguments_store& store ) const | ||
|  |     { | ||
|  |         store.set( param_name, std::vector<ValueType>() ); | ||
|  |     } | ||
|  | 
 | ||
|  | private: | ||
|  |     // Data members | ||
|  |     value_interpreter<ValueType, is_enum> m_interpreter; | ||
|  | }; | ||
|  | 
 | ||
|  | //____________________________________________________________________________// | ||
|  | 
 | ||
|  | } // namespace runtime | ||
|  | } // namespace boost | ||
|  | 
 | ||
|  | #include <boost/test/detail/enable_warnings.hpp> | ||
|  | 
 | ||
|  | #endif // BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP |