• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Boost.Wave: A Standard compliant C++ preprocessor library
3 
4     A C++ lexer token definition for the real_positions example
5 
6     http://www.boost.org/
7 
8     Copyright (c) 2001-2010 Hartmut Kaiser. Distributed under the Boost
9     Software License, Version 1.0. (See accompanying file
10     LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11 =============================================================================*/
12 
13 #if !defined(BOOST_REAL_POSITION_TOKEN_HPP_HK_061109_INCLUDED)
14 #define BOOST_REAL_POSITION_TOKEN_HPP_HK_061109_INCLUDED
15 
16 #include <boost/wave/wave_config.hpp>
17 #include <boost/wave/util/file_position.hpp>
18 #include <boost/wave/token_ids.hpp>
19 #include <boost/wave/language_support.hpp>
20 #include <boost/detail/atomic_count.hpp>
21 
22 ///////////////////////////////////////////////////////////////////////////////
23 namespace impl {
24 
25 template <typename StringTypeT, typename PositionT>
26 class token_data
27 {
28 public:
29     typedef StringTypeT string_type;
30     typedef PositionT   position_type;
31 
token_data()32     token_data()
33     :   id(boost::wave::T_EOI), refcnt(1)
34     {}
35 
36     //  construct an invalid token
token_data(int)37     explicit token_data(int)
38     :   id(boost::wave::T_UNKNOWN), refcnt(1)
39     {}
40 
token_data(boost::wave::token_id id_,string_type const & value_,position_type const & pos_)41     token_data(boost::wave::token_id id_, string_type const &value_,
42             position_type const &pos_)
43     :   id(id_), value(value_), pos(pos_), corrected_pos(pos_), refcnt(1)
44     {}
45 
token_data(token_data const & rhs)46     token_data(token_data const& rhs)
47     :   id(rhs.id), value(rhs.value), pos(rhs.pos),
48         corrected_pos(rhs.corrected_pos), refcnt(1)
49     {}
50 
~token_data()51     ~token_data()
52     {}
53 
addref()54     std::size_t addref() { return ++refcnt; }
release()55     std::size_t release() { return --refcnt; }
get_refcnt() const56     std::size_t get_refcnt() const { return refcnt; }
57 
58 // accessors
operator boost::wave::token_id() const59     operator boost::wave::token_id() const { return id; }
get_value() const60     string_type const &get_value() const { return value; }
get_position() const61     position_type const &get_position() const { return pos; }
get_corrected_position() const62     position_type const &get_corrected_position() const
63         { return corrected_pos; }
is_eoi() const64     bool is_eoi() const
65     {
66         return id == boost::wave::T_EOI;
67     }
68 
set_token_id(boost::wave::token_id id_)69     void set_token_id (boost::wave::token_id id_) { id = id_; }
set_value(string_type const & value_)70     void set_value (string_type const &value_) { value = value_; }
set_position(position_type const & pos_)71     void set_position (position_type const &pos_) { pos = pos_; }
set_corrected_position(position_type const & pos_)72     void set_corrected_position (position_type const &pos_)
73         { corrected_pos = pos_; }
74 
operator ==(token_data const & lhs,token_data const & rhs)75     friend bool operator== (token_data const& lhs, token_data const& rhs)
76     {
77         //  two tokens are considered equal even if they refer to different
78         //  positions
79         return (lhs.id == rhs.id && lhs.value == rhs.value) ? true : false;
80     }
81 
82 private:
83     boost::wave::token_id id;     // the token id
84     string_type value;            // the text, which was parsed into this token
85     position_type pos;            // the original file position
86     position_type corrected_pos;  // the original file position
87     boost::detail::atomic_count refcnt;
88 };
89 
90 ///////////////////////////////////////////////////////////////////////////////
91 } // namespace impl
92 
93 ///////////////////////////////////////////////////////////////////////////////
94 //  forward declaration of the token type
95 template <typename PositionT = boost::wave::util::file_position_type>
96 class lex_token;
97 
98 ///////////////////////////////////////////////////////////////////////////////
99 //
100 //  lex_token
101 //
102 ///////////////////////////////////////////////////////////////////////////////
103 
104 template <typename PositionT>
105 class lex_token
106 {
107 public:
108     typedef BOOST_WAVE_STRINGTYPE                        string_type;
109     typedef PositionT                                    position_type;
110     typedef impl::token_data<string_type, position_type> data_type;
111 
lex_token()112     lex_token()
113     :   data(new impl::token_data<string_type, position_type>())
114     {}
115 
116     //  construct an invalid token
lex_token(int)117     explicit lex_token(int)
118     :   data(new data_type(0))
119     {}
120 
lex_token(lex_token const & rhs)121     lex_token(lex_token const& rhs)
122     :   data(rhs.data)
123     {
124         data->addref();
125     }
126 
lex_token(boost::wave::token_id id_,string_type const & value_,PositionT const & pos_)127     lex_token(boost::wave::token_id id_, string_type const &value_,
128             PositionT const &pos_)
129     :   data(new impl::token_data<string_type, position_type>(id_, value_, pos_))
130     {}
131 
~lex_token()132     ~lex_token()
133     {
134         if (0 == data->release())
135             delete data;
136         data = 0;
137     }
138 
operator =(lex_token const & rhs)139     lex_token& operator=(lex_token const& rhs)
140     {
141         if (&rhs != this) {
142             if (0 == data->release())
143                 delete data;
144 
145             data = rhs.data;
146             data->addref();
147         }
148         return *this;
149     }
150 
151 // accessors
operator boost::wave::token_id() const152     operator boost::wave::token_id() const
153         { return boost::wave::token_id(*data); }
get_value() const154     string_type const &get_value() const
155         { return data->get_value(); }
get_position() const156     position_type const &get_position() const
157         { return data->get_position(); }
get_corrected_position() const158     position_type const &get_corrected_position() const
159         { return data->get_corrected_position(); }
is_valid() const160     bool is_valid() const
161     {
162         using namespace boost::wave;
163         return 0 != data && token_id(*data) != boost::wave::T_UNKNOWN;
164     }
165 
set_token_id(boost::wave::token_id id_)166     void set_token_id (boost::wave::token_id id_)
167         { make_unique(); data->set_token_id(id_); }
set_value(string_type const & value_)168     void set_value (string_type const &value_)
169         { make_unique(); data->set_value(value_); }
set_position(position_type const & pos_)170     void set_position (position_type const &pos_)
171         { make_unique(); data->set_position(pos_); }
set_corrected_position(position_type const & pos_)172     void set_corrected_position (position_type const &pos_)
173         { make_unique(); data->set_corrected_position(pos_); }
174 
operator ==(lex_token const & lhs,lex_token const & rhs)175     friend bool operator== (lex_token const& lhs, lex_token const& rhs)
176     {
177         return *(lhs.data) == *(rhs.data);
178     }
179 
180 // debug support
181 #if BOOST_WAVE_DUMP_PARSE_TREE != 0
182 // access functions for the tree_to_xml functionality
get_token_id(lex_token const & t)183     static int get_token_id(lex_token const &t)
184         { return token_id(t); }
get_token_value(lex_token const & t)185     static string_type get_token_value(lex_token const &t)
186         { return t.get_value(); }
187 #endif
188 
189 private:
190     // make a unique copy of the current object
make_unique()191     void make_unique()
192     {
193         if (1 == data->get_refcnt())
194             return;
195 
196         impl::token_data<string_type, position_type> *newdata =
197             new impl::token_data<string_type, position_type>(*data);
198 
199         data->release();          // release this reference, can't get zero
200         data = newdata;
201     }
202 
203     impl::token_data<string_type, position_type> *data;
204 };
205 
206 ///////////////////////////////////////////////////////////////////////////////
207 //  This overload is needed by the multi_pass/functor_input_policy to
208 //  validate a token instance. It has to be defined in the same namespace
209 //  as the token class itself to allow ADL to find it.
210 ///////////////////////////////////////////////////////////////////////////////
211 template <typename Position>
212 inline bool
token_is_valid(lex_token<Position> const & t)213 token_is_valid(lex_token<Position> const& t)
214 {
215     return t.is_valid();
216 }
217 
218 #endif // !defined(BOOST_REAL_POSITION_TOKEN_HPP_HK_061109_INCLUDED)
219