• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Boost.Wave: A Standard compliant C++ preprocessor library
3 
4     Definition of the position_iterator and file_position templates
5 
6     http://www.boost.org/
7 
8     Copyright (c) 2001-2012 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_FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED)
14 #define BOOST_FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED
15 
16 #include <string>
17 #include <ostream>
18 
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
26 
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
31 
32 ///////////////////////////////////////////////////////////////////////////////
33 namespace boost {
34 namespace wave {
35 namespace util {
36 
37 ///////////////////////////////////////////////////////////////////////////////
38 //
39 //  file_position
40 //
41 //  A structure to hold positional information. This includes the filename,
42 //  line number and column number of a current token position.
43 //
44 ///////////////////////////////////////////////////////////////////////////////
45 
46 template <typename StringT>
47 struct file_position {
48 
49 public:
50     typedef StringT string_type;
51 
file_positionboost::wave::util::file_position52     file_position()
53     :   file(), line(1), column(1)
54     {}
file_positionboost::wave::util::file_position55     explicit file_position(string_type const& file_, std::size_t line_ = 1,
56             std::size_t column_ = 1)
57     :   file(file_), line(line_), column(column_)
58     {}
59 
60 // accessors
get_fileboost::wave::util::file_position61     string_type const &get_file() const { return file; }
get_lineboost::wave::util::file_position62     std::size_t get_line() const { return line; }
get_columnboost::wave::util::file_position63     std::size_t get_column() const { return column; }
64 
set_fileboost::wave::util::file_position65     void set_file(string_type const &file_)
66     {
67         file = file_;
68     }
set_lineboost::wave::util::file_position69     void set_line(std::size_t line_) { line = line_; }
set_columnboost::wave::util::file_position70     void set_column(std::size_t column_) { column = column_; }
71 
72 private:
73 #if BOOST_WAVE_SERIALIZATION != 0
74     friend class boost::serialization::access;
75     template<typename Archive>
serializeboost::wave::util::file_position76     void serialize(Archive &ar, const unsigned int version)
77     {
78         using namespace boost::serialization;
79         ar & make_nvp("filename", file);
80         ar & make_nvp("line", line);
81         ar & make_nvp("column", column);
82     }
83 #endif
84 
85     string_type file;
86     std::size_t line;
87     std::size_t column;
88 };
89 
90 template <typename StringT>
operator ==(file_position<StringT> const & lhs,file_position<StringT> const & rhs)91 bool operator== (file_position<StringT> const &lhs,
92     file_position<StringT> const &rhs)
93 {
94     return lhs.get_column() == rhs.get_column() &&
95         lhs.get_line() == rhs.get_line() && lhs.get_file() == rhs.get_file();
96 }
97 
98 template <typename StringT>
99 inline std::ostream &
operator <<(std::ostream & o,file_position<StringT> const & pos)100 operator<< (std::ostream &o, file_position<StringT> const &pos)
101 {
102     o << pos.get_file() << ":" << pos.get_line() << ":"  << pos.get_column();
103     return o;
104 }
105 
106 typedef file_position<BOOST_WAVE_STRINGTYPE> file_position_type;
107 
108 ///////////////////////////////////////////////////////////////////////////////
109 //
110 //  position_iterator
111 //
112 //  The position_iterator used by Wave is now based on the corresponding Spirit
113 //  type. This type is used with our own file_position though. The needed
114 //  specialization of the boost::spirit::classic::position_policy class is
115 //  provided below.
116 //
117 ///////////////////////////////////////////////////////////////////////////////
118 
119 template <typename IteratorT, typename PositionT>
120 struct position_iterator
121 :   boost::spirit::classic::position_iterator<IteratorT, PositionT>
122 {
123     typedef boost::spirit::classic::position_iterator<IteratorT, PositionT> base_type;
124 
position_iteratorboost::wave::util::position_iterator125     position_iterator()
126     {
127     }
128 
position_iteratorboost::wave::util::position_iterator129     position_iterator(IteratorT const &begin, IteratorT const &end,
130             PositionT const &pos)
131     :   base_type(begin, end, pos)
132     {
133     }
134 };
135 
136 ///////////////////////////////////////////////////////////////////////////////
137 }   // namespace util
138 }   // namespace wave
139 
140 ///////////////////////////////////////////////////////////////////////////////
141 
142 namespace spirit { namespace classic {
143 
144 ///////////////////////////////////////////////////////////////////////////////
145 //
146 //  The boost::spirit::classic::position_policy has to be specialized for our
147 //  file_position class
148 //
149 ///////////////////////////////////////////////////////////////////////////////
150 
151     template <>
152     class position_policy<boost::wave::util::file_position_type> {
153 
154     public:
position_policy()155         position_policy()
156             : m_CharsPerTab(4)
157         {}
158 
next_line(boost::wave::util::file_position_type & pos)159         void next_line(boost::wave::util::file_position_type &pos)
160         {
161             pos.set_line(pos.get_line() + 1);
162             pos.set_column(1);
163         }
164 
set_tab_chars(unsigned int chars)165         void set_tab_chars(unsigned int chars)
166         {
167             m_CharsPerTab = chars;
168         }
169 
next_char(boost::wave::util::file_position_type & pos)170         void next_char(boost::wave::util::file_position_type &pos)
171         {
172             pos.set_column(pos.get_column() + 1);
173         }
174 
tabulation(boost::wave::util::file_position_type & pos)175         void tabulation(boost::wave::util::file_position_type &pos)
176         {
177             pos.set_column(pos.get_column() + m_CharsPerTab -
178                 (pos.get_column() - 1) % m_CharsPerTab);
179         }
180 
181     private:
182         unsigned int m_CharsPerTab;
183     };
184 
185 ///////////////////////////////////////////////////////////////////////////////
186 }}   // namespace spirit::classic
187 
188 }   // namespace boost
189 
190 // the suffix header occurs after all of the code
191 #ifdef BOOST_HAS_ABI_HEADERS
192 #include BOOST_ABI_SUFFIX
193 #endif
194 
195 #endif // !defined(BOOST_FILE_POSITION_H_52BDEDF7_DAD3_4F24_802F_E66BB8098F68_INCLUDED)
196