Release 1.39.0
[boost.git] / Boost_1_39_0 / boost / wave / util / file_position.hpp
bloba8f291c5e200909136fb35af1bee3185fc957e2a
1 /*=============================================================================
2 Boost.Wave: A Standard compliant C++ preprocessor library
4 Definition of the position_iterator and file_position templates
6 http://www.boost.org/
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
16 #include <string>
17 #include <ostream>
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>
25 #endif
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
30 #endif
32 ///////////////////////////////////////////////////////////////////////////////
33 namespace boost {
34 namespace wave {
35 namespace util {
37 ///////////////////////////////////////////////////////////////////////////////
38 namespace debug {
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>
44 inline bool
45 is_escaped_lit(StringT const &value)
47 typename StringT::size_type pos = value.find_first_of ("\\", 0);
48 if (StringT::npos != pos) {
49 do {
50 if ('\\' == value[pos+1] ||
51 '\"' == value[pos+1] ||
52 '?' == value[pos+1])
54 return true;
56 else {
57 pos = value.find_first_of ("\\", pos+1);
59 } while (pos != StringT::npos);
61 return false;
64 ///////////////////////////////////////////////////////////////////////////////
65 } // namespace debug
67 ///////////////////////////////////////////////////////////////////////////////
69 // file_position
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 {
79 public:
80 typedef StringT string_type;
82 file_position()
83 : file(), line(1), column(1)
85 explicit file_position(string_type const& file_, int line_ = 1,
86 int column_ = 1)
87 : file(file_), line(line_), column(column_)
89 BOOST_ASSERT(!debug::is_escaped_lit(file));
92 // accessors
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_)
99 file = 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_; }
105 private:
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);
116 #endif
118 string_type file;
119 unsigned int line;
120 unsigned int 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();
136 return o;
139 typedef file_position<BOOST_WAVE_STRINGTYPE> file_position_type;
141 ///////////////////////////////////////////////////////////////////////////////
143 // position_iterator
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
148 // provided below.
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;
158 position_iterator()
162 position_iterator(IteratorT const &begin, IteratorT const &end,
163 PositionT const &pos)
164 : base_type(begin, end, pos)
169 ///////////////////////////////////////////////////////////////////////////////
170 } // namespace util
171 } // namespace wave
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 ///////////////////////////////////////////////////////////////////////////////
184 template <>
185 class position_policy<boost::wave::util::file_position_type> {
187 public:
188 position_policy()
189 : m_CharsPerTab(4)
192 void next_line(boost::wave::util::file_position_type &pos)
194 pos.set_line(pos.get_line() + 1);
195 pos.set_column(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);
214 private:
215 unsigned int m_CharsPerTab;
218 ///////////////////////////////////////////////////////////////////////////////
219 }} // namespace spirit::classic
221 } // namespace boost
223 // the suffix header occurs after all of the code
224 #ifdef BOOST_HAS_ABI_HEADERS
225 #include BOOST_ABI_SUFFIX
226 #endif
228 #endif // !defined(FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED)