9
3

position_iterator.ipp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*=============================================================================
  2. Copyright (c) 2002 Juan Carlos Arevalo-Baeza
  3. Copyright (c) 2002-2006 Hartmut Kaiser
  4. Copyright (c) 2003 Giovanni Bajo
  5. http://spirit.sourceforge.net/
  6. Use, modification and distribution is subject to the Boost Software
  7. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  8. http://www.boost.org/LICENSE_1_0.txt)
  9. =============================================================================*/
  10. #ifndef POSITION_ITERATOR_IPP
  11. #define POSITION_ITERATOR_IPP
  12. #include <boost/config.hpp>
  13. #include <boost/iterator_adaptors.hpp>
  14. #include <boost/type_traits/add_const.hpp>
  15. #include <boost/mpl/if.hpp>
  16. #include <boost/type_traits/is_same.hpp>
  17. #include <boost/spirit/home/classic/core/nil.hpp> // for nil_t
  18. #include <iterator> // for std::iterator_traits
  19. namespace boost { namespace spirit {
  20. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  21. ///////////////////////////////////////////////////////////////////////////////
  22. //
  23. // position_policy<file_position_without_column>
  24. //
  25. // Specialization to handle file_position_without_column. Only take care of
  26. // newlines since no column tracking is needed.
  27. //
  28. ///////////////////////////////////////////////////////////////////////////////
  29. template <typename String>
  30. class position_policy<file_position_without_column_base<String> > {
  31. public:
  32. void next_line(file_position_without_column_base<String>& pos)
  33. {
  34. ++pos.line;
  35. }
  36. void set_tab_chars(unsigned int /*chars*/){}
  37. void next_char(file_position_without_column_base<String>& /*pos*/) {}
  38. void tabulation(file_position_without_column_base<String>& /*pos*/) {}
  39. };
  40. ///////////////////////////////////////////////////////////////////////////////
  41. //
  42. // position_policy<file_position>
  43. //
  44. // Specialization to handle file_position. Track characters and tabulation
  45. // to compute the current column correctly.
  46. //
  47. // Default tab size is 4. You can change this with the set_tabchars member
  48. // of position_iterator.
  49. //
  50. ///////////////////////////////////////////////////////////////////////////////
  51. template <typename String>
  52. class position_policy<file_position_base<String> > {
  53. public:
  54. position_policy()
  55. : m_CharsPerTab(4)
  56. {}
  57. void next_line(file_position_base<String>& pos)
  58. {
  59. ++pos.line;
  60. pos.column = 1;
  61. }
  62. void set_tab_chars(unsigned int chars)
  63. {
  64. m_CharsPerTab = chars;
  65. }
  66. void next_char(file_position_base<String>& pos)
  67. {
  68. ++pos.column;
  69. }
  70. void tabulation(file_position_base<String>& pos)
  71. {
  72. pos.column += m_CharsPerTab - (pos.column - 1) % m_CharsPerTab;
  73. }
  74. private:
  75. unsigned int m_CharsPerTab;
  76. };
  77. /* namespace boost::spirit { */ namespace iterator_ { namespace impl {
  78. template <typename T>
  79. struct make_const : boost::add_const<T>
  80. {};
  81. template <typename T>
  82. struct make_const<T&>
  83. {
  84. typedef typename boost::add_const<T>::type& type;
  85. };
  86. ///////////////////////////////////////////////////////////////////////////////
  87. //
  88. // position_iterator_base_generator
  89. //
  90. // Metafunction to generate the iterator type using boost::iterator_adaptors,
  91. // hiding all the metaprogramming thunking code in it. It is used
  92. // mainly to keep the public interface (position_iterator) cleanear.
  93. //
  94. ///////////////////////////////////////////////////////////////////////////////
  95. template <typename MainIterT, typename ForwardIterT, typename PositionT>
  96. struct position_iterator_base_generator
  97. {
  98. private:
  99. typedef std::iterator_traits<ForwardIterT> traits;
  100. typedef typename traits::value_type value_type;
  101. typedef typename traits::iterator_category iter_category_t;
  102. typedef typename traits::reference reference;
  103. // Position iterator is always a non-mutable iterator
  104. typedef typename boost::add_const<value_type>::type const_value_type;
  105. public:
  106. // Check if the MainIterT is nil. If it's nil, it means that the actual
  107. // self type is position_iterator. Otherwise, it's a real type we
  108. // must use
  109. typedef typename boost::mpl::if_<
  110. typename boost::is_same<MainIterT, nil_t>::type,
  111. position_iterator<ForwardIterT, PositionT, nil_t>,
  112. MainIterT
  113. >::type main_iter_t;
  114. typedef boost::iterator_adaptor<
  115. main_iter_t,
  116. ForwardIterT,
  117. const_value_type,
  118. boost::forward_traversal_tag,
  119. typename make_const<reference>::type
  120. > type;
  121. };
  122. }}
  123. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  124. }} /* namespace boost::spirit::iterator_::impl */
  125. #endif