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