1 /*=============================================================================
2 Boost.Wave: A Standard compliant C++ preprocessor library
4 Definition of the position_iterator and file_position templates
8 Copyright (c) 2001-2009 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 =============================================================================*/
13 #if !defined(FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED)
14 #define FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED
19 #include <boost/assert.hpp>
20 #include <boost/spirit/include/classic_version.hpp>
21 #include <boost/spirit/include/classic_position_iterator.hpp>
22 #include <boost/wave/wave_config.hpp>
23 #if BOOST_WAVE_SERIALIZATION != 0
24 #include <boost/serialization/serialization.hpp>
27 // this must occur after all of the includes and before any code appears
28 #ifdef BOOST_HAS_ABI_HEADERS
29 #include BOOST_ABI_PREFIX
32 ///////////////////////////////////////////////////////////////////////////////
37 ///////////////////////////////////////////////////////////////////////////////
40 // Used only when BOOST_ASSERT expands to something
41 // make sure the string literal does not contain any escapes ('\\' just
42 // before '\\', '\"' or '?')
43 template <typename StringT
>
45 is_escaped_lit(StringT
const &value
)
47 typename
StringT::size_type pos
= value
.find_first_of ("\\", 0);
48 if (StringT::npos
!= pos
) {
50 if ('\\' == value
[pos
+1] ||
51 '\"' == value
[pos
+1] ||
57 pos
= value
.find_first_of ("\\", pos
+1);
59 } while (pos
!= StringT::npos
);
64 ///////////////////////////////////////////////////////////////////////////////
67 ///////////////////////////////////////////////////////////////////////////////
71 // A structure to hold positional information. This includes the filename,
72 // line number and column number of a current token position.
74 ///////////////////////////////////////////////////////////////////////////////
76 template <typename StringT
>
77 struct file_position
{
80 typedef StringT string_type
;
83 : file(), line(1), column(1)
85 explicit file_position(string_type
const& file_
, int line_
= 1,
87 : file(file_
), line(line_
), column(column_
)
89 BOOST_ASSERT(!debug::is_escaped_lit(file
));
93 string_type
const &get_file() const { return file
; }
94 unsigned int get_line() const { return line
; }
95 unsigned int get_column() const { return column
; }
97 void set_file(string_type
const &file_
)
100 BOOST_ASSERT(!debug::is_escaped_lit(file
));
102 void set_line(unsigned int line_
) { line
= line_
; }
103 void set_column(unsigned int column_
) { column
= column_
; }
106 #if BOOST_WAVE_SERIALIZATION != 0
107 friend class boost::serialization::access
;
108 template<typename Archive
>
109 void serialize(Archive
&ar
, const unsigned int version
)
111 using namespace boost::serialization
;
112 ar
& make_nvp("filename", file
);
113 ar
& make_nvp("line", line
);
114 ar
& make_nvp("column", column
);
123 template <typename StringT
>
124 bool operator== (file_position
<StringT
> const &lhs
,
125 file_position
<StringT
> const &rhs
)
127 return lhs
.get_column() == rhs
.get_column() &&
128 lhs
.get_line() == rhs
.get_line() && lhs
.get_file() == rhs
.get_file();
131 template <typename StringT
>
132 inline std::ostream
&
133 operator<< (std::ostream
&o
, file_position
<StringT
> const &pos
)
135 o
<< pos
.get_file() << ":" << pos
.get_line() << ":" << pos
.get_column();
139 typedef file_position
<BOOST_WAVE_STRINGTYPE
> file_position_type
;
141 ///////////////////////////////////////////////////////////////////////////////
145 // The position_iterator used by Wave is now based on the corresponding Spirit
146 // type. This type is used with our own file_position though. The needed
147 // specialization of the boost::spirit::classic::position_policy class is
150 ///////////////////////////////////////////////////////////////////////////////
152 template <typename IteratorT
, typename PositionT
>
153 struct position_iterator
154 : boost::spirit::classic::position_iterator
<IteratorT
, PositionT
>
156 typedef boost::spirit::classic::position_iterator
<IteratorT
, PositionT
> base_type
;
162 position_iterator(IteratorT
const &begin
, IteratorT
const &end
,
163 PositionT
const &pos
)
164 : base_type(begin
, end
, pos
)
169 ///////////////////////////////////////////////////////////////////////////////
173 ///////////////////////////////////////////////////////////////////////////////
175 namespace spirit
{ namespace classic
{
177 ///////////////////////////////////////////////////////////////////////////////
179 // The boost::spirit::classic::position_policy has to be specialized for our
180 // file_position class
182 ///////////////////////////////////////////////////////////////////////////////
185 class position_policy
<boost::wave::util::file_position_type
> {
192 void next_line(boost::wave::util::file_position_type
&pos
)
194 pos
.set_line(pos
.get_line() + 1);
198 void set_tab_chars(unsigned int chars
)
200 m_CharsPerTab
= chars
;
203 void next_char(boost::wave::util::file_position_type
&pos
)
205 pos
.set_column(pos
.get_column() + 1);
208 void tabulation(boost::wave::util::file_position_type
&pos
)
210 pos
.set_column(pos
.get_column() + m_CharsPerTab
-
211 (pos
.get_column() - 1) % m_CharsPerTab
);
215 unsigned int m_CharsPerTab
;
218 ///////////////////////////////////////////////////////////////////////////////
219 }} // namespace spirit::classic
223 // the suffix header occurs after all of the code
224 #ifdef BOOST_HAS_ABI_HEADERS
225 #include BOOST_ABI_SUFFIX
228 #endif // !defined(FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED)