call.hpp 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /*=============================================================================
  2. Copyright (c) 2001-2014 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_X3_CALL_CONTEXT_MAY_26_2014_0234PM)
  7. #define BOOST_SPIRIT_X3_CALL_CONTEXT_MAY_26_2014_0234PM
  8. #include <type_traits>
  9. #include <boost/spirit/home/x3/support/context.hpp>
  10. #include <boost/spirit/home/x3/support/utility/is_callable.hpp>
  11. #include <boost/range/iterator_range.hpp>
  12. namespace boost { namespace spirit { namespace x3
  13. {
  14. ////////////////////////////////////////////////////////////////////////////
  15. struct rule_val_context_tag;
  16. template <typename Context>
  17. inline decltype(auto) _val(Context const& context)
  18. {
  19. return x3::get<rule_val_context_tag>(context);
  20. }
  21. ////////////////////////////////////////////////////////////////////////////
  22. struct where_context_tag;
  23. template <typename Context>
  24. inline decltype(auto) _where(Context const& context)
  25. {
  26. return x3::get<where_context_tag>(context);
  27. }
  28. ////////////////////////////////////////////////////////////////////////////
  29. struct attr_context_tag;
  30. template <typename Context>
  31. inline decltype(auto) _attr(Context const& context)
  32. {
  33. return x3::get<attr_context_tag>(context);
  34. }
  35. ////////////////////////////////////////////////////////////////////////////
  36. namespace detail
  37. {
  38. template <typename F, typename Context>
  39. auto call(F f, Context const& context, mpl::true_)
  40. {
  41. return f(context);
  42. }
  43. template <typename F, typename Context>
  44. auto call(F f, Context const& /* context */, mpl::false_)
  45. {
  46. return f();
  47. }
  48. }
  49. template <
  50. typename F, typename Iterator
  51. , typename Context, typename RuleContext, typename Attribute>
  52. auto call(
  53. F f, Iterator& first, Iterator const& last
  54. , Context const& context, RuleContext& rcontext, Attribute& attr)
  55. {
  56. boost::iterator_range<Iterator> rng(first, last);
  57. auto val_context = make_context<rule_val_context_tag>(rcontext, context);
  58. auto where_context = make_context<where_context_tag>(rng, val_context);
  59. auto attr_context = make_context<attr_context_tag>(attr, where_context);
  60. return detail::call(f, attr_context, is_callable<F(decltype(attr_context) const&)>());
  61. }
  62. }}}
  63. #endif