1 // Copyright Daniel Wallin, David Abrahams 2005. Use, modification and
2 // distribution is subject to the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
6 #ifndef BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP
7 # define BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP
9 # include <boost/parameter/aux_/void.hpp>
10 # include <boost/parameter/aux_/arg_list.hpp>
11 # include <boost/parameter/aux_/result_of0.hpp>
12 # include <boost/mpl/if.hpp>
13 # include <boost/mpl/apply_wrap.hpp>
14 # include <boost/mpl/and.hpp>
15 # include <boost/mpl/not.hpp>
16 # include <boost/type_traits/is_same.hpp>
17 # include <boost/type_traits/is_convertible.hpp>
18 # include <boost/type_traits/is_reference.hpp>
20 namespace boost
{ namespace parameter
{ namespace aux
{
22 struct empty_arg_list
;
25 struct tagged_argument_base
{};
27 // Holds a reference to an argument of type Arg associated with
30 template <class Keyword
, class Arg
>
31 struct tagged_argument
: tagged_argument_base
33 typedef Keyword key_type
;
34 typedef Arg value_type
;
35 typedef Arg
& reference
;
37 tagged_argument(reference x
) : value(x
) {}
39 // A metafunction class that, given a keyword and a default
40 // type, returns the appropriate result type for a keyword
41 // lookup given that default
44 template <class KW
, class Default
, class Reference
>
47 typedef typename
mpl::eval_if
<
48 boost::is_same
<KW
, key_type
>
49 , mpl::if_
<Reference
, reference
, value_type
>
50 , mpl::identity
<Default
>
55 // Comma operator to compose argument list without using parameters<>.
56 // Useful for argument lists with undetermined length.
57 template <class Keyword2
, class Arg2
>
59 tagged_argument
<Keyword
, Arg
>
60 , arg_list
<tagged_argument
<Keyword2
, Arg2
> >
62 operator,(tagged_argument
<Keyword2
, Arg2
> x
) const
65 tagged_argument
<Keyword
, Arg
>
66 , arg_list
<tagged_argument
<Keyword2
, Arg2
> >
69 , arg_list
<tagged_argument
<Keyword2
, Arg2
> >(x
, empty_arg_list())
73 reference
operator[](keyword
<Keyword
> const&) const
78 # if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
79 template <class KW
, class Default
>
80 Default
& get_with_default(default_
<KW
,Default
> const& x
, int) const
85 template <class Default
>
86 reference
get_with_default(default_
<key_type
,Default
> const&, long) const
91 template <class KW
, class Default
>
92 typename
mpl::apply_wrap3
<binding
, KW
, Default
&, mpl::true_
>::type
93 operator[](default_
<KW
,Default
> const& x
) const
95 return get_with_default(x
, 0L);
98 template <class KW
, class F
>
99 typename result_of0
<F
>::type
100 get_with_lazy_default(lazy_default
<KW
,F
> const& x
, int) const
102 return x
.compute_default();
106 reference
get_with_lazy_default(lazy_default
<key_type
,F
> const&, long) const
111 template <class KW
, class F
>
112 typename
mpl::apply_wrap3
<
114 , typename result_of0
<F
>::type
117 operator[](lazy_default
<KW
,F
> const& x
) const
119 return get_with_lazy_default(x
, 0L);
122 template <class Default
>
123 reference
operator[](default_
<key_type
,Default
> const& x
) const
129 reference
operator[](lazy_default
<key_type
,F
> const& x
) const
134 template <class KW
, class Default
>
135 Default
& operator[](default_
<KW
,Default
> const& x
) const
140 template <class KW
, class F
>
141 typename result_of0
<F
>::type
operator[](lazy_default
<KW
,F
> const& x
) const
143 return x
.compute_default();
146 template <class ParameterRequirements
>
147 static typename
ParameterRequirements::has_default
148 satisfies(ParameterRequirements
*);
150 template <class HasDefault
, class Predicate
>
151 static typename
mpl::apply1
<Predicate
, value_type
>::type
153 parameter_requirements
<key_type
,Predicate
,HasDefault
>*
158 # if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
159 // warning suppression
161 void operator=(tagged_argument
const&);
164 // MPL sequence support
165 typedef tagged_argument type
; // Convenience for users
166 typedef empty_arg_list tail_type
; // For the benefit of iterators
167 typedef arg_list_tag tag
; // For dispatching to sequence intrinsics
170 // Defines a metafunction, is_tagged_argument, that identifies
171 // tagged_argument specializations and their derived classes.
173 struct is_tagged_argument_aux
174 : is_convertible
<T
*,tagged_argument_base
const*>
178 struct is_tagged_argument
180 mpl::not_
<is_reference
<T
> >
181 , is_tagged_argument_aux
<T
>
185 }}} // namespace boost::parameter::aux
187 #endif // BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP