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
22namespace boost { namespace spirit { namespace detail
23{
24 ///////////////////////////////////////////////////////////////////////////
25#ifdef _MSC_VER
26# pragma warning(push)
27# pragma warning(disable: 4512) // assignment operator could not be generated.
28#endif
29 template <typename Context>
30 struct expand_arg
31 {
32 template <typename T>
33 struct result_type
34 {
35 // This is a temporary hack. The better way is to detect if T
36 // can be called given unused context.
37 typedef typename
38 mpl::eval_if<
39 mpl::or_<is_scalar<T>, traits::is_string<T> >
40 , mpl::identity<T const &>
41 , boost::result_of<T(unused_type, Context)>
42 >::type
43 type;
44 };
45
46 template <typename T>
47 struct result;
48
49 template <typename F, typename A0>
50 struct result<F(A0)>
51 : result_type<A0> {};
52
53 template <typename F, typename A0>
54 struct result<F(A0&)>
55 : result_type<A0> {};
56
57 expand_arg(Context& context_)
58 : context(context_)
59 {
60 }
61
62 template <typename T>
63 typename result_type<T>::type
64 call(T const& f, mpl::false_) const
65 {
66 return f(unused, context);
67 }
68
69 template <typename T>
70 typename result_type<T>::type
71 call(T const& val, mpl::true_) const
72 {
73 return val;
74 }
75
76 template <typename T>
77 typename result_type<T>::type
78 operator()(T const& x) const
79 {
80 return call(x, mpl::or_<is_scalar<T>, traits::is_string<T> >());
81 }
82
83 Context& context;
84 };
85#ifdef _MSC_VER
86# pragma warning(pop)
87#endif
88
89}}}
90
91#endif
92