123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583 |
- /*=============================================================================
- Copyright (c) 2003 Giovanni Bajo
- http://spirit.sourceforge.net/
- Use, modification and distribution is subject to the Boost Software
- License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- http://www.boost.org/LICENSE_1_0.txt)
- =============================================================================*/
- #include <boost/detail/lightweight_test.hpp>
- #include <iostream>
- #include <vector>
- #include <string>
- #include <list>
- #include <algorithm>
- #include <iterator>
- #include <cstddef>
- #include <boost/config.hpp>
- #include <boost/concept_check.hpp>
- #include <boost/mpl/if.hpp>
- #include <boost/mpl/list.hpp>
- #include <boost/mpl/for_each.hpp>
- // Our baby
- #include <boost/spirit/include/classic_position_iterator.hpp>
- using namespace std;
- using namespace BOOST_SPIRIT_CLASSIC_NS;
- namespace mpl = boost::mpl;
- ///////////////////////////////////////////////////////////////////////////////
- namespace test_impl {
- template <typename IterT>
- void InstanciateTestOne(void)
- {
- IterT();
- // Check that the iterator is a full non-mutable forward iterator
- typedef boost::ForwardIteratorConcept<IterT> concept_t;
- boost::function_requires<concept_t>();
- }
- struct InstanciateTest
- {
- template <typename BaseIterT>
- void operator()(BaseIterT )
- {
- InstanciateTestOne<position_iterator<BaseIterT> >();
- InstanciateTestOne<position_iterator2<BaseIterT> >();
- InstanciateTestOne<position_iterator<BaseIterT, file_position_without_column> >();
- InstanciateTestOne<position_iterator2<BaseIterT, file_position_without_column> >();
- }
- };
- ///////////////////////////////////////////////////////////////////////////////
- } /* namespace test_impl */
- // These tests are defined after main() to be absolutely sure that the
- // instantiation test will happen before any other (since it's mainly
- // a compile-time test).
- void CheckInstantiation(void);
- void CheckConstructors(void);
- void CheckBasicFunctionality(void);
- void CheckColumnCounting(void);
- void CheckLineExtraction(void);
- void CheckDistance(void);
- void CheckSingular();
- void CheckInstantiation(void)
- {
- typedef mpl::list
- <
- char*
- ,const char*
- ,string::iterator
- ,string::const_iterator
- > iter_list_t;
- mpl::for_each<iter_list_t>(test_impl::InstanciateTest());
- }
- int main(void)
- {
- CheckInstantiation();
- CheckConstructors();
- CheckBasicFunctionality();
- CheckColumnCounting();
- CheckLineExtraction();
- CheckDistance();
- CheckSingular();
- return boost::report_errors();
- }
- ///////////////////////////////////////////////////////////////////////////////
- namespace test_impl {
- template <typename IterT>
- void CheckIncrement(IterT iter)
- {
- IterT end;
- // Check also that copy construction and assignment do not
- // interfere with increment
- IterT iter2(iter);
- IterT iter3 = iter;
- BOOST_TEST(iter != end);
- BOOST_TEST(iter2 != end);
- BOOST_TEST(iter3 != end);
- BOOST_TEST(*iter == '0');
- ++iter;
- ++iter2;
- ++iter3;
- BOOST_TEST(iter == iter2);
- BOOST_TEST(iter == iter3);
- BOOST_TEST(*iter == *iter2);
- BOOST_TEST(*iter == *iter3);
- BOOST_TEST(iter.get_position() == iter2.get_position());
- BOOST_TEST(iter.get_position() == iter3.get_position());
- BOOST_TEST(*iter == '1');
- BOOST_TEST(*iter++ == '1');
- BOOST_TEST(*iter2++ == '1');
- BOOST_TEST(*iter3++ == '1');
- BOOST_TEST(*iter == *iter2);
- BOOST_TEST(*iter == *iter3);
- BOOST_TEST(iter.get_position() == iter2.get_position());
- BOOST_TEST(iter.get_position() == iter3.get_position());
- BOOST_TEST(*iter == '2');
- ++iter; ++iter; ++iter; ++iter; ++iter; ++iter; ++iter;
- BOOST_TEST(*iter == '9');
- ++iter;
- BOOST_TEST(iter == end);
- // Check that one after end is no more end
- ++iter;
- BOOST_TEST(iter != end);
- }
- template <typename IterT>
- void CheckLineCounting(IterT iter)
- {
- IterT end;
- BOOST_TEST(*iter == '\n');
- BOOST_TEST(iter.get_position().line == 1);
- ++iter; // 0
- BOOST_TEST(iter.get_position().line == 2);
- ++iter; // 1
- ++iter; // 2
- ++iter; // 3
- ++iter; // \r
- BOOST_TEST(*iter == '\r');
- BOOST_TEST(iter.get_position().line == 2);
- ++iter; // \n
- BOOST_TEST(*iter == '\n');
- BOOST_TEST(iter.get_position().line == 2);
- ++iter; // 4
- BOOST_TEST(iter.get_position().line == 3);
- ++iter; // 5
- ++iter; // 6
- ++iter; // 7
- ++iter; // \n
- BOOST_TEST(*iter == '\n');
- BOOST_TEST(iter.get_position().line == 3);
- ++iter; // 8
- BOOST_TEST(iter.get_position().line == 4);
- ++iter; // 9
- ++iter; // \n
- BOOST_TEST(iter.get_position().line == 4);
- BOOST_TEST(*iter == '\n');
- ++iter; // \r
- BOOST_TEST(iter.get_position().line == 5);
- BOOST_TEST(*iter == '\r');
- ++iter; // end
- BOOST_TEST(iter.get_position().line == 6);
- BOOST_TEST(iter == end);
- }
- template <typename IterT>
- void CheckColumnCounting_Tab4(IterT iter)
- {
- IterT end;
- // Don't call set_tabchars() here because
- // default must be 3.
- BOOST_TEST(*iter == '\t');
- BOOST_TEST(iter.get_position().column == 1);
- ++iter; // 0
- BOOST_TEST(iter.get_position().column == 5);
- ++iter; // 1
- BOOST_TEST(iter.get_position().column == 6);
- ++iter; // 2
- BOOST_TEST(iter.get_position().column == 7);
- ++iter; // 3
- BOOST_TEST(iter.get_position().column == 8);
- ++iter; // tab
- BOOST_TEST(*iter == '\t');
- BOOST_TEST(iter.get_position().column == 9);
- ++iter; // 4
- BOOST_TEST(iter.get_position().column == 13);
- ++iter; // tab
- BOOST_TEST(*iter == '\t');
- BOOST_TEST(iter.get_position().column == 14);
- ++iter; // 5
- BOOST_TEST(iter.get_position().column == 17);
- ++iter; // tab
- BOOST_TEST(*iter == '\t');
- BOOST_TEST(iter.get_position().column == 18);
- ++iter; // end
- BOOST_TEST(iter == end);
- }
- template <typename IterT>
- void CheckColumnCounting_Tab3(IterT iter)
- {
- IterT end;
- iter.set_tabchars(3);
- // Check also that tab settings propagates through
- // assignment and copy construction
- IterT iter2(iter);
- IterT iter3; iter3 = iter2;
- BOOST_TEST(*iter == '\t');
- BOOST_TEST(iter.get_position().column == 1);
- ++iter; // 0
- ++iter2; ++iter3;
- BOOST_TEST(iter.get_position().column == 4);
- BOOST_TEST(iter2.get_position().column == 4);
- BOOST_TEST(iter3.get_position().column == 4);
- ++iter; // 1
- BOOST_TEST(iter.get_position().column == 5);
- ++iter; // 2
- BOOST_TEST(iter.get_position().column == 6);
- ++iter; // 3
- BOOST_TEST(iter.get_position().column == 7);
- ++iter; // tab
- BOOST_TEST(*iter == '\t');
- BOOST_TEST(iter.get_position().column == 8);
- ++iter; // 4
- BOOST_TEST(iter.get_position().column == 10);
- ++iter; // tab
- BOOST_TEST(*iter == '\t');
- BOOST_TEST(iter.get_position().column == 11);
- ++iter; // 5
- BOOST_TEST(iter.get_position().column == 13);
- ++iter; // tab
- BOOST_TEST(*iter == '\t');
- BOOST_TEST(iter.get_position().column == 14);
- ++iter; // end
- BOOST_TEST(iter == end);
- }
- const string line1 = "abcd";
- const string line2 = "efgh";
- const string linebuf = "\n" + line1 + "\n" + line2 + "\n";
- template <typename IterT>
- void AssertIterString(IterT begin, IterT end, string s)
- {
- BOOST_TEST(string(begin, end) == s);
- }
- template <typename IterT>
- void CheckLineExtractionOne(IterT iter)
- {
- IterT end;
- // At the start, we are on a newline, which is an empty
- // string
- BOOST_TEST(iter.get_currentline() == string());
- BOOST_TEST(
- string(iter.get_currentline_begin(), iter.get_currentline_end())
- == string());
- ++iter; // a
- ++iter; // b
- ++iter; // c
- BOOST_TEST(iter.get_currentline() == line1);
- AssertIterString(
- iter.get_currentline_begin(),
- iter.get_currentline_end(),
- line1);
- ++iter; // d
- ++iter; // newline
- ++iter; // e
- // check that copy construction and assignment do
- // not interfere with get_currentline
- IterT iter2(iter);
- IterT iter3; iter3 = iter;
- BOOST_TEST(iter2.get_currentline() == line2);
- BOOST_TEST(iter3.get_currentline() == line2);
- AssertIterString(
- iter2.get_currentline_begin(),
- iter2.get_currentline_end(),
- line2);
- AssertIterString(
- iter3.get_currentline_begin(),
- iter3.get_currentline_end(),
- line2);
- ++iter; // f
- ++iter; // g
- ++iter; // h
- ++iter; // newline
- // Check when the iterator is on a newline
- BOOST_TEST(iter.get_currentline() == line2);
- AssertIterString(
- iter.get_currentline_begin(),
- iter.get_currentline_end(),
- line2);
- ++iter;
- BOOST_TEST(iter == end);
- }
- void CheckLineExtraction(void)
- {
- typedef string::const_iterator iter_t;
- CheckLineExtractionOne(
- position_iterator2<iter_t, file_position>
- (linebuf.begin(), linebuf.end(), ""));
- CheckLineExtractionOne(
- position_iterator2<iter_t, file_position_without_column>
- (linebuf.begin(), linebuf.end(), ""));
- }
- template <typename IterT>
- void CheckEmptySequence(void)
- {
- typedef IterT iter_t;
- char a[10];
- // Check construction with empty sequence, and
- // correct propagation of the information
- iter_t iter(a,a, "");
- iter_t iter2(iter);
- iter_t iter3; iter3 = iter;
- BOOST_TEST(iter == iter_t());
- BOOST_TEST(iter2 == iter_t());
- BOOST_TEST(iter3 == iter_t());
- }
- template <typename IterC, typename Iter>
- void CheckConstructors(void)
- {
- char a[20];
- std::string name = "abc";
- file_position_without_column pos(name,1);
- file_position posc(name,1,1);
- typedef IterC iterc_t;
- typedef Iter iter_t;
- BOOST_TEST(iterc_t(a,a+20,name).get_position() == posc);
- BOOST_TEST(iterc_t(a,a+20,name,1).get_position() == posc);
- BOOST_TEST(iterc_t(a,a+20,name,1,1).get_position() == posc);
- BOOST_TEST(iterc_t(a,a+20,posc).get_position() == posc);
- BOOST_TEST(iter_t(a,a+20,name).get_position() == pos);
- BOOST_TEST(iter_t(a,a+20,name,1).get_position() == pos);
- BOOST_TEST(iter_t(a,a+20,pos).get_position() == pos);
- // Check copy constructor and assignment. Notice that we want
- // an implicit copy constructor.
- iterc_t ic1(a,a+20,name);
- iterc_t ic2 = ic1;
- iterc_t ic3; ic3 = ic1;
- BOOST_TEST(ic1 == ic2);
- BOOST_TEST(ic1 == ic3);
- BOOST_TEST(ic1.get_position() == ic2.get_position());
- BOOST_TEST(ic1.get_position() == ic3.get_position());
- iter_t i1(a,a+20,name);
- iter_t i2 = i1;
- iter_t i3; i3 = i1;
- BOOST_TEST(i1 == i2);
- BOOST_TEST(i1 == i3);
- BOOST_TEST(i1.get_position() == i2.get_position());
- BOOST_TEST(i1.get_position() == i3.get_position());
- // Check construction with an empty sequence
- CheckEmptySequence<iter_t>();
- CheckEmptySequence<iterc_t>();
- }
- template <typename IterT>
- void CheckDistance(IterT begin)
- {
- IterT end;
- std::size_t std_distance = std::distance(begin, end);
-
- std::size_t manual_count = 0;
- for(IterT it = begin; it != end; ++it)
- ++manual_count;
-
- BOOST_TEST(std_distance == manual_count);
- }
- ///////////////////////////////////////////////////////////////////////////////
- } /* namespace test_impl */
- void CheckConstructors(void)
- {
- test_impl::CheckConstructors
- <
- position_iterator<char*, file_position>,
- position_iterator<char*, file_position_without_column>
- >();
- test_impl::CheckConstructors
- <
- position_iterator2<char*, file_position>,
- position_iterator2<char*, file_position_without_column>
- >();
- }
- void CheckBasicFunctionality(void)
- {
- const char* a = "0123456789";
- typedef const char* iter_t;
- test_impl::CheckIncrement(position_iterator<iter_t>(a, a+10, ""));
- test_impl::CheckIncrement(position_iterator2<iter_t>(a, a+10, ""));
- test_impl::CheckIncrement(position_iterator<iter_t, file_position_without_column>(a, a+10, ""));
- test_impl::CheckIncrement(position_iterator2<iter_t, file_position_without_column>(a, a+10, ""));
- const char* b = "\n0123\r\n4567\n89\n\r";
- test_impl::CheckLineCounting(position_iterator<iter_t>(b, b+16, ""));
- test_impl::CheckLineCounting(position_iterator2<iter_t>(b, b+16, ""));
- test_impl::CheckLineCounting(position_iterator<iter_t, file_position_without_column>(b, b+16, ""));
- test_impl::CheckLineCounting(position_iterator2<iter_t, file_position_without_column>(b, b+16, ""));
- }
- void CheckColumnCounting(void)
- {
- const char* a = "\t0123\t4\t5\t";
- typedef const char* iter_t;
- test_impl::CheckColumnCounting_Tab4(position_iterator<iter_t>(a, a+10, ""));
- test_impl::CheckColumnCounting_Tab4(position_iterator2<iter_t>(a, a+10, ""));
- test_impl::CheckColumnCounting_Tab3(position_iterator<iter_t>(a, a+10, ""));
- test_impl::CheckColumnCounting_Tab3(position_iterator2<iter_t>(a, a+10, ""));
- }
- void CheckLineExtraction(void)
- {
- test_impl::CheckLineExtraction();
- }
- void CheckDistance(void)
- {
- const char* b = "\n0123\r\n4567\n89\n\r";
- typedef const char* iter_t;
-
- test_impl::CheckDistance(position_iterator<iter_t>(b, b+15, ""));
- test_impl::CheckDistance(position_iterator2<iter_t>(b, b+15, ""));
- test_impl::CheckDistance(position_iterator<iter_t, file_position_without_column>(b, b+15, ""));
- test_impl::CheckDistance(position_iterator2<iter_t, file_position_without_column>(b, b+15, ""));
- }
- ///////////////////////////////////////////////////////////////////////////////
- namespace test_impl {
- template <bool AsValue = false>
- class check_singular_iterator
- {
- bool singular_;
- int count_;
- public:
- typedef std::forward_iterator_tag iterator_category;
- typedef int value_type;
- typedef std::ptrdiff_t difference_type;
- typedef int const* pointer;
- typedef typename boost::mpl::if_c<AsValue, int, int const&>::type reference;
- check_singular_iterator() : singular_(true), count_(0) {}
- explicit check_singular_iterator(int x) : singular_(false), count_(x) {}
- reference operator*() const {
- BOOST_TEST(!singular_);
- return count_;
- }
- pointer operator->() const {
- BOOST_TEST(!singular_);
- return &count_;
- }
- check_singular_iterator& operator++() {
- BOOST_TEST(count_ > 0);
- --count_;
- return *this;
- }
- check_singular_iterator operator++(int) {
- check_singular_iterator tmp(*this);
- ++(*this);
- return tmp;
- }
- bool operator==(check_singular_iterator const& other) const {
- BOOST_TEST(!singular_ && !other.singular_);
- return count_ == other.count_;
- }
- bool operator!=(check_singular_iterator const& other) const {
- return !(*this == other);
- }
- };
- template <typename CountIterator, typename Iterator>
- void CheckSingularImpl()
- {
- CountIterator begin(Iterator(5), Iterator(0));
- CountIterator end1(Iterator(0), Iterator(0));
- CountIterator end2;
- BOOST_TEST(begin == begin);
- BOOST_TEST(begin != end1);
- BOOST_TEST(begin != end2);
- BOOST_TEST(end1 != begin);
- BOOST_TEST(end1 == end1);
- BOOST_TEST(end1 == end2);
- BOOST_TEST(end2 != begin);
- BOOST_TEST(end2 == end1);
- BOOST_TEST(end2 == end2);
- BOOST_TEST(std::distance(begin, begin) == 0);
- BOOST_TEST(std::distance(begin, end1) == 5);
- BOOST_TEST(std::distance(begin, end2) == 5);
- BOOST_TEST(std::distance(end1, end1) == 0);
- BOOST_TEST(std::distance(end1, end2) == 0);
- BOOST_TEST(std::distance(end2, end1) == 0);
- BOOST_TEST(std::distance(end2, end2) == 0);
- BOOST_TEST(*begin == 5);
- }
- template <typename PositionT>
- void CheckSingular()
- {
- {
- typedef check_singular_iterator<false> interator_type;
- CheckSingularImpl<position_iterator<interator_type, PositionT>, interator_type>();
- CheckSingularImpl<position_iterator2<interator_type, PositionT>, interator_type>();
- }
- {
- typedef check_singular_iterator<true> interator_type;
- CheckSingularImpl<position_iterator<interator_type, PositionT>, interator_type>();
- CheckSingularImpl<position_iterator2<interator_type, PositionT>, interator_type>();
- }
- }
- }
- void CheckSingular()
- {
- test_impl::CheckSingular<file_position>();
- test_impl::CheckSingular<file_position_without_column>();
- }
|