position_iterator_tests.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 473 行

CPP
473
字号
/*=============================================================================    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 <boost/config.hpp>#include <boost/concept_check.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 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();    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, ""));}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?