PageRenderTime 998ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/avr-cpp-libs/foreign/cpp/boost/spirit/home/classic/iterator/position_iterator.hpp

https://bitbucket.org/nazemnykh_anton/avr-cpp-libs
C++ Header | 436 lines | 272 code | 63 blank | 101 comment | 38 complexity | 9840556a6ccffa9081b7583ff5b7be42 MD5 | raw file
  1. /*=============================================================================
  2. Copyright (c) 2002 Juan Carlos Arevalo-Baeza
  3. Copyright (c) 2002-2006 Hartmut Kaiser
  4. Copyright (c) 2003 Giovanni Bajo
  5. http://spirit.sourceforge.net/
  6. Distributed under the Boost Software License, Version 1.0. (See accompanying
  7. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. =============================================================================*/
  9. #ifndef BOOST_SPIRIT_POSITION_ITERATOR_HPP
  10. #define BOOST_SPIRIT_POSITION_ITERATOR_HPP
  11. #include <string>
  12. #include <boost/config.hpp>
  13. #include <boost/concept_check.hpp>
  14. #include <boost/spirit/home/classic/namespace.hpp>
  15. #include <boost/spirit/home/classic/iterator/position_iterator_fwd.hpp>
  16. namespace boost { namespace spirit {
  17. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  18. ///////////////////////////////////////////////////////////////////////////////
  19. //
  20. // file_position_without_column
  21. //
  22. // A structure to hold positional information. This includes the file,
  23. // and the line number
  24. //
  25. ///////////////////////////////////////////////////////////////////////////////
  26. template <typename String>
  27. struct file_position_without_column_base {
  28. String file;
  29. int line;
  30. file_position_without_column_base(String const& file_ = String(),
  31. int line_ = 1):
  32. file (file_),
  33. line (line_)
  34. {}
  35. bool operator==(const file_position_without_column_base& fp) const
  36. { return line == fp.line && file == fp.file; }
  37. };
  38. ///////////////////////////////////////////////////////////////////////////////
  39. //
  40. // file_position
  41. //
  42. // This structure holds complete file position, including file name,
  43. // line and column number
  44. //
  45. ///////////////////////////////////////////////////////////////////////////////
  46. template <typename String>
  47. struct file_position_base : public file_position_without_column_base<String> {
  48. int column;
  49. file_position_base(String const& file_ = String(),
  50. int line_ = 1, int column_ = 1):
  51. file_position_without_column_base<String> (file_, line_),
  52. column (column_)
  53. {}
  54. bool operator==(const file_position_base& fp) const
  55. { return column == fp.column && this->line == fp.line && this->file == fp.file; }
  56. };
  57. ///////////////////////////////////////////////////////////////////////////////
  58. //
  59. // position_policy<>
  60. //
  61. // This template is the policy to handle the file position. It is specialized
  62. // on the position type. Providing a custom file_position also requires
  63. // providing a specialization of this class.
  64. //
  65. // Policy interface:
  66. //
  67. // Default constructor of the custom position class must be accessible.
  68. // set_tab_chars(unsigned int chars) - Set the tabstop width
  69. // next_char(PositionT& pos) - Notify that a new character has been
  70. // processed
  71. // tabulation(PositionT& pos) - Notify that a tab character has been
  72. // processed
  73. // next_line(PositionT& pos) - Notify that a new line delimiter has
  74. // been reached.
  75. //
  76. ///////////////////////////////////////////////////////////////////////////////
  77. template <typename PositionT> class position_policy;
  78. ///////////////////////////////////////////////////////////////////////////////
  79. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  80. }} /* namespace BOOST_SPIRIT_CLASSIC_NS */
  81. // This must be included here for full compatibility with old MSVC
  82. #include "boost/spirit/home/classic/iterator/impl/position_iterator.ipp"
  83. ///////////////////////////////////////////////////////////////////////////////
  84. namespace boost { namespace spirit {
  85. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  86. ///////////////////////////////////////////////////////////////////////////////
  87. //
  88. // position_iterator
  89. //
  90. // It wraps an iterator, and keeps track of the current position in the input,
  91. // as it gets incremented.
  92. //
  93. // The wrapped iterator must be at least a Forward iterator. The position
  94. // iterator itself will always be a non-mutable Forward iterator.
  95. //
  96. // In order to have begin/end iterators constructed, the end iterator must be
  97. // empty constructed. Similar to what happens with stream iterators. The begin
  98. // iterator must be constructed from both, the begin and end iterators of the
  99. // wrapped iterator type. This is necessary to implement the lookahead of
  100. // characters necessary to parse CRLF sequences.
  101. //
  102. // In order to extract the current positional data from the iterator, you may
  103. // use the get_position member function.
  104. //
  105. // You can also use the set_position member function to reset the current
  106. // position to something new.
  107. //
  108. // The structure that holds the current position can be customized through a
  109. // template parameter, and the class position_policy must be specialized
  110. // on the new type to define how to handle it. Currently, it's possible
  111. // to choose between the file_position and file_position_without_column
  112. // (which saves some overhead if managing current column is not required).
  113. //
  114. ///////////////////////////////////////////////////////////////////////////////
  115. #if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
  116. BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
  117. #error "Please use at least Boost V1.31.0 while compiling the position_iterator class!"
  118. #else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
  119. ///////////////////////////////////////////////////////////////////////////////
  120. //
  121. // Uses the newer iterator_adaptor version (should be released with
  122. // Boost V1.31.0)
  123. //
  124. ///////////////////////////////////////////////////////////////////////////////
  125. template <
  126. typename ForwardIteratorT,
  127. typename PositionT,
  128. typename SelfT
  129. >
  130. class position_iterator
  131. : public iterator_::impl::position_iterator_base_generator<
  132. SelfT,
  133. ForwardIteratorT,
  134. PositionT
  135. >::type,
  136. public position_policy<PositionT>
  137. {
  138. private:
  139. typedef position_policy<PositionT> position_policy_t;
  140. typedef typename iterator_::impl::position_iterator_base_generator<
  141. SelfT,
  142. ForwardIteratorT,
  143. PositionT
  144. >::type base_t;
  145. typedef typename iterator_::impl::position_iterator_base_generator<
  146. SelfT,
  147. ForwardIteratorT,
  148. PositionT
  149. >::main_iter_t main_iter_t;
  150. public:
  151. typedef PositionT position_t;
  152. position_iterator()
  153. : _isend(true)
  154. {}
  155. position_iterator(
  156. const ForwardIteratorT& begin,
  157. const ForwardIteratorT& end)
  158. : base_t(begin), _end(end), _pos(PositionT()), _isend(begin == end)
  159. {}
  160. template <typename FileNameT>
  161. position_iterator(
  162. const ForwardIteratorT& begin,
  163. const ForwardIteratorT& end,
  164. FileNameT fileName)
  165. : base_t(begin), _end(end), _pos(PositionT(fileName)),
  166. _isend(begin == end)
  167. {}
  168. template <typename FileNameT, typename LineT>
  169. position_iterator(
  170. const ForwardIteratorT& begin,
  171. const ForwardIteratorT& end,
  172. FileNameT fileName, LineT line)
  173. : base_t(begin), _end(end), _pos(PositionT(fileName, line)),
  174. _isend(begin == end)
  175. {}
  176. template <typename FileNameT, typename LineT, typename ColumnT>
  177. position_iterator(
  178. const ForwardIteratorT& begin,
  179. const ForwardIteratorT& end,
  180. FileNameT fileName, LineT line, ColumnT column)
  181. : base_t(begin), _end(end), _pos(PositionT(fileName, line, column)),
  182. _isend(begin == end)
  183. {}
  184. position_iterator(
  185. const ForwardIteratorT& begin,
  186. const ForwardIteratorT& end,
  187. const PositionT& pos)
  188. : base_t(begin), _end(end), _pos(pos), _isend(begin == end)
  189. {}
  190. position_iterator(const position_iterator& iter)
  191. : base_t(iter.base()), position_policy_t(iter),
  192. _end(iter._end), _pos(iter._pos), _isend(iter._isend)
  193. {}
  194. position_iterator& operator=(const position_iterator& iter)
  195. {
  196. base_t::operator=(iter);
  197. position_policy_t::operator=(iter);
  198. _end = iter._end;
  199. _pos = iter._pos;
  200. _isend = iter._isend;
  201. return *this;
  202. }
  203. void set_position(PositionT const& newpos) { _pos = newpos; }
  204. PositionT& get_position() { return _pos; }
  205. PositionT const& get_position() const { return _pos; }
  206. void set_tabchars(unsigned int chars)
  207. {
  208. // This function (which comes from the position_policy) has a
  209. // different name on purpose, to avoid messing with using
  210. // declarations or qualified calls to access the base template
  211. // function, which might break some compilers.
  212. this->position_policy_t::set_tab_chars(chars);
  213. }
  214. private:
  215. friend class boost::iterator_core_access;
  216. void increment()
  217. {
  218. typename base_t::reference val = *(this->base());
  219. if (val == '\n') {
  220. ++this->base_reference();
  221. this->next_line(_pos);
  222. static_cast<main_iter_t &>(*this).newline();
  223. }
  224. else if ( val == '\r') {
  225. ++this->base_reference();
  226. if (this->base_reference() == _end || *(this->base()) != '\n')
  227. {
  228. this->next_line(_pos);
  229. static_cast<main_iter_t &>(*this).newline();
  230. }
  231. }
  232. else if (val == '\t') {
  233. this->tabulation(_pos);
  234. ++this->base_reference();
  235. }
  236. else {
  237. this->next_char(_pos);
  238. ++this->base_reference();
  239. }
  240. // The iterator is at the end only if it's the same
  241. // of the
  242. _isend = (this->base_reference() == _end);
  243. }
  244. template <
  245. typename OtherDerivedT, typename OtherIteratorT,
  246. typename V, typename C, typename R, typename D
  247. >
  248. bool equal(iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D>
  249. const &x) const
  250. {
  251. OtherDerivedT const &rhs = static_cast<OtherDerivedT const &>(x);
  252. bool x_is_end = rhs._isend;
  253. return (_isend == x_is_end) && (_isend || this->base() == rhs.base());
  254. }
  255. protected:
  256. void newline(void)
  257. {}
  258. ForwardIteratorT _end;
  259. PositionT _pos;
  260. bool _isend;
  261. };
  262. #endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
  263. ///////////////////////////////////////////////////////////////////////////////
  264. //
  265. // position_iterator2
  266. //
  267. // Equivalent to position_iterator, but it is able to extract the current
  268. // line into a string. This is very handy for error reports.
  269. //
  270. // Notice that the footprint of this class is higher than position_iterator,
  271. // (how much depends on how bulky the underlying iterator is), so it should
  272. // be used only if necessary.
  273. //
  274. ///////////////////////////////////////////////////////////////////////////////
  275. template
  276. <
  277. typename ForwardIteratorT,
  278. typename PositionT
  279. >
  280. class position_iterator2
  281. : public position_iterator
  282. <
  283. ForwardIteratorT,
  284. PositionT,
  285. position_iterator2<ForwardIteratorT, PositionT>
  286. >
  287. {
  288. typedef position_iterator
  289. <
  290. ForwardIteratorT,
  291. PositionT,
  292. position_iterator2<ForwardIteratorT, PositionT> // JDG 4-15-03
  293. > base_t;
  294. public:
  295. typedef typename base_t::value_type value_type;
  296. typedef PositionT position_t;
  297. position_iterator2()
  298. {}
  299. position_iterator2(
  300. const ForwardIteratorT& begin,
  301. const ForwardIteratorT& end):
  302. base_t(begin, end),
  303. _startline(begin)
  304. {}
  305. template <typename FileNameT>
  306. position_iterator2(
  307. const ForwardIteratorT& begin,
  308. const ForwardIteratorT& end,
  309. FileNameT file):
  310. base_t(begin, end, file),
  311. _startline(begin)
  312. {}
  313. template <typename FileNameT, typename LineT>
  314. position_iterator2(
  315. const ForwardIteratorT& begin,
  316. const ForwardIteratorT& end,
  317. FileNameT file, LineT line):
  318. base_t(begin, end, file, line),
  319. _startline(begin)
  320. {}
  321. template <typename FileNameT, typename LineT, typename ColumnT>
  322. position_iterator2(
  323. const ForwardIteratorT& begin,
  324. const ForwardIteratorT& end,
  325. FileNameT file, LineT line, ColumnT column):
  326. base_t(begin, end, file, line, column),
  327. _startline(begin)
  328. {}
  329. position_iterator2(
  330. const ForwardIteratorT& begin,
  331. const ForwardIteratorT& end,
  332. const PositionT& pos):
  333. base_t(begin, end, pos),
  334. _startline(begin)
  335. {}
  336. position_iterator2(const position_iterator2& iter)
  337. : base_t(iter), _startline(iter._startline)
  338. {}
  339. position_iterator2& operator=(const position_iterator2& iter)
  340. {
  341. base_t::operator=(iter);
  342. _startline = iter._startline;
  343. return *this;
  344. }
  345. ForwardIteratorT get_currentline_begin(void) const
  346. { return _startline; }
  347. ForwardIteratorT get_currentline_end(void) const
  348. { return get_endline(); }
  349. std::basic_string<value_type> get_currentline(void) const
  350. {
  351. return std::basic_string<value_type>
  352. (get_currentline_begin(), get_currentline_end());
  353. }
  354. protected:
  355. ForwardIteratorT _startline;
  356. friend class position_iterator<ForwardIteratorT, PositionT,
  357. position_iterator2<ForwardIteratorT, PositionT> >;
  358. ForwardIteratorT get_endline() const
  359. {
  360. ForwardIteratorT endline = _startline;
  361. while (endline != this->_end && *endline != '\r' && *endline != '\n')
  362. {
  363. ++endline;
  364. }
  365. return endline;
  366. }
  367. void newline(void)
  368. { _startline = this->base(); }
  369. };
  370. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  371. }} // namespace BOOST_SPIRIT_CLASSIC_NS
  372. #endif