expand_arg.hpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. #ifdef _MSC_VER
  22. # pragma warning(push)
  23. # pragma warning(disable: 4512) // assignment operator could not be generated.
  24. #endif
  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. template <typename T>
  42. struct result;
  43. template <typename F, typename A0>
  44. struct result<F(A0)>
  45. : result_type<A0> {};
  46. template <typename F, typename A0>
  47. struct result<F(A0&)>
  48. : result_type<A0> {};
  49. expand_arg(Context& context_)
  50. : context(context_)
  51. {
  52. }
  53. template <typename T>
  54. typename result_type<T>::type
  55. call(T const& f, mpl::false_) const
  56. {
  57. return f(unused, context);
  58. }
  59. template <typename T>
  60. typename result_type<T>::type
  61. call(T const& val, mpl::true_) const
  62. {
  63. return val;
  64. }
  65. template <typename T>
  66. typename result_type<T>::type
  67. operator()(T const& x) const
  68. {
  69. return call(x, mpl::or_<is_scalar<T>, traits::is_string<T> >());
  70. }
  71. Context& context;
  72. };
  73. #ifdef _MSC_VER
  74. # pragma warning(pop)
  75. #endif
  76. }}}
  77. #endif