• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #if !defined(BOOST_SPIRIT_EXPAND_ARG_FEB_19_2007_1107AM)
8 #define BOOST_SPIRIT_EXPAND_ARG_FEB_19_2007_1107AM
9 
10 #if defined(_MSC_VER)
11 #pragma once
12 #endif
13 
14 #include <boost/mpl/bool.hpp>
15 #include <boost/mpl/or.hpp>
16 #include <boost/mpl/identity.hpp>
17 #include <boost/mpl/eval_if.hpp>
18 #include <boost/utility/result_of.hpp>
19 #include <boost/type_traits/is_scalar.hpp>
20 #include <boost/spirit/home/support/string_traits.hpp>
21 
22 namespace boost { namespace spirit { namespace detail
23 {
24     ///////////////////////////////////////////////////////////////////////////
25     template <typename Context>
26     struct expand_arg
27     {
28         template <typename T>
29         struct result_type
30         {
31             // This is a temporary hack. The better way is to detect if T
32             // can be called given unused context.
33             typedef typename
34                 mpl::eval_if<
35                     mpl::or_<is_scalar<T>, traits::is_string<T> >
36                   , mpl::identity<T const &>
37                   , boost::result_of<T(unused_type, Context)>
38                 >::type
39             type;
40         };
41 
42         template <typename T>
43         struct result;
44 
45         template <typename F, typename A0>
46         struct result<F(A0)>
47           : result_type<A0> {};
48 
49         template <typename F, typename A0>
50         struct result<F(A0&)>
51           : result_type<A0> {};
52 
expand_argboost::spirit::detail::expand_arg53         expand_arg(Context& context_)
54           : context(context_)
55         {
56         }
57 
58         template <typename T>
59         typename result_type<T>::type
callboost::spirit::detail::expand_arg60         call(T const& f, mpl::false_) const
61         {
62             return f(unused, context);
63         }
64 
65         template <typename T>
66         typename result_type<T>::type
callboost::spirit::detail::expand_arg67         call(T const& val, mpl::true_) const
68         {
69             return val;
70         }
71 
72         template <typename T>
73         typename result_type<T>::type
operator ()boost::spirit::detail::expand_arg74         operator()(T const& x) const
75         {
76             return call(x, mpl::or_<is_scalar<T>, traits::is_string<T> >());
77         }
78 
79         Context& context;
80 
81         // silence MSVC warning C4512: assignment operator could not be generated
82         BOOST_DELETED_FUNCTION(expand_arg& operator= (expand_arg const&))
83     };
84 
85 }}}
86 
87 #endif
88