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