1
// (C) Copyright Gennadiy Rozental 2005-2008.
2
// Use, modification, and distribution are subject to the
3
// Boost Software License, Version 1.0. (See accompanying file
4
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
// See http://www.boost.org/libs/test for the library home page.
10
// Version : $Revision: 57992 $
12
// Description : generic typed_argument_factory implementation
13
// ***************************************************************************
15
#ifndef BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER
16
#define BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER
18
// Boost.Runtime.Parameter
19
#include <boost/test/utils/runtime/config.hpp>
21
#include <boost/test/utils/runtime/fwd.hpp>
22
#include <boost/test/utils/runtime/validation.hpp>
23
#include <boost/test/utils/runtime/argument.hpp>
24
#include <boost/test/utils/runtime/trace.hpp>
25
#include <boost/test/utils/runtime/interpret_argument_value.hpp>
27
#include <boost/test/utils/runtime/cla/fwd.hpp>
28
#include <boost/test/utils/runtime/cla/value_generator.hpp>
29
#include <boost/test/utils/runtime/cla/value_handler.hpp>
30
#include <boost/test/utils/runtime/cla/validation.hpp>
31
#include <boost/test/utils/runtime/cla/argv_traverser.hpp>
32
#include <boost/test/utils/runtime/cla/detail/argument_value_usage.hpp>
34
#include <boost/test/utils/runtime/cla/iface/argument_factory.hpp>
37
#include <boost/test/utils/callback.hpp>
40
#include <boost/optional.hpp>
44
namespace BOOST_RT_PARAM_NAMESPACE {
48
// ************************************************************************** //
49
// ************** default_value_interpreter ************** //
50
// ************************************************************************** //
52
namespace rt_cla_detail {
54
struct default_value_interpreter {
56
void operator()( argv_traverser& tr, boost::optional<T>& value )
58
if( interpret_argument_value( tr.token(), value, 0 ) )
63
} // namespace rt_cla_detail
65
// ************************************************************************** //
66
// ************** typed_argument_factory ************** //
67
// ************************************************************************** //
70
struct typed_argument_factory : public argument_factory {
72
typed_argument_factory()
73
: m_value_interpreter( rt_cla_detail::default_value_interpreter() )
75
BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~typed_argument_factory() {}
77
// properties modification
78
template<typename Modifier>
79
void accept_modifier( Modifier const& m )
81
optionally_assign( m_value_handler, m, handler );
82
optionally_assign( m_value_interpreter, m, interpreter );
84
if( m.has( default_value ) ) {
85
BOOST_RT_PARAM_VALIDATE_LOGIC( !m_value_generator,
86
BOOST_RT_PARAM_LITERAL( "multiple value generators for parameter" ) );
88
T const& dv_ref = m[default_value];
89
m_value_generator = rt_cla_detail::const_generator<T>( dv_ref );
92
if( m.has( default_refer_to ) ) {
93
BOOST_RT_PARAM_VALIDATE_LOGIC( !m_value_generator,
94
BOOST_RT_PARAM_LITERAL( "multiple value generators for parameter" ) );
96
cstring ref_id = m[default_refer_to];
97
m_value_generator = rt_cla_detail::ref_generator<T>( ref_id );
100
if( m.has( assign_to ) ) {
101
BOOST_RT_PARAM_VALIDATE_LOGIC( !m_value_handler,
102
BOOST_RT_PARAM_LITERAL( "multiple value handlers for parameter" ) );
104
m_value_handler = rt_cla_detail::assigner<T>( m[assign_to] );
108
// Argument factory implementation
109
virtual argument_ptr produce_using( parameter& p, argv_traverser& tr );
110
virtual argument_ptr produce_using( parameter& p, parser const& );
111
virtual void argument_usage_info( format_stream& fs );
115
unit_test::callback2<parameter const&,T&> m_value_handler;
116
unit_test::callback2<parser const&,boost::optional<T>&> m_value_generator;
117
unit_test::callback2<argv_traverser&,boost::optional<T>&> m_value_interpreter;
120
//____________________________________________________________________________//
124
typed_argument_factory<T>::produce_using( parameter& p, argv_traverser& tr )
126
boost::optional<T> value;
129
m_value_interpreter( tr, value );
131
catch( ... ) { // !! should we do that?
132
BOOST_RT_PARAM_TRACE( "Fail to parse argument value" );
134
if( !p.p_optional_value )
138
argument_ptr actual_arg = p.actual_argument();
140
BOOST_RT_CLA_VALIDATE_INPUT( !!value || p.p_optional_value, tr,
141
BOOST_RT_PARAM_LITERAL( "Argument value missing for parameter " ) << p.id_2_report() );
143
BOOST_RT_CLA_VALIDATE_INPUT( !actual_arg || p.p_multiplicable, tr,
144
BOOST_RT_PARAM_LITERAL( "Unexpected repetition of the parameter " ) << p.id_2_report() );
146
if( !!value && !!m_value_handler )
147
m_value_handler( p, *value );
149
if( !p.p_multiplicable )
150
actual_arg.reset( p.p_optional_value && (rtti::type_id<T>() != rtti::type_id<bool>())
151
? static_cast<argument*>(new typed_argument<boost::optional<T> >( p, value ))
152
: static_cast<argument*>(new typed_argument<T>( p, *value )) );
154
typedef std::list<boost::optional<T> > optional_list;
157
actual_arg.reset( p.p_optional_value
158
? static_cast<argument*>(new typed_argument<optional_list>( p ))
159
: static_cast<argument*>(new typed_argument<std::list<T> >( p )) );
161
if( p.p_optional_value ) {
162
optional_list& values = arg_value<optional_list>( *actual_arg );
164
values.push_back( value );
167
std::list<T>& values = arg_value<std::list<T> >( *actual_arg );
169
values.push_back( *value );
176
//____________________________________________________________________________//
180
typed_argument_factory<T>::produce_using( parameter& p, parser const& pa )
182
argument_ptr actual_arg;
184
if( !m_value_generator )
187
boost::optional<T> value;
188
m_value_generator( pa, value );
193
if( !!m_value_handler )
194
m_value_handler( p, *value );
196
actual_arg.reset( new typed_argument<T>( p, *value ) );
201
//____________________________________________________________________________//
205
typed_argument_factory<T>::argument_usage_info( format_stream& fs )
207
rt_cla_detail::argument_value_usage( fs, 0, reinterpret_cast<T*>(0) );
210
//____________________________________________________________________________//
214
} // namespace BOOST_RT_PARAM_NAMESPACE
218
#endif // BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER