confix.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright (c) 2001-2011 Hartmut Kaiser
  2. //
  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. #if !defined(BOOST_SPIRIT_REPOSITORY_KARMA_CONFIX_AUG_19_2008_1041AM)
  6. #define BOOST_SPIRIT_REPOSITORY_KARMA_CONFIX_AUG_19_2008_1041AM
  7. #if defined(_MSC_VER)
  8. #pragma once
  9. #endif
  10. #include <boost/spirit/home/support/common_terminals.hpp>
  11. #include <boost/spirit/home/support/info.hpp>
  12. #include <boost/spirit/home/support/unused.hpp>
  13. #include <boost/spirit/home/karma/detail/attributes.hpp>
  14. #include <boost/spirit/home/karma/domain.hpp>
  15. #include <boost/spirit/home/karma/meta_compiler.hpp>
  16. #include <boost/spirit/repository/home/support/confix.hpp>
  17. #include <boost/fusion/include/vector.hpp>
  18. #include <boost/mpl/or.hpp>
  19. ///////////////////////////////////////////////////////////////////////////////
  20. namespace boost { namespace spirit
  21. {
  22. ///////////////////////////////////////////////////////////////////////////
  23. // Enablers
  24. ///////////////////////////////////////////////////////////////////////////
  25. // enables confix(..., ...)[]
  26. template <typename Prefix, typename Suffix>
  27. struct use_directive<karma::domain
  28. , terminal_ex<repository::tag::confix, fusion::vector2<Prefix, Suffix> > >
  29. : mpl::true_ {};
  30. // enables *lazy* confix(..., ...)[g]
  31. template <>
  32. struct use_lazy_directive<karma::domain, repository::tag::confix, 2>
  33. : mpl::true_ {};
  34. }}
  35. ///////////////////////////////////////////////////////////////////////////////
  36. namespace boost { namespace spirit { namespace repository { namespace karma
  37. {
  38. #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
  39. using repository::confix;
  40. #endif
  41. using repository::confix_type;
  42. ///////////////////////////////////////////////////////////////////////////
  43. template <typename Subject, typename Prefix, typename Suffix>
  44. struct confix_generator
  45. : spirit::karma::primitive_generator<confix_generator<Subject, Prefix, Suffix> >
  46. {
  47. typedef Subject subject_type;
  48. template <typename Context, typename Iterator>
  49. struct attribute
  50. : traits::attribute_of<subject_type, Context, Iterator>
  51. {};
  52. confix_generator(Subject const& subject, Prefix const& prefix
  53. , Suffix const& suffix)
  54. : subject(subject), prefix(prefix), suffix(suffix) {}
  55. ///////////////////////////////////////////////////////////////////////
  56. template <typename OutputIterator, typename Context, typename Delimiter
  57. , typename Attribute>
  58. bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
  59. , Attribute const& attr) const
  60. {
  61. // generate the prefix, the embedded item and the suffix
  62. return prefix.generate(sink, ctx, d, unused) &&
  63. subject.generate(sink, ctx, d, attr) &&
  64. suffix.generate(sink, ctx, d, unused);
  65. }
  66. template <typename Context>
  67. info what(Context const& ctx) const
  68. {
  69. return info("confix", subject.what(ctx));
  70. }
  71. Subject subject;
  72. Prefix prefix;
  73. Suffix suffix;
  74. };
  75. }}}}
  76. ///////////////////////////////////////////////////////////////////////////////
  77. namespace boost { namespace spirit { namespace karma
  78. {
  79. ///////////////////////////////////////////////////////////////////////////
  80. // Generator generators: make_xxx function (objects)
  81. ///////////////////////////////////////////////////////////////////////////
  82. // creates confix(..., ...)[] directive generator
  83. template <typename Prefix, typename Suffix, typename Subject
  84. , typename Modifiers>
  85. struct make_directive<
  86. terminal_ex<repository::tag::confix, fusion::vector2<Prefix, Suffix> >
  87. , Subject, Modifiers>
  88. {
  89. typedef typename
  90. result_of::compile<karma::domain, Prefix, Modifiers>::type
  91. prefix_type;
  92. typedef typename
  93. result_of::compile<karma::domain, Suffix, Modifiers>::type
  94. suffix_type;
  95. typedef repository::karma::confix_generator<
  96. Subject, prefix_type, suffix_type> result_type;
  97. template <typename Terminal>
  98. result_type operator()(Terminal const& term, Subject const& subject
  99. , Modifiers const& modifiers) const
  100. {
  101. return result_type(subject
  102. , compile<karma::domain>(fusion::at_c<0>(term.args), modifiers)
  103. , compile<karma::domain>(fusion::at_c<1>(term.args), modifiers));
  104. }
  105. };
  106. }}}
  107. namespace boost { namespace spirit { namespace traits
  108. {
  109. template <typename Subject, typename Prefix, typename Suffix>
  110. struct has_semantic_action<
  111. repository::karma::confix_generator<Subject, Prefix, Suffix> >
  112. : mpl::or_<
  113. has_semantic_action<Subject>
  114. , has_semantic_action<Prefix>
  115. , has_semantic_action<Suffix>
  116. > {};
  117. }}}
  118. #endif