source: NonGTP/Boost/boost/test/utils/runtime/cla/argument_factory.hpp @ 857

Revision 857, 7.4 KB checked in by igarcia, 18 years ago (diff)
Line 
1//  (C) Copyright Gennadiy Rozental 2005.
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)
5
6//  See http://www.boost.org/libs/test for the library home page.
7//
8//  File        : $RCSfile: argument_factory.hpp,v $
9//
10//  Version     : $Revision: 1.1 $
11//
12//  Description : generic typed_argument_factory implementation
13// ***************************************************************************
14
15#ifndef BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER
16#define BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER
17
18// Boost.Runtime.Parameter
19#include <boost/test/utils/runtime/config.hpp>
20
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>
26
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>
33
34#include <boost/test/utils/runtime/cla/iface/argument_factory.hpp>
35
36// Boost.Test
37#include <boost/test/utils/callback.hpp>
38
39// Boost
40#include <boost/optional.hpp>
41
42namespace boost {
43
44namespace BOOST_RT_PARAM_NAMESPACE {
45
46namespace cla {
47
48// ************************************************************************** //
49// **************           default_value_interpreter          ************** //
50// ************************************************************************** //
51
52namespace rt_cla_detail {
53
54struct default_value_interpreter {
55    template<typename T>
56    void operator()( argv_traverser& tr, boost::optional<T>& value )
57    {
58        if( interpret_argument_value( tr.token(), value, 0 ) )
59            tr.next_token();
60    }
61};
62
63} // namespace rt_cla_detail
64
65// ************************************************************************** //
66// **************             typed_argument_factory           ************** //
67// ************************************************************************** //
68
69template<typename T>
70struct typed_argument_factory : public argument_factory {
71    // Constructor
72    typed_argument_factory()
73    : m_value_interpreter( rt_cla_detail::default_value_interpreter() )
74    {}
75    BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~typed_argument_factory() {}
76
77    // properties modification
78    template<typename Modifier>
79    void                accept_modifier( Modifier const& m )
80    {
81        optionally_assign( m_value_handler, m, handler );
82        optionally_assign( m_value_interpreter, m, interpreter );
83
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" ) );
87
88            T const& dv_ref = m[default_value];
89            m_value_generator = rt_cla_detail::const_generator<T>( dv_ref );
90        }
91
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" ) );
95
96            cstring ref_id = m[default_refer_to];
97            m_value_generator = rt_cla_detail::ref_generator<T>( ref_id );
98        }
99
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" ) );
103
104            m_value_handler = rt_cla_detail::assigner<T>( m[assign_to] );
105        }
106    }
107
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 );
112
113// !! private?
114    // Data members
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;
118};
119
120//____________________________________________________________________________//
121
122template<typename T>
123inline argument_ptr
124typed_argument_factory<T>::produce_using( parameter& p, argv_traverser& tr )
125{
126    boost::optional<T> value;
127
128    try {
129        m_value_interpreter( tr, value );
130    }
131    catch( ... ) { // !! should we do that?
132        BOOST_RT_PARAM_TRACE( "Fail to parse argument value" );
133
134        if( !p.p_optional_value )
135            throw;
136    }
137
138    argument_ptr arg = p.actual_argument();
139
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() );
142
143    BOOST_RT_CLA_VALIDATE_INPUT( !arg || p.p_multiplicable, tr,
144        BOOST_RT_PARAM_LITERAL( "Unexpected repetition of the parameter " ) << p.id_2_report() );
145
146    if( !!value && !!m_value_handler )
147        m_value_handler( p, *value );
148
149    if( !p.p_multiplicable )
150        arg.reset( p.p_optional_value
151            ? (argument*)new typed_argument<boost::optional<T> >( p, value )
152            : (argument*)new typed_argument<T>( p, *value ) );
153    else {
154        typedef std::list<boost::optional<T> > optional_list;
155
156        if( !arg )
157            arg.reset( p.p_optional_value
158                ? (argument*)new typed_argument<optional_list>( p )
159                : (argument*)new typed_argument<std::list<T> >( p ) );
160
161        if( p.p_optional_value ) {
162            optional_list& values = arg_value<optional_list>( *arg );
163
164            values.push_back( value );
165        }
166        else {
167            std::list<T>& values = arg_value<std::list<T> >( *arg );
168           
169            values.push_back( *value );
170        }
171    }
172
173    return arg;
174}
175
176//____________________________________________________________________________//
177
178template<typename T>
179inline argument_ptr
180typed_argument_factory<T>::produce_using( parameter& p, parser const& pa )
181{
182    argument_ptr arg;
183
184    if( !m_value_generator )
185        return arg;
186
187    boost::optional<T> value;
188    m_value_generator( pa, value );
189
190    if( !value )
191        return arg;
192
193    if( !!m_value_handler )
194        m_value_handler( p, *value );
195
196    arg.reset( new typed_argument<T>( p, *value ) );
197
198    return arg;
199}
200
201//____________________________________________________________________________//
202
203template<typename T>
204inline void
205typed_argument_factory<T>::argument_usage_info( format_stream& fs )
206{
207    rt_cla_detail::argument_value_usage( fs, 0, (T*)0 );
208}
209
210//____________________________________________________________________________//
211
212} // namespace boost
213
214} // namespace BOOST_RT_PARAM_NAMESPACE
215
216} // namespace cla
217
218// ************************************************************************** //
219//   Revision History:
220//
221//   $Log: argument_factory.hpp,v $
222//   Revision 1.1  2005/04/12 06:42:42  rogeeff
223//   Runtime.Param library initial commit
224//
225// ************************************************************************** //
226
227#endif // BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER
Note: See TracBrowser for help on using the repository browser.