real_position_token.hpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*=============================================================================
  2. Boost.Wave: A Standard compliant C++ preprocessor library
  3. A C++ lexer token definition for the real_positions example
  4. http://www.boost.org/
  5. Copyright (c) 2001-2010 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(REAL_POSITION_TOKEN_HPP_HK_061109_INCLUDED)
  10. #define REAL_POSITION_TOKEN_HPP_HK_061109_INCLUDED
  11. #include <boost/wave/wave_config.hpp>
  12. #include <boost/wave/util/file_position.hpp>
  13. #include <boost/wave/token_ids.hpp>
  14. #include <boost/wave/language_support.hpp>
  15. #include <boost/detail/atomic_count.hpp>
  16. ///////////////////////////////////////////////////////////////////////////////
  17. namespace impl {
  18. template <typename StringTypeT, typename PositionT>
  19. class token_data
  20. {
  21. public:
  22. typedef StringTypeT string_type;
  23. typedef PositionT position_type;
  24. token_data()
  25. : id(boost::wave::T_EOI), refcnt(1)
  26. {}
  27. // construct an invalid token
  28. explicit token_data(int)
  29. : id(T_UNKNOWN), refcnt(1)
  30. {}
  31. token_data(boost::wave::token_id id_, string_type const &value_,
  32. position_type const &pos_)
  33. : id(id_), value(value_), pos(pos_), corrected_pos(pos_), refcnt(1)
  34. {}
  35. token_data(token_data const& rhs)
  36. : id(rhs.id), value(rhs.value), pos(rhs.pos),
  37. corrected_pos(rhs.corrected_pos), refcnt(1)
  38. {}
  39. ~token_data()
  40. {}
  41. std::size_t addref() { return ++refcnt; }
  42. std::size_t release() { return --refcnt; }
  43. std::size_t get_refcnt() const { return refcnt; }
  44. // accessors
  45. operator boost::wave::token_id() const { return id; }
  46. string_type const &get_value() const { return value; }
  47. position_type const &get_position() const { return pos; }
  48. position_type const &get_corrected_position() const
  49. { return corrected_pos; }
  50. bool is_eoi() const { id == T_EOI; }
  51. void set_token_id (boost::wave::token_id id_) { id = id_; }
  52. void set_value (string_type const &value_) { value = value_; }
  53. void set_position (position_type const &pos_) { pos = pos_; }
  54. void set_corrected_position (position_type const &pos_)
  55. { corrected_pos = pos_; }
  56. friend bool operator== (token_data const& lhs, token_data const& rhs)
  57. {
  58. // two tokens are considered equal even if they refer to different
  59. // positions
  60. return (lhs.id == rhs.id && lhs.value == rhs.value) ? true : false;
  61. }
  62. private:
  63. boost::wave::token_id id; // the token id
  64. string_type value; // the text, which was parsed into this token
  65. position_type pos; // the original file position
  66. position_type corrected_pos; // the original file position
  67. boost::detail::atomic_count refcnt;
  68. };
  69. ///////////////////////////////////////////////////////////////////////////////
  70. } // namespace impl
  71. ///////////////////////////////////////////////////////////////////////////////
  72. // forward declaration of the token type
  73. template <typename PositionT = boost::wave::util::file_position_type>
  74. class lex_token;
  75. ///////////////////////////////////////////////////////////////////////////////
  76. //
  77. // lex_token
  78. //
  79. ///////////////////////////////////////////////////////////////////////////////
  80. template <typename PositionT>
  81. class lex_token
  82. {
  83. public:
  84. typedef BOOST_WAVE_STRINGTYPE string_type;
  85. typedef PositionT position_type;
  86. lex_token()
  87. : data(new impl::token_data<string_type, position_type>())
  88. {}
  89. // construct an invalid token
  90. explicit lex_token(int)
  91. : data(new data_type(0))
  92. {}
  93. lex_token(lex_token const& rhs)
  94. : data(rhs.data)
  95. {
  96. data->addref();
  97. }
  98. lex_token(boost::wave::token_id id_, string_type const &value_,
  99. PositionT const &pos_)
  100. : data(new impl::token_data<string_type, position_type>(id_, value_, pos_))
  101. {}
  102. ~lex_token()
  103. {
  104. if (0 == data->release())
  105. delete data;
  106. data = 0;
  107. }
  108. lex_token& operator=(lex_token const& rhs)
  109. {
  110. if (&rhs != this) {
  111. if (0 == data->release())
  112. delete data;
  113. data = rhs.data;
  114. data->addref();
  115. }
  116. return *this;
  117. }
  118. // accessors
  119. operator boost::wave::token_id() const
  120. { return boost::wave::token_id(*data); }
  121. string_type const &get_value() const
  122. { return data->get_value(); }
  123. position_type const &get_position() const
  124. { return data->get_position(); }
  125. position_type const &get_corrected_position() const
  126. { return data->get_corrected_position(); }
  127. bool is_valid() const { return 0 != data && token_id(*data) != T_UNKNOWN; }
  128. void set_token_id (boost::wave::token_id id_)
  129. { make_unique(); data->set_token_id(id_); }
  130. void set_value (string_type const &value_)
  131. { make_unique(); data->set_value(value_); }
  132. void set_position (position_type const &pos_)
  133. { make_unique(); data->set_position(pos_); }
  134. void set_corrected_position (position_type const &pos_)
  135. { make_unique(); data->set_corrected_position(pos_); }
  136. friend bool operator== (lex_token const& lhs, lex_token const& rhs)
  137. {
  138. return *(lhs.data) == *(rhs.data);
  139. }
  140. // debug support
  141. #if BOOST_WAVE_DUMP_PARSE_TREE != 0
  142. // access functions for the tree_to_xml functionality
  143. static int get_token_id(lex_token const &t)
  144. { return token_id(t); }
  145. static string_type get_token_value(lex_token const &t)
  146. { return t.get_value(); }
  147. #endif
  148. private:
  149. // make a unique copy of the current object
  150. void make_unique()
  151. {
  152. if (1 == data->get_refcnt())
  153. return;
  154. impl::token_data<string_type, position_type> *newdata =
  155. new impl::token_data<string_type, position_type>(*data);
  156. data->release(); // release this reference, can't get zero
  157. data = newdata;
  158. }
  159. impl::token_data<string_type, position_type> *data;
  160. };
  161. ///////////////////////////////////////////////////////////////////////////////
  162. // This overload is needed by the multi_pass/functor_input_policy to
  163. // validate a token instance. It has to be defined in the same namespace
  164. // as the token class itself to allow ADL to find it.
  165. ///////////////////////////////////////////////////////////////////////////////
  166. template <typename Position>
  167. inline bool
  168. token_is_valid(lex_token<Position> const& t)
  169. {
  170. return t.is_valid();
  171. }
  172. #endif // !defined(REAL_POSITION_TOKEN_HPP_HK_061109_INCLUDED)