Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/wave/cpplexer/cpp_lex_token.hpp @ 35

Last change on this file since 35 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 8.1 KB
Line 
1/*=============================================================================
2    Boost.Wave: A Standard compliant C++ preprocessor library
3
4    A generic C++ lexer token definition
5   
6    http://www.boost.org/
7
8    Copyright (c) 2001-2007 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(CPP_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED)
14#define CPP_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED
15
16#include <boost/wave/wave_config.hpp>
17#if BOOST_WAVE_SERIALIZATION != 0
18#include <boost/serialization/serialization.hpp>
19#endif
20#include <boost/wave/util/file_position.hpp>
21#include <boost/wave/token_ids.hpp> 
22#include <boost/wave/language_support.hpp>
23
24#include <boost/pool/singleton_pool.hpp>
25
26// this must occur after all of the includes and before any code appears
27#ifdef BOOST_HAS_ABI_HEADERS
28#include BOOST_ABI_PREFIX
29#endif
30
31///////////////////////////////////////////////////////////////////////////////
32namespace boost {
33namespace wave {
34namespace cpplexer {
35
36namespace impl {
37
38template <typename StringTypeT, typename PositionT>
39class token_data
40{
41public:
42    typedef StringTypeT string_type;
43    typedef PositionT   position_type;
44   
45    token_data()
46    :   id(T_EOI), refcnt(1)
47    {}
48   
49    token_data(token_id id_, string_type const &value_, position_type const &pos_)
50    :   id(id_), value(value_), pos(pos_), refcnt(1)
51    {}
52
53    token_data(token_data const& rhs)
54    :   id(rhs.id), value(rhs.value), pos(rhs.pos), refcnt(1)
55    {}
56   
57    ~token_data()
58    {}
59   
60    std::size_t addref() { return ++refcnt; }
61    std::size_t release() { return --refcnt; }
62    std::size_t get_refcnt() const { return refcnt; }
63   
64// accessors
65    operator token_id() const { return id; }
66    string_type const &get_value() const { return value; }
67    position_type const &get_position() const { return pos; }
68
69    void set_token_id (token_id id_) { id = id_; }
70    void set_value (string_type const &value_) { value = value_; }
71    void set_position (position_type const &pos_) { pos = pos_; }
72
73    friend bool operator== (token_data const& lhs, token_data const& rhs)
74    {
75        //  two tokens are considered equal even if they refer to different
76        //  positions
77        return (lhs.id == rhs.id && lhs.value == rhs.value) ? true : false;
78    }
79   
80    static void *operator new(std::size_t size);
81    static void operator delete(void *p, std::size_t size);
82   
83#if defined(BOOST_SPIRIT_DEBUG)
84// debug support
85    void print (std::ostream &stream) const
86    {
87        stream << get_token_name(id) << "(";
88        for (std::size_t i = 0; i < value.size(); ++i) {
89            switch (value[i]) {
90            case '\r':  stream << "\\r"; break;
91            case '\n':  stream << "\\n"; break;
92            default:
93                stream << value[i]; 
94                break;
95            }
96        }
97        stream << ")";
98    }
99#endif // defined(BOOST_SPIRIT_DEBUG)
100
101#if BOOST_WAVE_SERIALIZATION != 0
102    friend class boost::serialization::access;
103    template<typename Archive>
104    void serialize(Archive &ar, const unsigned int version)
105    {
106        ar & id;
107        ar & value;
108        ar & pos;
109    }
110#endif
111
112private:
113    token_id id;                // the token id
114    string_type value;          // the text, which was parsed into this token
115    position_type pos;          // the original file position
116    std::size_t refcnt;
117};
118
119///////////////////////////////////////////////////////////////////////////////
120struct token_data_tag {};
121
122template <typename StringTypeT, typename PositionT>
123inline void *
124token_data<StringTypeT, PositionT>::operator new(std::size_t size)
125{
126    BOOST_ASSERT(sizeof(token_data<StringTypeT, PositionT>) == size);
127    typedef boost::singleton_pool<
128            token_data_tag, sizeof(token_data<StringTypeT, PositionT>)
129        > pool_type;
130       
131    void *ret = pool_type::malloc();
132    if (0 == ret)
133        throw std::bad_alloc();
134    return ret;
135}
136
137template <typename StringTypeT, typename PositionT>
138inline void 
139token_data<StringTypeT, PositionT>::operator delete(void *p, std::size_t size)
140{
141    BOOST_ASSERT(sizeof(token_data<StringTypeT, PositionT>) == size);
142    typedef boost::singleton_pool<
143            token_data_tag, sizeof(token_data<StringTypeT, PositionT>)
144        > pool_type;
145
146    if (0 != p) 
147        pool_type::free(p);
148}
149
150} // namespace impl
151
152///////////////////////////////////////////////////////////////////////////////
153//  forward declaration of the token type
154template <typename PositionT = boost::wave::util::file_position_type>
155class lex_token;
156
157///////////////////////////////////////////////////////////////////////////////
158// 
159//  lex_token
160//
161///////////////////////////////////////////////////////////////////////////////
162
163template <typename PositionT>
164class lex_token 
165{
166public:
167    typedef BOOST_WAVE_STRINGTYPE   string_type;
168    typedef PositionT               position_type;
169   
170    lex_token()
171    :   data(new impl::token_data<string_type, position_type>())
172    {}
173   
174    lex_token(lex_token const& rhs)
175    :   data(rhs.data)
176    {
177        data->addref();
178    }
179
180    lex_token(token_id id_, string_type const &value_, PositionT const &pos_)
181    :   data(new impl::token_data<string_type, position_type>(id_, value_, pos_))
182    {}
183
184    ~lex_token()
185    {
186        if (0 == data->release()) 
187            delete data;
188        data = 0;
189    }
190   
191    lex_token& operator=(lex_token const& rhs)
192    {
193        if (&rhs != this) {
194            if (0 == data->release()) 
195                delete data;
196           
197            data = rhs.data;
198            data->addref();
199        }
200        return *this;
201    }
202   
203// accessors
204    operator token_id() const { return token_id(*data); }
205    string_type const &get_value() const { return data->get_value(); }
206    position_type const &get_position() const { return data->get_position(); }
207
208    void set_token_id (token_id id_) { make_unique(); data->set_token_id(id_); }
209    void set_value (string_type const &value_) { make_unique(); data->set_value(value_); }
210    void set_position (position_type const &pos_) { make_unique(); data->set_position(pos_); }
211
212    friend bool operator== (lex_token const& lhs, lex_token const& rhs)
213    {
214        return *(lhs.data) == *(rhs.data);
215    }
216   
217// debug support   
218#if BOOST_WAVE_DUMP_PARSE_TREE != 0
219// access functions for the tree_to_xml functionality
220    static int get_token_id(lex_token const &t) 
221        { return token_id(t); }
222    static string_type get_token_value(lex_token const &t) 
223        { return t.get_value(); }
224#endif
225   
226#if defined(BOOST_SPIRIT_DEBUG)
227// debug support
228    void print (std::ostream &stream) const
229    {
230        data->print(stream);
231    }
232#endif // defined(BOOST_SPIRIT_DEBUG)
233
234private:
235#if BOOST_WAVE_SERIALIZATION != 0
236    friend class boost::serialization::access;
237    template<typename Archive>
238    void serialize(Archive &ar, const unsigned int version)
239    {
240        data->serialize(ar, version);
241    }
242#endif
243
244    // make a unique copy of the current object
245    void make_unique()
246    {
247        if (1 == data->get_refcnt())
248            return;
249       
250        impl::token_data<string_type, position_type> *newdata = 
251            new impl::token_data<string_type, position_type>(*data);
252
253        data->release();          // release this reference, can't get zero
254        data = newdata;
255    }
256   
257    impl::token_data<string_type, position_type> *data;
258};
259
260///////////////////////////////////////////////////////////////////////////////
261#if defined(BOOST_SPIRIT_DEBUG)
262template <typename PositionT>
263inline std::ostream &
264operator<< (std::ostream &stream, lex_token<PositionT> const &object)
265{
266    object.print(stream);
267    return stream;
268}
269#endif // defined(BOOST_SPIRIT_DEBUG)
270
271///////////////////////////////////////////////////////////////////////////////
272}   // namespace cpplexer
273}   // namespace wave
274}   // namespace boost
275
276// the suffix header occurs after all of the code
277#ifdef BOOST_HAS_ABI_HEADERS
278#include BOOST_ABI_SUFFIX
279#endif
280
281#endif // !defined(CPP_TOKEN_HPP_53A13BD2_FBAA_444B_9B8B_FCB225C2BBA8_INCLUDED)
Note: See TracBrowser for help on using the repository browser.