expand_arg.hpp 2.5 KB

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