diff options
Diffstat (limited to 'boost/test/utils/runtime/argument_factory.hpp')
-rw-r--r-- | boost/test/utils/runtime/argument_factory.hpp | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/boost/test/utils/runtime/argument_factory.hpp b/boost/test/utils/runtime/argument_factory.hpp new file mode 100644 index 0000000000..a163deb9a2 --- /dev/null +++ b/boost/test/utils/runtime/argument_factory.hpp @@ -0,0 +1,242 @@ +// (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_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) + : 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 |