reference.hpp 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright (c) 2001-2011 Joel de Guzman
  2. // Copyright (c) 2001-2011 Hartmut Kaiser
  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. #if !defined(BOOST_SPIRIT_KARMA_REFERENCE_APR_17_2009_1057PM)
  7. #define BOOST_SPIRIT_KARMA_REFERENCE_APR_17_2009_1057PM
  8. #if defined(_MSC_VER)
  9. #pragma once
  10. #endif
  11. #include <boost/spirit/home/karma/meta_compiler.hpp>
  12. #include <boost/spirit/home/karma/generator.hpp>
  13. #include <boost/spirit/home/support/info.hpp>
  14. #include <boost/spirit/home/support/handles_container.hpp>
  15. #include <boost/type_traits/remove_const.hpp>
  16. #include <boost/ref.hpp>
  17. namespace boost { namespace spirit { namespace karma
  18. {
  19. ///////////////////////////////////////////////////////////////////////////
  20. // reference is a generator that references another generator (its Subject)
  21. ///////////////////////////////////////////////////////////////////////////
  22. template <typename Subject>
  23. struct reference : generator<reference<Subject> >
  24. {
  25. typedef mpl::int_<generator_properties::all_properties> properties;
  26. typedef Subject subject_type;
  27. reference(Subject& subject)
  28. : ref(subject) {}
  29. template <typename Context, typename Unused>
  30. struct attribute : Subject::template attribute<Context, Unused> {};
  31. // Default overload, used whenever the attribute is not unused and not
  32. // used from an aliased rule.
  33. template <typename OutputIterator, typename Context
  34. , typename Delimiter, typename Attribute>
  35. bool generate(OutputIterator& sink, Context& context
  36. , Delimiter const& delim, Attribute const& attr) const
  37. {
  38. return ref.get().generate(sink, context, delim, attr);
  39. }
  40. // This overload gets called from an aliased rule only, we take the
  41. // attribute from the context provided from the wrapper rule.
  42. template <typename OutputIterator, typename Context
  43. , typename Delimiter>
  44. bool generate(OutputIterator& sink, Context& context
  45. , Delimiter const& delim, unused_type) const
  46. {
  47. return ref.get().generate(sink, context, delim, context.attributes);
  48. }
  49. // This overload is used whenever no attribute is given and it is used
  50. // not from an aliased rule.
  51. template <typename OutputIterator, typename Delimiter>
  52. bool generate(OutputIterator& sink, unused_type
  53. , Delimiter const& delim, unused_type) const
  54. {
  55. return ref.get().generate(sink, unused, delim, unused);
  56. }
  57. template <typename Context>
  58. info what(Context& context) const
  59. {
  60. // the reference is transparent (does not add any info)
  61. return ref.get().what(context);
  62. }
  63. boost::reference_wrapper<Subject> ref;
  64. };
  65. }}}
  66. namespace boost { namespace spirit { namespace traits
  67. {
  68. ///////////////////////////////////////////////////////////////////////////
  69. template <typename Subject, typename Attribute, typename Context
  70. , typename Iterator>
  71. struct handles_container<karma::reference<Subject>, Attribute
  72. , Context, Iterator>
  73. : handles_container<typename remove_const<Subject>::type, Attribute
  74. , Context, Iterator>
  75. {};
  76. }}}
  77. #endif