source: NonGTP/Boost/boost/test/utils/named_params.hpp @ 857

Revision 857, 11.8 KB checked in by igarcia, 18 years ago (diff)
Line 
1//  (C) Copyright Gennadiy Rozental 2005.
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: named_params.hpp,v $
9//
10//  Version     : $Revision: 1.4 $
11//
12//  Description : facilities for named function parameters support
13// ***************************************************************************
14
15#ifndef BOOST_TEST_NAMED_PARAM_022505GER
16#define BOOST_TEST_NAMED_PARAM_022505GER
17
18// Boost
19#include <boost/config.hpp>
20#include <boost/detail/workaround.hpp>
21
22// Boost.Test
23#include <boost/test/utils/rtti.hpp>
24#include <boost/test/utils/assign_op.hpp>
25
26//____________________________________________________________________________//
27
28namespace boost {
29
30namespace nfp { // named function parameters
31
32// ************************************************************************** //
33// **************              forward declarations            ************** //
34// ************************************************************************** //
35
36template<typename T, typename unique_id,typename RefType>   struct named_parameter;
37template<typename unique_id,bool required>                  struct keyword;
38
39namespace nfp_detail {
40
41template<typename NP1,typename NP2>        struct named_parameter_combine;
42
43// ************************************************************************** //
44// **************          access_to_invalid_parameter         ************** //
45// ************************************************************************** //
46
47struct access_to_invalid_parameter {};
48
49//____________________________________________________________________________//
50
51inline void
52report_access_to_invalid_parameter()
53{
54    throw access_to_invalid_parameter();
55}
56
57//____________________________________________________________________________//
58
59// ************************************************************************** //
60// **************                       nil                    ************** //
61// ************************************************************************** //
62
63struct nil {
64    template<typename T>
65    operator T() const
66    { report_access_to_invalid_parameter(); static T* v = 0; return *v; }
67
68    template<typename Arg1>
69    nil operator()( Arg1 const& )
70    { report_access_to_invalid_parameter(); return nil(); }
71
72    template<typename Arg1,typename Arg2>
73    nil operator()( Arg1 const&, Arg2 const& )
74    { report_access_to_invalid_parameter(); return nil(); }
75
76    template<typename Arg1,typename Arg2,typename Arg3>
77    nil operator()( Arg1 const&, Arg2 const&, Arg3 const& )
78    { report_access_to_invalid_parameter(); return nil(); }
79
80    // Visitation support
81    template<typename Visitor>
82    void            apply_to( Visitor& V ) const {}
83};
84   
85// ************************************************************************** //
86// **************              named_parameter_base            ************** //
87// ************************************************************************** //
88
89template<typename Derived>
90struct named_parameter_base {
91    template<typename NP>
92    named_parameter_combine<NP,Derived>
93    operator,( NP const& np ) const { return named_parameter_combine<NP,Derived>( np, *static_cast<Derived const*>(this) ); }
94};
95
96//____________________________________________________________________________//
97
98#if BOOST_WORKAROUND( __SUNPRO_CC, == 0x530 )
99
100struct unknown_id_helper {
101    template<typename UnknownId>
102    nil     operator[]( keyword<UnknownId,false> kw ) const { return nil(); }
103
104    template<typename UnknownId>
105    bool    has( keyword<UnknownId,false> ) const           { return false; }
106};
107
108#endif
109
110//____________________________________________________________________________//
111
112// ************************************************************************** //
113// **************             named_parameter_combine          ************** //
114// ************************************************************************** //
115
116template<typename NP, typename Rest = nil>
117struct named_parameter_combine : Rest, named_parameter_base<named_parameter_combine<NP,Rest> > {
118    typedef typename NP::ref_type  res_type;
119    typedef named_parameter_combine<NP,Rest> self_type;
120
121    // Constructor
122    named_parameter_combine( NP const& np, Rest const& r )
123    : Rest( r ), m_param( np ) {}
124
125    // Access methods
126    res_type    operator[]( keyword<typename NP::id,true> kw ) const    { return m_param[kw]; }
127    res_type    operator[]( keyword<typename NP::id,false> kw ) const   { return m_param[kw]; }
128    using       Rest::operator[];
129
130    bool        has( keyword<typename NP::id,false> ) const             { return true; }
131    using       Rest::has;
132
133    #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
134    template<typename NP>
135    named_parameter_combine<NP,self_type> operator,( NP const& np ) const
136    { return named_parameter_combine<NP,self_type>( np, *this ); }
137    #else
138    using       named_parameter_base<named_parameter_combine<NP,Rest> >::operator,;
139    #endif
140
141    // Visitation support
142    template<typename Visitor>
143    void            apply_to( Visitor& V ) const
144    {
145        m_param.apply_to( V );
146
147        Rest::apply_to( V );
148    }
149private:
150    // Data members
151    NP          m_param;
152};
153
154} // namespace nfp_detail
155
156// ************************************************************************** //
157// **************             named_parameter_combine          ************** //
158// ************************************************************************** //
159
160template<typename T, typename unique_id,typename ReferenceType=T&>
161struct named_parameter
162: nfp_detail::named_parameter_base<named_parameter<T, unique_id,ReferenceType> >
163#if BOOST_WORKAROUND( __SUNPRO_CC, == 0x530 )
164, nfp_detail::unknown_id_helper
165#endif
166{
167    typedef T               data_type;
168    typedef ReferenceType   ref_type;
169    typedef unique_id       id;
170
171    // Constructor
172    explicit        named_parameter( ref_type v ) : m_value( v ) {}
173
174    // Access methods
175    ref_type        operator[]( keyword<unique_id,true> ) const     { return m_value; }
176    ref_type        operator[]( keyword<unique_id,false> ) const    { return m_value; }
177#if BOOST_WORKAROUND( __SUNPRO_CC, == 0x530 )
178    using           nfp_detail::unknown_id_helper::operator[];
179#else
180    template<typename UnknownId>
181    nfp_detail::nil  operator[]( keyword<UnknownId,false> ) const   { return nfp_detail::nil(); }
182#endif
183
184    bool            has( keyword<unique_id,false> ) const           { return true; }
185#if BOOST_WORKAROUND( __SUNPRO_CC, == 0x530 )
186    using           nfp_detail::unknown_id_helper::has;
187#else
188    template<typename UnknownId>
189    bool            has( keyword<UnknownId,false> ) const           { return false; }
190#endif
191
192    // Visitation support
193    template<typename Visitor>
194    void            apply_to( Visitor& V ) const
195    {
196        V.set_parameter( rtti::type_id<unique_id>(), m_value );
197    }
198
199private:
200    // Data members
201    ref_type        m_value;
202};
203
204//____________________________________________________________________________//
205
206// ************************************************************************** //
207// **************                    no_params                 ************** //
208// ************************************************************************** //
209
210namespace nfp_detail {
211typedef named_parameter<char, struct no_params_type_t,char> no_params_type;
212}
213
214namespace {
215nfp_detail::no_params_type no_params( '\0' );
216} // local namespace
217
218//____________________________________________________________________________//
219
220// ************************************************************************** //
221// **************                     keyword                  ************** //
222// ************************************************************************** //
223
224template<typename unique_id, bool required = false>
225struct keyword {
226    typedef unique_id id;
227
228    template<typename T>
229    named_parameter<T const,unique_id>
230    operator=( T const& t ) const       { return named_parameter<T const,unique_id>( t ); }
231
232    template<typename T>
233    named_parameter<T,unique_id>
234    operator=( T& t ) const   { return named_parameter<T,unique_id>( t ); }
235
236    named_parameter<char const*,unique_id,char const*>
237    operator=( char const* t ) const   { return named_parameter<char const*,unique_id,char const*>( t ); }
238};
239
240//____________________________________________________________________________//
241
242// ************************************************************************** //
243// **************                  typed_keyword               ************** //
244// ************************************************************************** //
245
246template<typename T, typename unique_id, bool required = false>
247struct typed_keyword : keyword<unique_id,required> {
248    named_parameter<T const,unique_id>
249    operator=( T const& t ) const       { return named_parameter<T const,unique_id>( t ); }
250
251    named_parameter<T,unique_id>
252    operator=( T& t ) const             { return named_parameter<T,unique_id>( t ); }
253};
254
255//____________________________________________________________________________//
256
257template<typename unique_id>
258struct typed_keyword<bool,unique_id,false>
259: keyword<unique_id,false>
260, named_parameter<bool,unique_id,bool> {
261    typedef unique_id id;
262
263    typed_keyword() : named_parameter<bool,unique_id,bool>( true ) {}
264
265    named_parameter<bool,unique_id,bool>
266    operator!() const           { return named_parameter<bool,unique_id,bool>( false ); }
267};
268
269//____________________________________________________________________________//
270
271// ************************************************************************** //
272// **************                optionally_assign             ************** //
273// ************************************************************************** //
274
275template<typename T>
276inline void
277optionally_assign( T&, nfp_detail::nil )
278{
279    nfp_detail::report_access_to_invalid_parameter();
280}
281
282//____________________________________________________________________________//
283
284template<typename T, typename Source>
285inline void
286#if BOOST_WORKAROUND( __MWERKS__, BOOST_TESTED_AT( 0x3003 ) ) \
287    || BOOST_WORKAROUND( __DECCXX_VER, BOOST_TESTED_AT(60590042) )
288optionally_assign( T& target, Source src )
289#else
290optionally_assign( T& target, Source const& src )
291#endif
292{
293    using namespace unit_test;
294
295    assign_op( target, src, 0 );
296}
297
298//____________________________________________________________________________//
299
300template<typename T, typename Params, typename Keyword>
301inline void
302optionally_assign( T& target, Params const& p, Keyword k )
303{
304    if( p.has(k) )
305        optionally_assign( target, p[k] );
306}
307
308//____________________________________________________________________________//
309
310} // namespace nfp
311
312} // namespace boost
313
314// ***************************************************************************
315//   Revision History:
316// 
317//  $Log: named_params.hpp,v $
318//  Revision 1.4  2005/06/13 10:35:08  schoepflin
319//  Enable optionally_assign() overload workaround for Tru64/CXX-6.5 as well.
320//
321//  Revision 1.3  2005/06/05 18:10:59  grafik
322//  named_param.hpp; Work around CW not handling operator, using declaration, by using a real operator,().
323//  token_iterator_test.cpp; Work around CW-8 confused with array initialization.
324//
325//  Revision 1.2  2005/05/03 05:02:49  rogeeff
326//  como fixes
327//
328//  Revision 1.1  2005/04/12 06:48:12  rogeeff
329//  Runtime.Param library initial commit
330//
331// ***************************************************************************
332
333#endif // BOOST_TEST_NAMED_PARAM_022505GER
334
Note: See TracBrowser for help on using the repository browser.