]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/spirit/classic/test/position_iterator_tests.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / spirit / classic / test / position_iterator_tests.cpp
CommitLineData
7c673cae
FG
1/*=============================================================================
2 Copyright (c) 2003 Giovanni Bajo
3 http://spirit.sourceforge.net/
4
5 Use, modification and distribution is subject to the Boost Software
6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 http://www.boost.org/LICENSE_1_0.txt)
8=============================================================================*/
9
1e59de90 10#include <boost/core/lightweight_test.hpp>
7c673cae
FG
11#include <iostream>
12#include <vector>
13#include <string>
14#include <list>
15#include <algorithm>
11fdf7f2
TL
16#include <iterator>
17#include <cstddef>
7c673cae
FG
18#include <boost/config.hpp>
19#include <boost/concept_check.hpp>
92f5a8d4 20#include <boost/mpl/if.hpp>
7c673cae
FG
21#include <boost/mpl/list.hpp>
22#include <boost/mpl/for_each.hpp>
23
24// Our baby
25#include <boost/spirit/include/classic_position_iterator.hpp>
26
27using namespace std;
28using namespace BOOST_SPIRIT_CLASSIC_NS;
29namespace mpl = boost::mpl;
30
31///////////////////////////////////////////////////////////////////////////////
32namespace test_impl {
33
34template <typename IterT>
35void InstanciateTestOne(void)
36{
37 IterT();
38
39 // Check that the iterator is a full non-mutable forward iterator
40 typedef boost::ForwardIteratorConcept<IterT> concept_t;
41 boost::function_requires<concept_t>();
42}
43
44struct InstanciateTest
45{
46 template <typename BaseIterT>
47 void operator()(BaseIterT )
48 {
49 InstanciateTestOne<position_iterator<BaseIterT> >();
50 InstanciateTestOne<position_iterator2<BaseIterT> >();
51 InstanciateTestOne<position_iterator<BaseIterT, file_position_without_column> >();
52 InstanciateTestOne<position_iterator2<BaseIterT, file_position_without_column> >();
53 }
54};
55
56///////////////////////////////////////////////////////////////////////////////
57} /* namespace test_impl */
58
59// These tests are defined after main() to be absolutely sure that the
60// instantiation test will happen before any other (since it's mainly
61// a compile-time test).
62void CheckInstantiation(void);
63void CheckConstructors(void);
64void CheckBasicFunctionality(void);
65void CheckColumnCounting(void);
66void CheckLineExtraction(void);
67void CheckDistance(void);
68void CheckSingular();
69
70void CheckInstantiation(void)
71{
72 typedef mpl::list
73 <
74 char*
75 ,const char*
76 ,string::iterator
77 ,string::const_iterator
78 > iter_list_t;
79
80 mpl::for_each<iter_list_t>(test_impl::InstanciateTest());
81}
82
83int main(void)
84{
85 CheckInstantiation();
86 CheckConstructors();
87 CheckBasicFunctionality();
88 CheckColumnCounting();
89 CheckLineExtraction();
90 CheckDistance();
91 CheckSingular();
92
93 return boost::report_errors();
94}
95
96///////////////////////////////////////////////////////////////////////////////
97namespace test_impl {
98
99template <typename IterT>
100void CheckIncrement(IterT iter)
101{
102 IterT end;
103
104 // Check also that copy construction and assignment do not
105 // interfere with increment
106 IterT iter2(iter);
107 IterT iter3 = iter;
108
109 BOOST_TEST(iter != end);
110 BOOST_TEST(iter2 != end);
111 BOOST_TEST(iter3 != end);
112 BOOST_TEST(*iter == '0');
113
114 ++iter;
115 ++iter2;
116 ++iter3;
117 BOOST_TEST(iter == iter2);
118 BOOST_TEST(iter == iter3);
119 BOOST_TEST(*iter == *iter2);
120 BOOST_TEST(*iter == *iter3);
121 BOOST_TEST(iter.get_position() == iter2.get_position());
122 BOOST_TEST(iter.get_position() == iter3.get_position());
123 BOOST_TEST(*iter == '1');
124
125 BOOST_TEST(*iter++ == '1');
126 BOOST_TEST(*iter2++ == '1');
127 BOOST_TEST(*iter3++ == '1');
128 BOOST_TEST(*iter == *iter2);
129 BOOST_TEST(*iter == *iter3);
130 BOOST_TEST(iter.get_position() == iter2.get_position());
131 BOOST_TEST(iter.get_position() == iter3.get_position());
132 BOOST_TEST(*iter == '2');
133
134 ++iter; ++iter; ++iter; ++iter; ++iter; ++iter; ++iter;
135 BOOST_TEST(*iter == '9');
136 ++iter;
137 BOOST_TEST(iter == end);
138
139 // Check that one after end is no more end
140 ++iter;
141 BOOST_TEST(iter != end);
142}
143
144template <typename IterT>
145void CheckLineCounting(IterT iter)
146{
147 IterT end;
148
149 BOOST_TEST(*iter == '\n');
150 BOOST_TEST(iter.get_position().line == 1);
151 ++iter; // 0
152 BOOST_TEST(iter.get_position().line == 2);
153 ++iter; // 1
154 ++iter; // 2
155 ++iter; // 3
156 ++iter; // \r
157 BOOST_TEST(*iter == '\r');
158 BOOST_TEST(iter.get_position().line == 2);
159 ++iter; // \n
160 BOOST_TEST(*iter == '\n');
161 BOOST_TEST(iter.get_position().line == 2);
162 ++iter; // 4
163 BOOST_TEST(iter.get_position().line == 3);
164 ++iter; // 5
165 ++iter; // 6
166 ++iter; // 7
167 ++iter; // \n
168 BOOST_TEST(*iter == '\n');
169 BOOST_TEST(iter.get_position().line == 3);
170 ++iter; // 8
171 BOOST_TEST(iter.get_position().line == 4);
172 ++iter; // 9
173 ++iter; // \n
174 BOOST_TEST(iter.get_position().line == 4);
175 BOOST_TEST(*iter == '\n');
176 ++iter; // \r
177 BOOST_TEST(iter.get_position().line == 5);
178 BOOST_TEST(*iter == '\r');
179 ++iter; // end
180 BOOST_TEST(iter.get_position().line == 6);
181 BOOST_TEST(iter == end);
182}
183
184template <typename IterT>
185void CheckColumnCounting_Tab4(IterT iter)
186{
187 IterT end;
188
189 // Don't call set_tabchars() here because
190 // default must be 3.
191 BOOST_TEST(*iter == '\t');
192 BOOST_TEST(iter.get_position().column == 1);
193 ++iter; // 0
194 BOOST_TEST(iter.get_position().column == 5);
195 ++iter; // 1
196 BOOST_TEST(iter.get_position().column == 6);
197 ++iter; // 2
198 BOOST_TEST(iter.get_position().column == 7);
199 ++iter; // 3
200 BOOST_TEST(iter.get_position().column == 8);
201 ++iter; // tab
202 BOOST_TEST(*iter == '\t');
203 BOOST_TEST(iter.get_position().column == 9);
204 ++iter; // 4
205 BOOST_TEST(iter.get_position().column == 13);
206 ++iter; // tab
207 BOOST_TEST(*iter == '\t');
208 BOOST_TEST(iter.get_position().column == 14);
209 ++iter; // 5
210 BOOST_TEST(iter.get_position().column == 17);
211 ++iter; // tab
212 BOOST_TEST(*iter == '\t');
213 BOOST_TEST(iter.get_position().column == 18);
214 ++iter; // end
215 BOOST_TEST(iter == end);
216}
217
218template <typename IterT>
219void CheckColumnCounting_Tab3(IterT iter)
220{
221 IterT end;
222
223 iter.set_tabchars(3);
224
225 // Check also that tab settings propagates through
226 // assignment and copy construction
227 IterT iter2(iter);
228 IterT iter3; iter3 = iter2;
229
230 BOOST_TEST(*iter == '\t');
231 BOOST_TEST(iter.get_position().column == 1);
232 ++iter; // 0
233 ++iter2; ++iter3;
234 BOOST_TEST(iter.get_position().column == 4);
235 BOOST_TEST(iter2.get_position().column == 4);
236 BOOST_TEST(iter3.get_position().column == 4);
237 ++iter; // 1
238 BOOST_TEST(iter.get_position().column == 5);
239 ++iter; // 2
240 BOOST_TEST(iter.get_position().column == 6);
241 ++iter; // 3
242 BOOST_TEST(iter.get_position().column == 7);
243 ++iter; // tab
244 BOOST_TEST(*iter == '\t');
245 BOOST_TEST(iter.get_position().column == 8);
246 ++iter; // 4
247 BOOST_TEST(iter.get_position().column == 10);
248 ++iter; // tab
249 BOOST_TEST(*iter == '\t');
250 BOOST_TEST(iter.get_position().column == 11);
251 ++iter; // 5
252 BOOST_TEST(iter.get_position().column == 13);
253 ++iter; // tab
254 BOOST_TEST(*iter == '\t');
255 BOOST_TEST(iter.get_position().column == 14);
256 ++iter; // end
257 BOOST_TEST(iter == end);
258}
259
260const string line1 = "abcd";
261const string line2 = "efgh";
262const string linebuf = "\n" + line1 + "\n" + line2 + "\n";
263
264template <typename IterT>
265void AssertIterString(IterT begin, IterT end, string s)
266{
267 BOOST_TEST(string(begin, end) == s);
268}
269
270template <typename IterT>
271void CheckLineExtractionOne(IterT iter)
272{
273 IterT end;
274
275 // At the start, we are on a newline, which is an empty
276 // string
277 BOOST_TEST(iter.get_currentline() == string());
278 BOOST_TEST(
279 string(iter.get_currentline_begin(), iter.get_currentline_end())
280 == string());
281
282 ++iter; // a
283 ++iter; // b
284 ++iter; // c
285 BOOST_TEST(iter.get_currentline() == line1);
286 AssertIterString(
287 iter.get_currentline_begin(),
288 iter.get_currentline_end(),
289 line1);
290
291 ++iter; // d
292 ++iter; // newline
293 ++iter; // e
294
295 // check that copy construction and assignment do
296 // not interfere with get_currentline
297 IterT iter2(iter);
298 IterT iter3; iter3 = iter;
299 BOOST_TEST(iter2.get_currentline() == line2);
300 BOOST_TEST(iter3.get_currentline() == line2);
301 AssertIterString(
302 iter2.get_currentline_begin(),
303 iter2.get_currentline_end(),
304 line2);
305 AssertIterString(
306 iter3.get_currentline_begin(),
307 iter3.get_currentline_end(),
308 line2);
309
310 ++iter; // f
311 ++iter; // g
312 ++iter; // h
313 ++iter; // newline
314
315 // Check when the iterator is on a newline
316 BOOST_TEST(iter.get_currentline() == line2);
317 AssertIterString(
318 iter.get_currentline_begin(),
319 iter.get_currentline_end(),
320 line2);
321
322 ++iter;
323 BOOST_TEST(iter == end);
324}
325
326
327void CheckLineExtraction(void)
328{
329 typedef string::const_iterator iter_t;
330
331 CheckLineExtractionOne(
332 position_iterator2<iter_t, file_position>
333 (linebuf.begin(), linebuf.end(), ""));
334
335 CheckLineExtractionOne(
336 position_iterator2<iter_t, file_position_without_column>
337 (linebuf.begin(), linebuf.end(), ""));
338}
339
340template <typename IterT>
341void CheckEmptySequence(void)
342{
343 typedef IterT iter_t;
344 char a[10];
345
346 // Check construction with empty sequence, and
347 // correct propagation of the information
348 iter_t iter(a,a, "");
349 iter_t iter2(iter);
350 iter_t iter3; iter3 = iter;
351
352 BOOST_TEST(iter == iter_t());
353 BOOST_TEST(iter2 == iter_t());
354 BOOST_TEST(iter3 == iter_t());
355}
356
357template <typename IterC, typename Iter>
358void CheckConstructors(void)
359{
360 char a[20];
361 std::string name = "abc";
362
363 file_position_without_column pos(name,1);
364 file_position posc(name,1,1);
365 typedef IterC iterc_t;
366 typedef Iter iter_t;
367
368 BOOST_TEST(iterc_t(a,a+20,name).get_position() == posc);
369 BOOST_TEST(iterc_t(a,a+20,name,1).get_position() == posc);
370 BOOST_TEST(iterc_t(a,a+20,name,1,1).get_position() == posc);
371 BOOST_TEST(iterc_t(a,a+20,posc).get_position() == posc);
372 BOOST_TEST(iter_t(a,a+20,name).get_position() == pos);
373 BOOST_TEST(iter_t(a,a+20,name,1).get_position() == pos);
374 BOOST_TEST(iter_t(a,a+20,pos).get_position() == pos);
375
376 // Check copy constructor and assignment. Notice that we want
377 // an implicit copy constructor.
378 iterc_t ic1(a,a+20,name);
379 iterc_t ic2 = ic1;
380 iterc_t ic3; ic3 = ic1;
381 BOOST_TEST(ic1 == ic2);
382 BOOST_TEST(ic1 == ic3);
383 BOOST_TEST(ic1.get_position() == ic2.get_position());
384 BOOST_TEST(ic1.get_position() == ic3.get_position());
385
386 iter_t i1(a,a+20,name);
387 iter_t i2 = i1;
388 iter_t i3; i3 = i1;
389 BOOST_TEST(i1 == i2);
390 BOOST_TEST(i1 == i3);
391 BOOST_TEST(i1.get_position() == i2.get_position());
392 BOOST_TEST(i1.get_position() == i3.get_position());
393
394 // Check construction with an empty sequence
395 CheckEmptySequence<iter_t>();
396 CheckEmptySequence<iterc_t>();
397}
398
399template <typename IterT>
400void CheckDistance(IterT begin)
401{
402 IterT end;
403
404 std::size_t std_distance = std::distance(begin, end);
405
406 std::size_t manual_count = 0;
407 for(IterT it = begin; it != end; ++it)
408 ++manual_count;
409
410 BOOST_TEST(std_distance == manual_count);
411}
412
413
414///////////////////////////////////////////////////////////////////////////////
415} /* namespace test_impl */
416
417
418void CheckConstructors(void)
419{
420 test_impl::CheckConstructors
421 <
422 position_iterator<char*, file_position>,
423 position_iterator<char*, file_position_without_column>
424 >();
425
426 test_impl::CheckConstructors
427 <
428 position_iterator2<char*, file_position>,
429 position_iterator2<char*, file_position_without_column>
430 >();
431}
432
433void CheckBasicFunctionality(void)
434{
435 const char* a = "0123456789";
436 typedef const char* iter_t;
437
438 test_impl::CheckIncrement(position_iterator<iter_t>(a, a+10, ""));
439 test_impl::CheckIncrement(position_iterator2<iter_t>(a, a+10, ""));
440 test_impl::CheckIncrement(position_iterator<iter_t, file_position_without_column>(a, a+10, ""));
441 test_impl::CheckIncrement(position_iterator2<iter_t, file_position_without_column>(a, a+10, ""));
442
443 const char* b = "\n0123\r\n4567\n89\n\r";
444
445 test_impl::CheckLineCounting(position_iterator<iter_t>(b, b+16, ""));
446 test_impl::CheckLineCounting(position_iterator2<iter_t>(b, b+16, ""));
447 test_impl::CheckLineCounting(position_iterator<iter_t, file_position_without_column>(b, b+16, ""));
448 test_impl::CheckLineCounting(position_iterator2<iter_t, file_position_without_column>(b, b+16, ""));
449}
450
451
452void CheckColumnCounting(void)
453{
454 const char* a = "\t0123\t4\t5\t";
455 typedef const char* iter_t;
456
457 test_impl::CheckColumnCounting_Tab4(position_iterator<iter_t>(a, a+10, ""));
458 test_impl::CheckColumnCounting_Tab4(position_iterator2<iter_t>(a, a+10, ""));
459 test_impl::CheckColumnCounting_Tab3(position_iterator<iter_t>(a, a+10, ""));
460 test_impl::CheckColumnCounting_Tab3(position_iterator2<iter_t>(a, a+10, ""));
461}
462
463void CheckLineExtraction(void)
464{
465 test_impl::CheckLineExtraction();
466}
467
468void CheckDistance(void)
469{
470 const char* b = "\n0123\r\n4567\n89\n\r";
471 typedef const char* iter_t;
472
473 test_impl::CheckDistance(position_iterator<iter_t>(b, b+15, ""));
474 test_impl::CheckDistance(position_iterator2<iter_t>(b, b+15, ""));
475 test_impl::CheckDistance(position_iterator<iter_t, file_position_without_column>(b, b+15, ""));
476 test_impl::CheckDistance(position_iterator2<iter_t, file_position_without_column>(b, b+15, ""));
477}
478
479///////////////////////////////////////////////////////////////////////////////
480
481namespace test_impl {
482
92f5a8d4 483 template <bool AsValue = false>
7c673cae 484 class check_singular_iterator
7c673cae
FG
485 {
486 bool singular_;
487 int count_;
488
489 public:
11fdf7f2
TL
490 typedef std::forward_iterator_tag iterator_category;
491 typedef int value_type;
492 typedef std::ptrdiff_t difference_type;
92f5a8d4
TL
493 typedef int const* pointer;
494 typedef typename boost::mpl::if_c<AsValue, int, int const&>::type reference;
7c673cae
FG
495
496 check_singular_iterator() : singular_(true), count_(0) {}
497 explicit check_singular_iterator(int x) : singular_(false), count_(x) {}
498
92f5a8d4 499 reference operator*() const {
7c673cae
FG
500 BOOST_TEST(!singular_);
501 return count_;
502 }
503
92f5a8d4 504 pointer operator->() const {
7c673cae
FG
505 BOOST_TEST(!singular_);
506 return &count_;
507 }
508
509 check_singular_iterator& operator++() {
510 BOOST_TEST(count_ > 0);
511 --count_;
512 return *this;
513 }
514
515 check_singular_iterator operator++(int) {
516 check_singular_iterator tmp(*this);
517 ++(*this);
518 return tmp;
519 }
520
521 bool operator==(check_singular_iterator const& other) const {
522 BOOST_TEST(!singular_ && !other.singular_);
523 return count_ == other.count_;
524 }
525
526 bool operator!=(check_singular_iterator const& other) const {
527 return !(*this == other);
528 }
529 };
530
92f5a8d4
TL
531 template <typename CountIterator, typename Iterator>
532 void CheckSingularImpl()
7c673cae 533 {
92f5a8d4
TL
534 CountIterator begin(Iterator(5), Iterator(0));
535 CountIterator end1(Iterator(0), Iterator(0));
7c673cae
FG
536 CountIterator end2;
537
538 BOOST_TEST(begin == begin);
539 BOOST_TEST(begin != end1);
540 BOOST_TEST(begin != end2);
541
542 BOOST_TEST(end1 != begin);
543 BOOST_TEST(end1 == end1);
544 BOOST_TEST(end1 == end2);
545
546 BOOST_TEST(end2 != begin);
547 BOOST_TEST(end2 == end1);
548 BOOST_TEST(end2 == end2);
549
550 BOOST_TEST(std::distance(begin, begin) == 0);
551 BOOST_TEST(std::distance(begin, end1) == 5);
552 BOOST_TEST(std::distance(begin, end2) == 5);
553
554 BOOST_TEST(std::distance(end1, end1) == 0);
555 BOOST_TEST(std::distance(end1, end2) == 0);
556
557 BOOST_TEST(std::distance(end2, end1) == 0);
558 BOOST_TEST(std::distance(end2, end2) == 0);
92f5a8d4
TL
559
560 BOOST_TEST(*begin == 5);
561 }
562
563 template <typename PositionT>
564 void CheckSingular()
565 {
566 {
567 typedef check_singular_iterator<false> interator_type;
568 CheckSingularImpl<position_iterator<interator_type, PositionT>, interator_type>();
569 CheckSingularImpl<position_iterator2<interator_type, PositionT>, interator_type>();
570 }
571 {
572 typedef check_singular_iterator<true> interator_type;
573 CheckSingularImpl<position_iterator<interator_type, PositionT>, interator_type>();
574 CheckSingularImpl<position_iterator2<interator_type, PositionT>, interator_type>();
575 }
7c673cae
FG
576 }
577}
578
579void CheckSingular()
580{
92f5a8d4
TL
581 test_impl::CheckSingular<file_position>();
582 test_impl::CheckSingular<file_position_without_column>();
7c673cae 583}