file_position.hpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*=============================================================================
  2. Boost.Wave: A Standard compliant C++ preprocessor library
  3. Definition of the position_iterator and file_position templates
  4. http://www.boost.org/
  5. Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
  6. Software License, Version 1.0. (See accompanying file
  7. LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. =============================================================================*/
  9. #if !defined(BOOST_FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED)
  10. #define BOOST_FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED
  11. #include <string>
  12. #include <ostream>
  13. #include <boost/assert.hpp>
  14. #include <boost/spirit/include/classic_version.hpp>
  15. #include <boost/spirit/include/classic_position_iterator.hpp>
  16. #include <boost/wave/wave_config.hpp>
  17. #if BOOST_WAVE_SERIALIZATION != 0
  18. #include <boost/serialization/serialization.hpp>
  19. #endif
  20. // this must occur after all of the includes and before any code appears
  21. #ifdef BOOST_HAS_ABI_HEADERS
  22. #include BOOST_ABI_PREFIX
  23. #endif
  24. ///////////////////////////////////////////////////////////////////////////////
  25. namespace boost {
  26. namespace wave {
  27. namespace util {
  28. ///////////////////////////////////////////////////////////////////////////////
  29. //
  30. // file_position
  31. //
  32. // A structure to hold positional information. This includes the filename,
  33. // line number and column number of a current token position.
  34. //
  35. ///////////////////////////////////////////////////////////////////////////////
  36. template <typename StringT>
  37. struct file_position {
  38. public:
  39. typedef StringT string_type;
  40. file_position()
  41. : file(), line(1), column(1)
  42. {}
  43. explicit file_position(string_type const& file_, std::size_t line_ = 1,
  44. std::size_t column_ = 1)
  45. : file(file_), line(line_), column(column_)
  46. {}
  47. // accessors
  48. string_type const &get_file() const { return file; }
  49. std::size_t get_line() const { return line; }
  50. std::size_t get_column() const { return column; }
  51. void set_file(string_type const &file_)
  52. {
  53. file = file_;
  54. }
  55. void set_line(std::size_t line_) { line = line_; }
  56. void set_column(std::size_t column_) { column = column_; }
  57. private:
  58. #if BOOST_WAVE_SERIALIZATION != 0
  59. friend class boost::serialization::access;
  60. template<typename Archive>
  61. void serialize(Archive &ar, const unsigned int version)
  62. {
  63. using namespace boost::serialization;
  64. ar & make_nvp("filename", file);
  65. ar & make_nvp("line", line);
  66. ar & make_nvp("column", column);
  67. }
  68. #endif
  69. string_type file;
  70. std::size_t line;
  71. std::size_t column;
  72. };
  73. template <typename StringT>
  74. bool operator== (file_position<StringT> const &lhs,
  75. file_position<StringT> const &rhs)
  76. {
  77. return lhs.get_column() == rhs.get_column() &&
  78. lhs.get_line() == rhs.get_line() && lhs.get_file() == rhs.get_file();
  79. }
  80. template <typename StringT>
  81. inline std::ostream &
  82. operator<< (std::ostream &o, file_position<StringT> const &pos)
  83. {
  84. o << pos.get_file() << ":" << pos.get_line() << ":" << pos.get_column();
  85. return o;
  86. }
  87. typedef file_position<BOOST_WAVE_STRINGTYPE> file_position_type;
  88. ///////////////////////////////////////////////////////////////////////////////
  89. //
  90. // position_iterator
  91. //
  92. // The position_iterator used by Wave is now based on the corresponding Spirit
  93. // type. This type is used with our own file_position though. The needed
  94. // specialization of the boost::spirit::classic::position_policy class is
  95. // provided below.
  96. //
  97. ///////////////////////////////////////////////////////////////////////////////
  98. template <typename IteratorT, typename PositionT>
  99. struct position_iterator
  100. : boost::spirit::classic::position_iterator<IteratorT, PositionT>
  101. {
  102. typedef boost::spirit::classic::position_iterator<IteratorT, PositionT> base_type;
  103. position_iterator()
  104. {
  105. }
  106. position_iterator(IteratorT const &begin, IteratorT const &end,
  107. PositionT const &pos)
  108. : base_type(begin, end, pos)
  109. {
  110. }
  111. };
  112. ///////////////////////////////////////////////////////////////////////////////
  113. } // namespace util
  114. } // namespace wave
  115. ///////////////////////////////////////////////////////////////////////////////
  116. namespace spirit { namespace classic {
  117. ///////////////////////////////////////////////////////////////////////////////
  118. //
  119. // The boost::spirit::classic::position_policy has to be specialized for our
  120. // file_position class
  121. //
  122. ///////////////////////////////////////////////////////////////////////////////
  123. template <>
  124. class position_policy<boost::wave::util::file_position_type> {
  125. public:
  126. position_policy()
  127. : m_CharsPerTab(4)
  128. {}
  129. void next_line(boost::wave::util::file_position_type &pos)
  130. {
  131. pos.set_line(pos.get_line() + 1);
  132. pos.set_column(1);
  133. }
  134. void set_tab_chars(unsigned int chars)
  135. {
  136. m_CharsPerTab = chars;
  137. }
  138. void next_char(boost::wave::util::file_position_type &pos)
  139. {
  140. pos.set_column(pos.get_column() + 1);
  141. }
  142. void tabulation(boost::wave::util::file_position_type &pos)
  143. {
  144. pos.set_column(pos.get_column() + m_CharsPerTab -
  145. (pos.get_column() - 1) % m_CharsPerTab);
  146. }
  147. private:
  148. unsigned int m_CharsPerTab;
  149. };
  150. ///////////////////////////////////////////////////////////////////////////////
  151. }} // namespace spirit::classic
  152. } // namespace boost
  153. // the suffix header occurs after all of the code
  154. #ifdef BOOST_HAS_ABI_HEADERS
  155. #include BOOST_ABI_SUFFIX
  156. #endif
  157. #endif // !defined(BOOST_FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED)