blob: 2dcf2e5652ddc15becee35faedda47e386063982 [file] [log] [blame]
/*=============================================================================
Copyright (c) 2001-2003 Daniel Nuffer
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/spirit/include/classic_multi_pass.hpp>
#include <boost/scoped_ptr.hpp>
#include <iterator>
#include <string>
#include <boost/detail/lightweight_test.hpp>
#include "impl/sstream.hpp"
using namespace std;
using namespace BOOST_SPIRIT_CLASSIC_NS;
sstream_t res;
typedef multi_pass<istream_iterator<char> > default_multi_pass_t;
typedef look_ahead<istream_iterator<char>, 6> fixed_multi_pass_t;
typedef multi_pass<
istream_iterator<char>,
multi_pass_policies::input_iterator,
multi_pass_policies::first_owner,
multi_pass_policies::buf_id_check,
multi_pass_policies::std_deque
> first_owner_multi_pass_t;
// a functor to test out the functor_multi_pass
class my_functor
{
public:
typedef char result_type;
my_functor()
: c('A')
{}
char operator()()
{
if (c == 'M')
return eof;
else
return c++;
}
static result_type eof;
private:
char c;
};
my_functor::result_type my_functor::eof = '\0';
typedef multi_pass<
my_functor,
multi_pass_policies::functor_input,
multi_pass_policies::first_owner,
multi_pass_policies::no_check,
multi_pass_policies::std_deque
> functor_multi_pass_t;
void test_default_multi_pass()
{
res << "-*= test_default_multi_pass =*-\n";
istream_iterator<char> end;
boost::scoped_ptr<default_multi_pass_t> mpend(new default_multi_pass_t(end));
{
sstream_t ss;
ss << "test string";
istream_iterator<char> a(ss);
boost::scoped_ptr<default_multi_pass_t> mp1(new default_multi_pass_t(a));
while (*mp1 != *mpend)
{
res << *((*mp1)++);
}
res << endl;
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> b(ss);
boost::scoped_ptr<default_multi_pass_t> mp2(new default_multi_pass_t(b));
boost::scoped_ptr<default_multi_pass_t> mp3(new default_multi_pass_t(b));
*mp3 = *mp2;
for (int i = 0; i < 4; ++i)
{
res << **mp2;
++*mp2;
}
mp3.reset();
while (*mp2 != *mpend)
{
res << **mp2;
++*mp2;
}
res << endl;
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> a(ss);
boost::scoped_ptr<default_multi_pass_t> mp1(new default_multi_pass_t(a));
boost::scoped_ptr<default_multi_pass_t> mp2(new default_multi_pass_t(*mp1));
for (int i = 0; i < 4; ++i)
{
res << **mp1;
++*mp1;
}
while (*mp2 != *mpend)
{
res << **mp2;
++*mp2;
}
while (*mp1 != *mpend)
{
res << **mp1;
++*mp1;
}
res << endl;
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> b(ss);
boost::scoped_ptr<default_multi_pass_t> mp2(new default_multi_pass_t(b));
boost::scoped_ptr<default_multi_pass_t> mp3(new default_multi_pass_t(b));
*mp3 = *mp2;
for (int i = 0; i < 4; ++i)
{
res << **mp2;
++*mp2;
}
mp3.reset();
++*mp2;
while (*mp2 != *mpend)
{
res << **mp2;
++*mp2;
}
res << endl;
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> a(ss);
boost::scoped_ptr<default_multi_pass_t> mp1(new default_multi_pass_t(a));
boost::scoped_ptr<default_multi_pass_t> mp2(new default_multi_pass_t(*mp1));
BOOST_TEST(*mp1 == *mp2);
BOOST_TEST(*mp1 >= *mp2);
BOOST_TEST(*mp1 <= *mp2);
for (int i = 0; i < 4; ++i)
{
res << **mp1;
++*mp1;
}
BOOST_TEST(*mp1 != *mp2);
BOOST_TEST(*mp1 > *mp2);
BOOST_TEST(*mp1 >= *mp2);
BOOST_TEST(*mp2 < *mp1);
BOOST_TEST(*mp2 <= *mp1);
while (*mp2 != *mp1)
{
res << **mp2;
++*mp2;
}
BOOST_TEST(*mp1 == *mp2);
BOOST_TEST(*mp1 >= *mp2);
BOOST_TEST(*mp1 <= *mp2);
while (*mp1 != *mpend)
{
res << **mp1;
++*mp1;
}
BOOST_TEST(*mp1 != *mp2);
BOOST_TEST(*mp1 > *mp2);
BOOST_TEST(*mp1 >= *mp2);
BOOST_TEST(*mp2 < *mp1);
BOOST_TEST(*mp2 <= *mp1);
while (*mp2 != *mpend)
{
res << **mp2;
++*mp2;
}
BOOST_TEST(*mp1 == *mp2);
BOOST_TEST(*mp1 >= *mp2);
BOOST_TEST(*mp1 <= *mp2);
res << endl;
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> a(ss);
boost::scoped_ptr<default_multi_pass_t> mp1(new default_multi_pass_t(a));
boost::scoped_ptr<default_multi_pass_t> mp2(new default_multi_pass_t(a));
BOOST_TEST(*mp1 != *mp2);
++*mp1;
BOOST_TEST(*mp1 != *mp2);
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> b(ss);
boost::scoped_ptr<default_multi_pass_t> mp2(new default_multi_pass_t(b));
boost::scoped_ptr<default_multi_pass_t> mp3(new default_multi_pass_t(b));
*mp3 = *mp2;
for (int i = 0; i < 4; ++i)
{
res << **mp2;
++*mp2;
}
mp2->clear_queue();
while (*mp2 != *mpend)
{
res << **mp2;
++*mp2;
}
try
{
res << **mp3; // this should throw illegal_backtracking
BOOST_TEST(0);
}
catch (const BOOST_SPIRIT_CLASSIC_NS::multi_pass_policies::illegal_backtracking& /*e*/)
{
}
res << endl;
}
}
void test_fixed_multi_pass()
{
res << "-*= test_fixed_multi_pass =*-\n";
istream_iterator<char> end;
boost::scoped_ptr<fixed_multi_pass_t> mpend(new fixed_multi_pass_t(end));
{
sstream_t ss;
ss << "test string";
istream_iterator<char> a(ss);
boost::scoped_ptr<fixed_multi_pass_t> mp1(new fixed_multi_pass_t(a));
while (*mp1 != *mpend)
{
res << *((*mp1)++);
}
res << endl;
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> b(ss);
boost::scoped_ptr<fixed_multi_pass_t> mp2(new fixed_multi_pass_t(b));
boost::scoped_ptr<fixed_multi_pass_t> mp3(new fixed_multi_pass_t(*mp2));
for (int i = 0; i < 4; ++i)
{
res << **mp2;
++*mp2;
}
mp3.reset();
while (*mp2 != *mpend)
{
res << **mp2;
++*mp2;
}
res << endl;
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> a(ss);
boost::scoped_ptr<fixed_multi_pass_t> mp1(new fixed_multi_pass_t(a));
boost::scoped_ptr<fixed_multi_pass_t> mp2(new fixed_multi_pass_t(*mp1));
for (int i = 0; i < 4; ++i)
{
res << **mp1;
++*mp1;
}
while (*mp2 != *mpend)
{
res << **mp2;
++*mp2;
}
while (*mp1 != *mpend)
{
res << **mp1;
++*mp1;
}
res << endl;
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> b(ss);
boost::scoped_ptr<fixed_multi_pass_t> mp2(new fixed_multi_pass_t(b));
boost::scoped_ptr<fixed_multi_pass_t> mp3(new fixed_multi_pass_t(*mp2));
for (int i = 0; i < 4; ++i)
{
res << **mp2;
++*mp2;
}
mp3.reset();
++*mp2;
while (*mp2 != *mpend)
{
res << **mp2;
++*mp2;
}
res << endl;
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> a(ss);
boost::scoped_ptr<fixed_multi_pass_t> mp1(new fixed_multi_pass_t(a));
boost::scoped_ptr<fixed_multi_pass_t> mp2(new fixed_multi_pass_t(*mp1));
BOOST_TEST(*mp1 == *mp2);
BOOST_TEST(*mp1 >= *mp2);
BOOST_TEST(*mp1 <= *mp2);
for (int i = 0; i < 4; ++i)
{
res << **mp1;
++*mp1;
}
BOOST_TEST(*mp1 != *mp2);
BOOST_TEST(*mp1 > *mp2);
BOOST_TEST(*mp1 >= *mp2);
BOOST_TEST(*mp2 < *mp1);
BOOST_TEST(*mp2 <= *mp1);
while (*mp2 != *mp1)
{
res << **mp2;
++*mp2;
}
BOOST_TEST(*mp1 == *mp2);
BOOST_TEST(*mp1 >= *mp2);
BOOST_TEST(*mp1 <= *mp2);
while (*mp1 != *mpend)
{
res << **mp1;
++*mp1;
}
BOOST_TEST(*mp1 != *mp2);
BOOST_TEST(*mp1 > *mp2);
BOOST_TEST(*mp1 >= *mp2);
BOOST_TEST(*mp2 < *mp1);
BOOST_TEST(*mp2 <= *mp1);
while (*mp2 != *mpend)
{
res << **mp2;
++*mp2;
}
BOOST_TEST(*mp1 == *mp2);
BOOST_TEST(*mp1 >= *mp2);
BOOST_TEST(*mp1 <= *mp2);
res << endl;
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> a(ss);
boost::scoped_ptr<fixed_multi_pass_t> mp1(new fixed_multi_pass_t(a));
boost::scoped_ptr<fixed_multi_pass_t> mp2(new fixed_multi_pass_t(a));
BOOST_TEST(*mp1 != *mp2);
++*mp1;
BOOST_TEST(*mp1 != *mp2);
}
}
void test_first_owner_multi_pass()
{
res << "-*= test_first_owner_multi_pass =*-\n";
istream_iterator<char> end;
boost::scoped_ptr<first_owner_multi_pass_t> mpend(new first_owner_multi_pass_t(end));
{
sstream_t ss;
ss << "test string";
istream_iterator<char> a(ss);
boost::scoped_ptr<first_owner_multi_pass_t> mp1(new first_owner_multi_pass_t(a));
while (*mp1 != *mpend)
{
res << *((*mp1)++);
}
res << endl;
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> b(ss);
boost::scoped_ptr<first_owner_multi_pass_t> mp2(new first_owner_multi_pass_t(b));
boost::scoped_ptr<first_owner_multi_pass_t> mp3(new first_owner_multi_pass_t(*mp2));
for (int i = 0; i < 4; ++i)
{
res << **mp2;
++*mp2;
}
mp3.reset();
while (*mp2 != *mpend)
{
res << **mp2;
++*mp2;
}
res << endl;
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> a(ss);
boost::scoped_ptr<first_owner_multi_pass_t> mp1(new first_owner_multi_pass_t(a));
boost::scoped_ptr<first_owner_multi_pass_t> mp2(new first_owner_multi_pass_t(*mp1));
for (int i = 0; i < 4; ++i)
{
res << **mp1;
++*mp1;
}
while (*mp2 != *mpend)
{
res << **mp2;
++*mp2;
}
while (*mp1 != *mpend)
{
res << **mp1;
++*mp1;
}
res << endl;
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> b(ss);
boost::scoped_ptr<first_owner_multi_pass_t> mp2(new first_owner_multi_pass_t(b));
boost::scoped_ptr<first_owner_multi_pass_t> mp3(new first_owner_multi_pass_t(*mp2));
for (int i = 0; i < 4; ++i)
{
res << **mp2;
++*mp2;
}
mp3.reset();
++*mp2;
while (*mp2 != *mpend)
{
res << **mp2;
++*mp2;
}
res << endl;
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> a(ss);
boost::scoped_ptr<first_owner_multi_pass_t> mp1(new first_owner_multi_pass_t(a));
boost::scoped_ptr<first_owner_multi_pass_t> mp2(new first_owner_multi_pass_t(*mp1));
BOOST_TEST(*mp1 == *mp2);
BOOST_TEST(*mp1 >= *mp2);
BOOST_TEST(*mp1 <= *mp2);
for (int i = 0; i < 4; ++i)
{
res << **mp1;
++*mp1;
}
BOOST_TEST(*mp1 != *mp2);
BOOST_TEST(*mp1 > *mp2);
BOOST_TEST(*mp1 >= *mp2);
BOOST_TEST(*mp2 < *mp1);
BOOST_TEST(*mp2 <= *mp1);
while (*mp2 != *mp1)
{
res << **mp2;
++*mp2;
}
BOOST_TEST(*mp1 == *mp2);
BOOST_TEST(*mp1 >= *mp2);
BOOST_TEST(*mp1 <= *mp2);
while (*mp1 != *mpend)
{
res << **mp1;
++*mp1;
}
BOOST_TEST(*mp1 != *mp2);
BOOST_TEST(*mp1 > *mp2);
BOOST_TEST(*mp1 >= *mp2);
BOOST_TEST(*mp2 < *mp1);
BOOST_TEST(*mp2 <= *mp1);
while (*mp2 != *mpend)
{
res << **mp2;
++*mp2;
}
BOOST_TEST(*mp1 == *mp2);
BOOST_TEST(*mp1 >= *mp2);
BOOST_TEST(*mp1 <= *mp2);
res << endl;
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> a(ss);
boost::scoped_ptr<first_owner_multi_pass_t> mp1(new first_owner_multi_pass_t(a));
boost::scoped_ptr<first_owner_multi_pass_t> mp2(new first_owner_multi_pass_t(a));
BOOST_TEST(*mp1 != *mp2);
++*mp1;
BOOST_TEST(*mp1 != *mp2);
}
{
sstream_t ss;
ss << "test string";
istream_iterator<char> b(ss);
boost::scoped_ptr<first_owner_multi_pass_t> mp2(new first_owner_multi_pass_t(b));
boost::scoped_ptr<first_owner_multi_pass_t> mp3(new first_owner_multi_pass_t(*mp2));
for (int i = 0; i < 4; ++i)
{
res << **mp2;
++*mp2;
}
mp2->clear_queue();
while (*mp2 != *mpend)
{
res << **mp2;
++*mp2;
}
try
{
res << **mp3; // this should throw illegal_backtracking
BOOST_TEST(0);
}
catch (const BOOST_SPIRIT_CLASSIC_NS::multi_pass_policies::illegal_backtracking& /*e*/)
{
}
res << endl;
}
}
void test_functor_multi_pass()
{
res << "-*= test_functor_multi_pass =*-\n";
functor_multi_pass_t mpend;
{
functor_multi_pass_t mp1 = functor_multi_pass_t(my_functor());
while (mp1 != mpend)
{
res << *(mp1++);
}
res << endl;
}
{
functor_multi_pass_t mp1 = functor_multi_pass_t(my_functor());
functor_multi_pass_t mp2 = functor_multi_pass_t(mp1);
for (int i = 0; i < 4; ++i)
{
res << *mp1;
++mp1;
}
while (mp2 != mpend)
{
res << *mp2;
++mp2;
}
while (mp1 != mpend)
{
res << *mp1;
++mp1;
}
res << endl;
}
{
functor_multi_pass_t mp1 = functor_multi_pass_t(my_functor());
functor_multi_pass_t mp2 = functor_multi_pass_t(mp1);
BOOST_TEST(mp1 == mp2);
BOOST_TEST(mp1 >= mp2);
BOOST_TEST(mp1 <= mp2);
for (int i = 0; i < 4; ++i)
{
res << *mp1;
++mp1;
}
BOOST_TEST(mp1 != mp2);
BOOST_TEST(mp1 > mp2);
BOOST_TEST(mp1 >= mp2);
BOOST_TEST(mp2 < mp1);
BOOST_TEST(mp2 <= mp1);
while (mp2 != mp1)
{
res << *mp2;
++mp2;
}
BOOST_TEST(mp1 == mp2);
BOOST_TEST(mp1 >= mp2);
BOOST_TEST(mp1 <= mp2);
while (mp1 != mpend)
{
res << *mp1;
++mp1;
}
BOOST_TEST(mp1 != mp2);
BOOST_TEST(mp1 > mp2);
BOOST_TEST(mp1 >= mp2);
BOOST_TEST(mp2 < mp1);
BOOST_TEST(mp2 <= mp1);
while (mp2 != mpend)
{
res << *mp2;
++mp2;
}
BOOST_TEST(mp1 == mp2);
BOOST_TEST(mp1 >= mp2);
BOOST_TEST(mp1 <= mp2);
res << endl;
}
{
functor_multi_pass_t mp1 = functor_multi_pass_t(my_functor());
functor_multi_pass_t mp2 = functor_multi_pass_t(my_functor());
BOOST_TEST(mp1 != mp2);
++mp1;
BOOST_TEST(mp1 != mp2);
}
}
int main(int, char**)
{
test_default_multi_pass();
test_fixed_multi_pass();
test_first_owner_multi_pass();
test_functor_multi_pass();
BOOST_TEST(getstring(res) == "-*= test_default_multi_pass =*-\n"
"teststring\n"
"teststring\n"
"testteststringstring\n"
"testtring\n"
"testteststringstring\n"
"teststring\n"
"-*= test_fixed_multi_pass =*-\n"
"teststring\n"
"teststring\n"
"testteststringstring\n"
"testtring\n"
"testteststringstring\n"
"-*= test_first_owner_multi_pass =*-\n"
"teststring\n"
"teststring\n"
"testteststringstring\n"
"testtring\n"
"testteststringstring\n"
"teststring\n"
"-*= test_functor_multi_pass =*-\n"
"ABCDEFGHIJKL\n"
"ABCDABCDEFGHIJKLEFGHIJKL\n"
"ABCDABCDEFGHIJKLEFGHIJKL\n");
return boost::report_errors();
}