Merge Boost.Algorithm to release branch

[SVN r78025]
This commit is contained in:
Marshall Clow
2012-04-16 18:54:41 +00:00
parent 0f2399fef0
commit 76cd99ed53
71 changed files with 49915 additions and 0 deletions

49
test/Jamfile.v2 Normal file
View File

@ -0,0 +1,49 @@
# Boost algorithm library test suite Jamfile ----------------------------
#
# Copyright Marshall Clow 2010-2012. 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)
#
# See http://www.boost.org for updates, documentation, and revision history.
import testing ;
{
test-suite algorithm:
# Search tests
: [ run empty_search_test.cpp : : : : empty_search_test ]
[ run search_test1.cpp : : : : search_test1 ]
[ run search_test2.cpp : : : : search_test2 ]
[ run search_test3.cpp : : : : search_test3 ]
[ compile-fail search_fail1.cpp : : : : ]
[ compile-fail search_fail2.cpp : : : : ]
[ compile-fail search_fail3.cpp : : : : ]
# Clamp tests
[ run clamp_test.cpp : : : : clamp_test ]
# Cxx11 tests
[ run all_of_test.cpp : : : : all_of_test ]
[ run any_of_test.cpp : : : : any_of_test ]
[ run none_of_test.cpp : : : : none_of_test ]
[ run one_of_test.cpp : : : : one_of_test ]
[ run ordered_test.cpp : : : : ordered_test ]
[ run find_if_not_test1.cpp : : : : find_if_not_test1 ]
[ run copy_n_test1.cpp : : : : copy_n_test1 ]
[ run iota_test1.cpp : : : : iota_test1 ]
[ run is_permutation_test1.cpp : : : : is_permutation_test1 ]
[ run partition_point_test1.cpp : : : : partition_point_test1 ]
[ run is_partitioned_test1.cpp : : : : is_partitioned_test1 ]
[ run partition_copy_test1.cpp : : : : partition_copy_test1 ]
# Hex tests
[ run hex_test1.cpp : : : : hex_test1 ]
[ run hex_test2.cpp : : : : hex_test2 ]
[ run hex_test3.cpp : : : : hex_test3 ]
[ compile-fail hex_fail1.cpp ]
;
}

86
test/all_of_test.cpp Normal file
View File

@ -0,0 +1,86 @@
/*
Copyright (c) Marshall Clow 2010-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <boost/config.hpp>
#include <boost/algorithm/cxx11/all_of.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <functional>
#include <vector>
#include <list>
template<typename T>
struct is_ : public std::unary_function<T, bool> {
is_ ( T v ) : val_ ( v ) {}
~is_ () {}
bool operator () ( T comp ) const { return val_ == comp; }
private:
is_ (); // need a value
T val_;
};
namespace ba = boost::algorithm;
void test_all ()
{
// Note: The literal values here are tested against directly, careful if you change them:
int some_numbers[] = { 1, 1, 1, 18, 10 };
std::vector<int> vi(some_numbers, some_numbers + 5);
std::list<int> li(vi.begin(), vi.end ());
int some_letters[] = { 'a', 'q', 'n', 'y', 'n' };
std::vector<char> vc(some_letters, some_letters + 5);
BOOST_CHECK (!ba::all_of_equal ( vi, 1 ));
BOOST_CHECK (!ba::all_of ( vi, is_<int> ( 1 )));
BOOST_CHECK (!ba::all_of_equal ( vi.begin(), vi.end(), 1 ));
BOOST_CHECK (!ba::all_of ( vi.begin(), vi.end(), is_<int> ( 1 )));
BOOST_CHECK (!ba::all_of_equal ( vi, 0 ));
BOOST_CHECK (!ba::all_of ( vi, is_<int> ( 0 )));
BOOST_CHECK (!ba::all_of_equal ( vi.begin(), vi.end(), 0 ));
BOOST_CHECK (!ba::all_of ( vi.begin(), vi.end(), is_<int> ( 0 )));
BOOST_CHECK ( ba::all_of_equal ( vi.end(), vi.end(), 0 ));
BOOST_CHECK ( ba::all_of ( vi.end(), vi.end(), is_<int> ( 0 )));
BOOST_CHECK ( ba::all_of_equal ( vi.begin(), vi.begin () + 3, 1 ));
BOOST_CHECK ( ba::all_of ( vi.begin(), vi.begin () + 3, is_<int> ( 1 )));
BOOST_CHECK ( ba::all_of_equal ( vc.begin() + 1, vc.begin() + 2, 'q' ));
BOOST_CHECK ( ba::all_of ( vc.begin() + 1, vc.begin() + 2, is_<char> ( 'q' )));
BOOST_CHECK (!ba::all_of_equal ( vc, '!' ));
BOOST_CHECK (!ba::all_of ( vc, is_<char> ( '!' )));
BOOST_CHECK ( ba::all_of_equal ( vi.begin(), vi.begin(), 1 ));
BOOST_CHECK ( ba::all_of_equal ( vc.begin(), vc.begin(), 'a' ));
BOOST_CHECK ( ba::all_of ( vi.begin(), vi.begin(), is_<int> ( 1 )));
BOOST_CHECK ( ba::all_of ( vc.begin(), vc.begin(), is_<char> ( 'a' )));
BOOST_CHECK (!ba::all_of_equal ( li, 1 ));
BOOST_CHECK (!ba::all_of ( li, is_<int> ( 1 )));
BOOST_CHECK (!ba::all_of_equal ( li.begin(), li.end(), 1 ));
BOOST_CHECK (!ba::all_of ( li.begin(), li.end(), is_<int> ( 1 )));
std::list<int>::iterator l_iter = li.begin ();
l_iter++; l_iter++; l_iter++;
BOOST_CHECK ( ba::all_of_equal ( li.begin(), l_iter, 1 ));
BOOST_CHECK ( ba::all_of ( li.begin(), l_iter, is_<int> ( 1 )));
}
int test_main( int , char* [] )
{
test_all ();
return 0;
}

105
test/any_of_test.cpp Normal file
View File

@ -0,0 +1,105 @@
/*
Copyright (c) Marshall Clow 2010-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <boost/config.hpp>
#include <boost/algorithm/cxx11/any_of.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <functional>
#include <vector>
#include <list>
template<typename T>
struct is_ : public std::unary_function<T, bool> {
is_ ( T v ) : val_ ( v ) {}
~is_ () {}
bool operator () ( T comp ) const { return val_ == comp; }
private:
is_ (); // need a value
T val_;
};
namespace ba = boost::algorithm;
void test_any ()
{
// Note: The literal values here are tested against directly, careful if you change them:
int some_numbers[] = { 1, 5, 0, 18, 10 };
std::vector<int> vi(some_numbers, some_numbers + 5);
std::list<int> li(vi.begin(), vi.end ());
int some_letters[] = { 'a', 'q', 'n', 'y', 'n' };
std::vector<char> vc(some_letters, some_letters + 5);
BOOST_CHECK ( ba::any_of_equal ( vi, 1 ));
BOOST_CHECK ( ba::any_of ( vi, is_<int> ( 1 )));
BOOST_CHECK ( ba::any_of_equal ( vi.begin(), vi.end(), 1 ));
BOOST_CHECK ( ba::any_of ( vi.begin(), vi.end(), is_<int> ( 1 )));
BOOST_CHECK (!ba::any_of_equal ( vi, 9 ));
BOOST_CHECK (!ba::any_of ( vi, is_<int> ( 9 )));
BOOST_CHECK (!ba::any_of_equal ( vi.begin(), vi.end(), 9 ));
BOOST_CHECK (!ba::any_of ( vi.begin(), vi.end(), is_<int> ( 9 )));
BOOST_CHECK ( ba::any_of_equal ( vi, 10 ));
BOOST_CHECK ( ba::any_of ( vi, is_<int> ( 10 )));
BOOST_CHECK (!ba::any_of_equal ( vi, 4 ));
BOOST_CHECK (!ba::any_of ( vi, is_<int> ( 4 )));
BOOST_CHECK (!ba::any_of_equal ( vi.end(), vi.end(), 0 ));
BOOST_CHECK (!ba::any_of ( vi.end(), vi.end(), is_<int> ( 0 )));
// 5 is not in { 0, 18, 10 }, but 10 is
BOOST_CHECK ( ba::any_of_equal ( vi.begin() + 2, vi.end(), 10 ));
BOOST_CHECK ( ba::any_of ( vi.begin() + 2, vi.end(), is_<int> ( 10 )));
BOOST_CHECK (!ba::any_of_equal ( vi.begin() + 2, vi.end(), 5 ));
BOOST_CHECK (!ba::any_of ( vi.begin() + 2, vi.end(), is_<int> ( 5 )));
// 18 is not in { 1, 5, 0 }, but 5 is
BOOST_CHECK ( ba::any_of_equal ( vi.begin(), vi.begin() + 3, 5 ));
BOOST_CHECK ( ba::any_of ( vi.begin(), vi.begin() + 3, is_<int> ( 5 )));
BOOST_CHECK (!ba::any_of_equal ( vi.begin(), vi.begin() + 3, 18 ));
BOOST_CHECK (!ba::any_of ( vi.begin(), vi.begin() + 3, is_<int> ( 18 )));
BOOST_CHECK ( ba::any_of_equal ( vc, 'q' ));
BOOST_CHECK ( ba::any_of ( vc, is_<char> ( 'q' )));
BOOST_CHECK (!ba::any_of_equal ( vc, '!' ));
BOOST_CHECK (!ba::any_of ( vc, is_<char> ( '!' )));
BOOST_CHECK ( ba::any_of_equal ( vc, 'n' ));
BOOST_CHECK ( ba::any_of ( vc, is_<char> ( 'n' )));
BOOST_CHECK (!ba::any_of_equal ( vi.begin(), vi.begin(), 1 ));
BOOST_CHECK (!ba::any_of_equal ( vc.begin(), vc.begin(), 'a' ));
BOOST_CHECK (!ba::any_of ( vi.begin(), vi.begin(), is_<int> ( 1 )));
BOOST_CHECK (!ba::any_of ( vc.begin(), vc.begin(), is_<char> ( 'a' )));
BOOST_CHECK ( ba::any_of_equal ( li, 1 ));
BOOST_CHECK ( ba::any_of ( li, is_<int> ( 1 )));
BOOST_CHECK ( ba::any_of_equal ( li.begin(), li.end(), 1 ));
BOOST_CHECK ( ba::any_of ( li.begin(), li.end(), is_<int> ( 1 )));
std::list<int>::iterator l_iter = li.begin ();
l_iter++; l_iter++; l_iter++;
BOOST_CHECK ( ba::any_of_equal ( li.begin(), l_iter, 5 ));
BOOST_CHECK ( ba::any_of ( li.begin(), l_iter, is_<int> ( 5 )));
BOOST_CHECK (!ba::any_of_equal ( li.begin(), l_iter, 18 ));
BOOST_CHECK (!ba::any_of ( li.begin(), l_iter, is_<int> ( 18 )));
}
int test_main( int , char* [] )
{
test_any ();
return 0;
}

218
test/clamp_test.cpp Normal file
View File

@ -0,0 +1,218 @@
// (C) Copyright Jesse Williamson 2009
// Use, modification and distribution are 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 <iostream>
#include <vector>
#include <boost/config.hpp>
#include <boost/algorithm/clamp.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
namespace ba = boost::algorithm;
bool intGreater ( int lhs, int rhs ) { return lhs > rhs; }
bool doubleGreater ( double lhs, double rhs ) { return lhs > rhs; }
class custom {
public:
custom ( int x ) : v(x) {}
custom ( const custom &rhs ) : v(rhs.v) {}
~custom () {}
custom & operator = ( const custom &rhs ) { v = rhs.v; return *this; }
bool operator < ( const custom &rhs ) const { return v < rhs.v; }
bool operator == ( const custom &rhs ) const { return v == rhs.v; } // need this for the test
std::ostream & print ( std::ostream &os ) const { return os << v; }
int v;
};
std::ostream & operator << ( std::ostream & os, const custom &x ) { return x.print ( os ); }
bool customLess ( const custom &lhs, const custom &rhs ) { return lhs.v < rhs.v; }
void test_ints()
{
// Inside the range, equal to the endpoints, and outside the endpoints.
BOOST_CHECK_EQUAL ( 3, ba::clamp ( 3, 1, 10 ));
BOOST_CHECK_EQUAL ( 1, ba::clamp ( 1, 1, 10 ));
BOOST_CHECK_EQUAL ( 1, ba::clamp ( 0, 1, 10 ));
BOOST_CHECK_EQUAL ( 10, ba::clamp ( 10, 1, 10 ));
BOOST_CHECK_EQUAL ( 10, ba::clamp ( 11, 1, 10 ));
BOOST_CHECK_EQUAL ( 3, ba::clamp ( 3, 10, 1, intGreater ));
BOOST_CHECK_EQUAL ( 1, ba::clamp ( 1, 10, 1, intGreater ));
BOOST_CHECK_EQUAL ( 1, ba::clamp ( 0, 10, 1, intGreater ));
BOOST_CHECK_EQUAL ( 10, ba::clamp ( 10, 10, 1, intGreater ));
BOOST_CHECK_EQUAL ( 10, ba::clamp ( 11, 10, 1, intGreater ));
// Negative numbers
BOOST_CHECK_EQUAL ( -3, ba::clamp ( -3, -10, -1 ));
BOOST_CHECK_EQUAL ( -1, ba::clamp ( -1, -10, -1 ));
BOOST_CHECK_EQUAL ( -1, ba::clamp ( 0, -10, -1 ));
BOOST_CHECK_EQUAL ( -10, ba::clamp ( -10, -10, -1 ));
BOOST_CHECK_EQUAL ( -10, ba::clamp ( -11, -10, -1 ));
// Mixed positive and negative numbers
BOOST_CHECK_EQUAL ( 5, ba::clamp ( 5, -10, 10 ));
BOOST_CHECK_EQUAL ( -10, ba::clamp ( -10, -10, 10 ));
BOOST_CHECK_EQUAL ( -10, ba::clamp ( -15, -10, 10 ));
BOOST_CHECK_EQUAL ( 10, ba::clamp ( 10, -10, 10 ));
BOOST_CHECK_EQUAL ( 10, ba::clamp ( 15, -10, 10 ));
// Unsigned
BOOST_CHECK_EQUAL ( 5U, ba::clamp ( 5U, 1U, 10U ));
BOOST_CHECK_EQUAL ( 1U, ba::clamp ( 1U, 1U, 10U ));
BOOST_CHECK_EQUAL ( 1U, ba::clamp ( 0U, 1U, 10U ));
BOOST_CHECK_EQUAL ( 10U, ba::clamp ( 10U, 1U, 10U ));
BOOST_CHECK_EQUAL ( 10U, ba::clamp ( 15U, 1U, 10U ));
// Mixed (1)
BOOST_CHECK_EQUAL ( 5U, ba::clamp ( 5U, 1, 10 ));
BOOST_CHECK_EQUAL ( 1U, ba::clamp ( 1U, 1, 10 ));
BOOST_CHECK_EQUAL ( 1U, ba::clamp ( 0U, 1, 10 ));
BOOST_CHECK_EQUAL ( 10U, ba::clamp ( 10U, 1, 10 ));
BOOST_CHECK_EQUAL ( 10U, ba::clamp ( 15U, 1, 10 ));
// Mixed (3)
BOOST_CHECK_EQUAL ( 5U, ba::clamp ( 5U, 1, 10. ));
BOOST_CHECK_EQUAL ( 1U, ba::clamp ( 1U, 1, 10. ));
BOOST_CHECK_EQUAL ( 1U, ba::clamp ( 0U, 1, 10. ));
BOOST_CHECK_EQUAL ( 10U, ba::clamp ( 10U, 1, 10. ));
BOOST_CHECK_EQUAL ( 10U, ba::clamp ( 15U, 1, 10. ));
short foo = 50;
BOOST_CHECK_EQUAL ( 56, ba::clamp ( foo, 56.9, 129 ));
BOOST_CHECK_EQUAL ( 24910, ba::clamp ( foo, 12345678, 123456999 ));
}
void test_floats()
{
// Inside the range, equal to the endpoints, and outside the endpoints.
BOOST_CHECK_EQUAL ( 3.0, ba::clamp ( 3.0, 1.0, 10.0 ));
BOOST_CHECK_EQUAL ( 1.0, ba::clamp ( 1.0, 1.0, 10.0 ));
BOOST_CHECK_EQUAL ( 1.0, ba::clamp ( 0.0, 1.0, 10.0 ));
BOOST_CHECK_EQUAL ( 10.0, ba::clamp ( 10.0, 1.0, 10.0 ));
BOOST_CHECK_EQUAL ( 10.0, ba::clamp ( 11.0, 1.0, 10.0 ));
BOOST_CHECK_EQUAL ( 3.0, ba::clamp ( 3.0, 10.0, 1.0, doubleGreater ));
BOOST_CHECK_EQUAL ( 1.0, ba::clamp ( 1.0, 10.0, 1.0, doubleGreater ));
BOOST_CHECK_EQUAL ( 1.0, ba::clamp ( 0.0, 10.0, 1.0, doubleGreater ));
BOOST_CHECK_EQUAL ( 10.0, ba::clamp ( 10.0, 10.0, 1.0, doubleGreater ));
BOOST_CHECK_EQUAL ( 10.0, ba::clamp ( 11.0, 10.0, 1.0, doubleGreater ));
// Negative numbers
BOOST_CHECK_EQUAL ( -3.f, ba::clamp ( -3.f, -10.f, -1.f ));
BOOST_CHECK_EQUAL ( -1.f, ba::clamp ( -1.f, -10.f, -1.f ));
BOOST_CHECK_EQUAL ( -1.f, ba::clamp ( 0.f, -10.f, -1.f ));
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -10.f, -10.f, -1.f ));
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -11.f, -10.f, -1.f ));
// Mixed positive and negative numbers
BOOST_CHECK_EQUAL ( 5.f, ba::clamp ( 5.f, -10.f, 10.f ));
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -10.f, -10.f, 10.f ));
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -15.f, -10.f, 10.f ));
BOOST_CHECK_EQUAL ( 10.f, ba::clamp ( 10.f, -10.f, 10.f ));
BOOST_CHECK_EQUAL ( 10.f, ba::clamp ( 15.f, -10.f, 10.f ));
// Mixed (1)
BOOST_CHECK_EQUAL ( 5.f, ba::clamp ( 5.f, -10., 10. ));
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -10.f, -10., 10. ));
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -15.f, -10., 10. ));
BOOST_CHECK_EQUAL ( 10.f, ba::clamp ( 10.f, -10., 10. ));
BOOST_CHECK_EQUAL ( 10.f, ba::clamp ( 15.f, -10., 10. ));
// Mixed (2)
BOOST_CHECK_EQUAL ( 5.f, ba::clamp ( 5.f, -10, 10 ));
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -10.f, -10, 10 ));
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -15.f, -10, 10 ));
BOOST_CHECK_EQUAL ( 10.f, ba::clamp ( 10.f, -10, 10 ));
BOOST_CHECK_EQUAL ( 10.f, ba::clamp ( 15.f, -10, 10 ));
}
void test_custom()
{
// Inside the range, equal to the endpoints, and outside the endpoints.
BOOST_CHECK_EQUAL ( custom( 3), ba::clamp ( custom( 3), custom(1), custom(10)));
BOOST_CHECK_EQUAL ( custom( 1), ba::clamp ( custom( 1), custom(1), custom(10)));
BOOST_CHECK_EQUAL ( custom( 1), ba::clamp ( custom( 0), custom(1), custom(10)));
BOOST_CHECK_EQUAL ( custom(10), ba::clamp ( custom(10), custom(1), custom(10)));
BOOST_CHECK_EQUAL ( custom(10), ba::clamp ( custom(11), custom(1), custom(10)));
BOOST_CHECK_EQUAL ( custom( 3), ba::clamp ( custom( 3), custom(1), custom(10), customLess ));
BOOST_CHECK_EQUAL ( custom( 1), ba::clamp ( custom( 1), custom(1), custom(10), customLess ));
BOOST_CHECK_EQUAL ( custom( 1), ba::clamp ( custom( 0), custom(1), custom(10), customLess ));
BOOST_CHECK_EQUAL ( custom(10), ba::clamp ( custom(10), custom(1), custom(10), customLess ));
BOOST_CHECK_EQUAL ( custom(10), ba::clamp ( custom(11), custom(1), custom(10), customLess ));
// Fail!!
// BOOST_CHECK_EQUAL ( custom(1), ba::clamp ( custom(11), custom(1), custom(10)));
}
#define elementsof(v) (sizeof (v) / sizeof (v[0]))
#define a_begin(v) (&v[0])
#define a_end(v) (v + elementsof (v))
#define a_range(v) v
#define b_e(v) a_begin(v),a_end(v)
void test_int_range ()
{
int inputs [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 19, 99, 999, -1, -3, -99, 234234 };
int outputs [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, -1, -1, -1, 10 };
std::vector<int> results;
std::vector<int> in_v;
std::copy ( a_begin(inputs), a_end(inputs), std::back_inserter ( in_v ));
ba::clamp_range ( a_begin(inputs), a_end(inputs), std::back_inserter ( results ), -1, 10 );
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
results.clear ();
ba::clamp_range ( in_v.begin (), in_v.end (), std::back_inserter ( results ), -1, 10 );
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
results.clear ();
ba::clamp_range ( a_begin(inputs), a_end(inputs), std::back_inserter ( results ), 10, -1, intGreater );
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
results.clear ();
ba::clamp_range ( in_v.begin (), in_v.end (), std::back_inserter ( results ), 10, -1, intGreater );
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
results.clear ();
ba::clamp_range ( a_range(inputs), std::back_inserter ( results ), -1, 10 );
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
results.clear ();
ba::clamp_range ( in_v, std::back_inserter ( results ), -1, 10 );
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
results.clear ();
ba::clamp_range ( a_range(inputs), std::back_inserter ( results ), 10, -1, intGreater );
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
results.clear ();
ba::clamp_range ( in_v, std::back_inserter ( results ), 10, -1, intGreater );
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
results.clear ();
int junk[elementsof(inputs)];
ba::clamp_range ( inputs, junk, 10, -1, intGreater );
BOOST_CHECK ( std::equal ( b_e(junk), outputs ));
}
int test_main( int , char* [] )
{
test_ints ();
test_floats ();
test_custom ();
test_int_range ();
// test_float_range ();
// test_custom_range ();
return 0;
}

85
test/copy_n_test1.cpp Normal file
View File

@ -0,0 +1,85 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <boost/config.hpp>
#include <boost/algorithm/cxx11/copy_n.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <string>
#include <iostream>
#include <vector>
#include <list>
namespace ba = boost::algorithm;
// namespace ba = boost;
template <typename Container>
void test_sequence ( Container const &c ) {
typedef typename Container::value_type value_type;
std::vector<value_type> v;
// Copy zero elements
v.clear ();
ba::copy_n ( c.begin (), 0, back_inserter ( v ));
BOOST_CHECK ( v.size () == 0 );
ba::copy_n ( c.begin (), 0U, back_inserter ( v ));
BOOST_CHECK ( v.size () == 0 );
if ( c.size () > 0 ) {
// Just one element
v.clear ();
ba::copy_n ( c.begin (), 1, back_inserter ( v ));
BOOST_CHECK ( v.size () == 1 );
BOOST_CHECK ( v[0] == *c.begin ());
v.clear ();
ba::copy_n ( c.begin (), 1U, back_inserter ( v ));
BOOST_CHECK ( v.size () == 1 );
BOOST_CHECK ( v[0] == *c.begin ());
// Half the elements
v.clear ();
ba::copy_n ( c.begin (), c.size () / 2, back_inserter ( v ));
BOOST_CHECK ( v.size () == c.size () / 2);
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
// Half the elements + 1
v.clear ();
ba::copy_n ( c.begin (), c.size () / 2 + 1, back_inserter ( v ));
BOOST_CHECK ( v.size () == c.size () / 2 + 1 );
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
// All the elements
v.clear ();
ba::copy_n ( c.begin (), c.size (), back_inserter ( v ));
BOOST_CHECK ( v.size () == c.size ());
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
}
}
void test_sequence1 () {
std::vector<int> v;
for ( int i = 5; i < 15; ++i )
v.push_back ( i );
test_sequence ( v );
std::list<int> l;
for ( int i = 25; i > 15; --i )
l.push_back ( i );
test_sequence ( l );
}
int test_main( int , char* [] )
{
test_sequence1 ();
return 0;
}

View File

@ -0,0 +1,83 @@
/*
Copyright (c) Marshall Clow 2010-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <string>
#include <boost/algorithm/searching/boyer_moore.hpp>
#include <boost/algorithm/searching/boyer_moore_horspool.hpp>
#include <boost/algorithm/searching/knuth_morris_pratt.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
int test_main( int argc, char *argv [] )
{
const std::string cs;
std::string estr;
std::string str ( "abc" );
// empty corpus, empty pattern
BOOST_CHECK (
boost::algorithm::boyer_moore_search (
cs.begin (), cs.end (), estr.begin (), estr.end ())
== cs.begin ()
);
BOOST_CHECK (
boost::algorithm::boyer_moore_horspool_search (
cs.begin (), cs.end (), estr.begin (), estr.end ())
== cs.begin ()
);
BOOST_CHECK (
boost::algorithm::knuth_morris_pratt_search (
cs.begin (), cs.end (), estr.begin (), estr.end ())
== cs.begin ()
);
// empty corpus, non-empty pattern
BOOST_CHECK (
boost::algorithm::boyer_moore_search (
estr.begin (), estr.end (), str.begin (), str.end ())
== estr.end ()
);
BOOST_CHECK (
boost::algorithm::boyer_moore_horspool_search (
estr.begin (), estr.end (), str.begin (), str.end ())
== estr.end ()
);
BOOST_CHECK (
boost::algorithm::knuth_morris_pratt_search (
estr.begin (), estr.end (), str.begin (), str.end ())
== estr.end ()
);
// non-empty corpus, empty pattern
BOOST_CHECK (
boost::algorithm::boyer_moore_search (
str.begin (), str.end (), estr.begin (), estr.end ())
== str.begin ()
);
BOOST_CHECK (
boost::algorithm::boyer_moore_horspool_search (
str.begin (), str.end (), estr.begin (), estr.end ())
== str.begin ()
);
BOOST_CHECK (
boost::algorithm::knuth_morris_pratt_search (
str.begin (), str.end (), estr.begin (), estr.end ())
== str.begin ()
);
(void) argv; (void) argc;
return 0;
}

View File

@ -0,0 +1,90 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <iostream>
#include <boost/config.hpp>
#include <boost/algorithm/cxx11/find_if_not.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <string>
#include <vector>
#include <list>
namespace ba = boost::algorithm;
// namespace ba = boost;
template <typename Container>
typename Container::iterator offset_to_iter ( Container &v, int offset ) {
typename Container::iterator retval;
if ( offset >= 0 ) {
retval = v.begin ();
std::advance ( retval, offset );
}
else {
retval = v.end ();
std::advance ( retval, offset + 1 );
}
return retval;
}
template <typename Container, typename Predicate>
void test_sequence ( Container &v, Predicate comp, int expected ) {
typename Container::iterator res, exp;
res = ba::find_if_not ( v.begin (), v.end (), comp );
exp = offset_to_iter ( v, expected );
std::cout << "Expected(1): " << std::distance ( v.begin (), exp )
<< ", got: " << std::distance ( v.begin (), res ) << std::endl;
BOOST_CHECK ( exp == res );
}
template <typename T>
struct less_than {
public:
less_than ( T foo ) : val ( foo ) {}
less_than ( const less_than &rhs ) : val ( rhs.val ) {}
bool operator () ( const T &v ) const { return v < val; }
private:
less_than ();
less_than operator = ( const less_than &rhs );
T val;
};
void test_sequence1 () {
std::vector<int> v;
v.clear ();
for ( int i = 5; i < 15; ++i )
v.push_back ( i );
test_sequence ( v, less_than<int>(3), 0 ); // no elements
test_sequence ( v, less_than<int>(6), 1 ); // only the first element
test_sequence ( v, less_than<int>(10), 5 );
test_sequence ( v, less_than<int>(99), -1 ); // all elements satisfy
// With bidirectional iterators.
std::list<int> l;
for ( int i = 5; i < 15; ++i )
l.push_back ( i );
test_sequence ( l, less_than<int>(3), 0 ); // no elements
test_sequence ( l, less_than<int>(6), 1 ); // only the first element
test_sequence ( l, less_than<int>(10), 5 );
test_sequence ( l, less_than<int>(99), -1 ); // all elements satisfy
}
int test_main( int , char* [] )
{
test_sequence1 ();
return 0;
}

25
test/hex_fail1.cpp Normal file
View File

@ -0,0 +1,25 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <boost/config.hpp>
#include <boost/algorithm/hex.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <string>
#include <iostream>
#include <vector>
// should not compile: vector is not an integral type
int test_main( int , char* [] )
{
std::vector<float> v;
std::string out;
boost::algorithm::unhex ( out, std::back_inserter(v));
return 0;
}

154
test/hex_test1.cpp Normal file
View File

@ -0,0 +1,154 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <boost/config.hpp>
#include <boost/algorithm/hex.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <string>
#include <iostream>
template<typename String>
void test_to_hex ( const typename String::value_type ** tests ) {
for ( const typename String::value_type **p = tests; *p; p++ ) {
String arg, argh, one, two, three, four;
arg.assign ( *p );
boost::algorithm::hex ( *p, std::back_inserter ( one ));
boost::algorithm::hex ( arg, std::back_inserter ( two ));
boost::algorithm::hex ( arg.begin (), arg.end (), std::back_inserter ( three ));
four = boost::algorithm::hex ( arg );
BOOST_CHECK ( one == two );
BOOST_CHECK ( one == three );
BOOST_CHECK ( one == four );
argh = one;
one.clear (); two.clear (); three.clear (); four.clear ();
boost::algorithm::unhex ( argh.c_str (), std::back_inserter ( one ));
boost::algorithm::unhex ( argh, std::back_inserter ( two ));
boost::algorithm::unhex ( argh.begin (), argh.end (), std::back_inserter ( three ));
four = boost::algorithm::unhex ( argh );
BOOST_CHECK ( one == two );
BOOST_CHECK ( one == three );
BOOST_CHECK ( one == four );
BOOST_CHECK ( one == arg );
}
}
template<typename String>
void test_from_hex_success ( const typename String::value_type ** tests ) {
for ( const typename String::value_type **p = tests; *p; p++ ) {
String arg, argh, one, two, three, four;
arg.assign ( *p );
boost::algorithm::unhex ( *p, std::back_inserter ( one ));
boost::algorithm::unhex ( arg, std::back_inserter ( two ));
boost::algorithm::unhex ( arg.begin (), arg.end (), std::back_inserter ( three ));
four = boost::algorithm::unhex ( arg );
BOOST_CHECK ( one == two );
BOOST_CHECK ( one == three );
BOOST_CHECK ( one == four );
argh = one;
one.clear (); two.clear (); three.clear (); four.clear ();
boost::algorithm::hex ( argh.c_str (), std::back_inserter ( one ));
boost::algorithm::hex ( argh, std::back_inserter ( two ));
boost::algorithm::hex ( argh.begin (), argh.end (), std::back_inserter ( three ));
four = boost::algorithm::hex ( argh );
BOOST_CHECK ( one == two );
BOOST_CHECK ( one == three );
BOOST_CHECK ( one == four );
BOOST_CHECK ( one == arg );
}
}
template<typename String>
void test_from_hex_failure ( const typename String::value_type ** tests ) {
int num_catches;
for ( const typename String::value_type **p = tests; *p; p++ ) {
String arg, one;
arg.assign ( *p );
num_catches = 0;
try { boost::algorithm::unhex ( *p, std::back_inserter ( one )); }
catch ( const boost::algorithm::hex_decode_error & /*ex*/ ) { num_catches++; }
try { boost::algorithm::unhex ( arg, std::back_inserter ( one )); }
catch ( const boost::algorithm::hex_decode_error & /*ex*/ ) { num_catches++; }
try { boost::algorithm::unhex ( arg.begin (), arg.end (), std::back_inserter ( one )); }
catch ( const boost::algorithm::hex_decode_error & /*ex*/ ) { num_catches++; }
BOOST_CHECK ( num_catches == 3 );
}
}
const char *tohex [] = {
"",
"a",
"\001",
"12",
"asdfadsfsad",
"01234567890ABCDEF",
NULL // End of the list
};
const wchar_t *tohex_w [] = {
L"",
L"a",
L"\001",
L"12",
L"asdfadsfsad",
L"01234567890ABCDEF",
NULL // End of the list
};
const char *fromhex [] = {
"20",
"2122234556FF",
NULL // End of the list
};
const wchar_t *fromhex_w [] = {
L"00101020",
L"2122234556FF3456",
NULL // End of the list
};
const char *fromhex_fail [] = {
"2",
"H",
"234",
"21222G4556FF",
NULL // End of the list
};
const wchar_t *fromhex_fail_w [] = {
L"2",
L"12",
L"H",
L"234",
L"21222G4556FF",
NULL // End of the list
};
int test_main( int , char* [] )
{
test_to_hex<std::string> ( tohex );
test_from_hex_success<std::string> ( fromhex );
test_from_hex_failure<std::string> ( fromhex_fail );
test_to_hex<std::wstring> ( tohex_w );
test_from_hex_success<std::wstring> ( fromhex_w );
test_from_hex_failure<std::wstring> ( fromhex_fail_w );
return 0;
}

137
test/hex_test2.cpp Normal file
View File

@ -0,0 +1,137 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under 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)
For more information, see http://www.boost.org
Test non-string cases; vector and list
*/
#include <boost/config.hpp>
#include <boost/algorithm/hex.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <string>
#include <iostream>
#include <deque>
#include <list>
const char *tohex [] = {
"",
"a",
"\001",
"12",
"asdfadsfsad",
"01234567890ABCDEF",
NULL // End of the list
};
void test_to_hex () {
for ( const char **p = tohex; *p; p++ ) {
std::deque<char> arg, argh;
std::list<char> one, two, three;
arg.assign ( *p, *p + strlen (*p));
boost::algorithm::hex ( *p, std::back_inserter ( one ));
boost::algorithm::hex ( arg, std::back_inserter ( two ));
boost::algorithm::hex ( arg.begin (), arg.end (), std::back_inserter ( three ));
BOOST_CHECK ( std::equal ( one.begin (), one.end (), two.begin ()));
BOOST_CHECK ( std::equal ( two.begin (), two.end (), three.begin ()));
std::copy ( one.begin (), one.end (), std::back_inserter ( argh ));
one.clear (); two.clear (); three.clear ();
// boost::algorithm::unhex ( argh.c_str (), std::back_inserter ( one ));
boost::algorithm::unhex ( argh, std::back_inserter ( two ));
boost::algorithm::unhex ( argh.begin (), argh.end (), std::back_inserter ( three ));
// BOOST_CHECK ( std::equal ( one.begin (), one.end (), two.begin ()));
BOOST_CHECK ( std::equal ( two.begin (), two.end (), three.begin ()));
BOOST_CHECK ( std::equal ( two.begin (), two.end (), arg.begin ()));
}
// Again, with a front_inserter
for ( const char **p = tohex; *p; p++ ) {
std::deque<char> arg, argh;
std::list<char> one, two, three;
arg.assign ( *p, *p + strlen (*p));
boost::algorithm::hex ( *p, std::front_inserter ( one ));
boost::algorithm::hex ( arg, std::front_inserter ( two ));
boost::algorithm::hex ( arg.begin (), arg.end (), std::front_inserter ( three ));
BOOST_CHECK ( std::equal ( one.begin (), one.end (), two.begin ()));
BOOST_CHECK ( std::equal ( two.begin (), two.end (), three.begin ()));
// Copy, reversing
std::copy ( one.begin (), one.end (), std::front_inserter ( argh ));
one.clear (); two.clear (); three.clear ();
// boost::algorithm::unhex ( argh.c_str (), std::front_inserter ( one ));
boost::algorithm::unhex ( argh, std::front_inserter ( two ));
boost::algorithm::unhex ( argh.begin (), argh.end (), std::front_inserter ( three ));
// BOOST_CHECK ( std::equal ( one.begin (), one.end (), two.begin ()));
BOOST_CHECK ( std::equal ( two.begin (), two.end (), three.begin ()));
BOOST_CHECK ( std::equal ( two.begin (), two.end (), arg.rbegin ())); // reverse
}
}
const char *fromhex [] = {
"20",
"2122234556FF",
NULL // End of the list
};
void test_from_hex_success () {
for ( const char **p = fromhex; *p; p++ ) {
std::deque<char> arg, argh;
std::list<char> one, two, three;
arg.assign ( *p, *p + strlen (*p));
boost::algorithm::unhex ( *p, std::back_inserter ( one ));
boost::algorithm::unhex ( arg, std::back_inserter ( two ));
boost::algorithm::unhex ( arg.begin (), arg.end (), std::back_inserter ( three ));
BOOST_CHECK ( std::equal ( one.begin (), one.end (), two.begin ()));
BOOST_CHECK ( std::equal ( two.begin (), two.end (), three.begin ()));
std::copy ( one.begin (), one.end (), std::back_inserter ( argh ));
one.clear (); two.clear (); three.clear ();
// boost::algorithm::hex ( argh.c_str (), std::back_inserter ( one ));
boost::algorithm::hex ( argh, std::back_inserter ( two ));
boost::algorithm::hex ( argh.begin (), argh.end (), std::back_inserter ( three ));
// BOOST_CHECK ( std::equal ( one.begin (), one.end (), two.begin ()));
BOOST_CHECK ( std::equal ( two.begin (), two.end (), three.begin ()));
BOOST_CHECK ( std::equal ( two.begin (), two.end (), arg.begin ()));
}
// Again, with a front_inserter
for ( const char **p = fromhex; *p; p++ ) {
std::deque<char> arg, argh;
std::list<char> one, two, three;
arg.assign ( *p, *p + strlen (*p));
boost::algorithm::unhex ( *p, std::front_inserter ( one ));
boost::algorithm::unhex ( arg, std::front_inserter ( two ));
boost::algorithm::unhex ( arg.begin (), arg.end (), std::front_inserter ( three ));
BOOST_CHECK ( std::equal ( one.begin (), one.end (), two.begin ()));
BOOST_CHECK ( std::equal ( two.begin (), two.end (), three.begin ()));
// Copy, reversing
std::copy ( one.begin (), one.end (), std::front_inserter ( argh ));
one.clear (); two.clear (); three.clear ();
// boost::algorithm::hex ( argh.c_str (), std::front_inserter ( one ));
boost::algorithm::hex ( argh, std::front_inserter ( two ));
boost::algorithm::hex ( argh.begin (), argh.end (), std::front_inserter ( three ));
// BOOST_CHECK ( std::equal ( one.begin (), one.end (), two.begin ()));
BOOST_CHECK ( std::equal ( two.begin (), two.end (), three.begin ()));
BOOST_CHECK ( std::equal ( two.begin (), two.end (), arg.rbegin ())); // reversed
}
}
int test_main( int , char* [] )
{
test_to_hex ();
test_from_hex_success ();
return 0;
}

123
test/hex_test3.cpp Normal file
View File

@ -0,0 +1,123 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under 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)
For more information, see http://www.boost.org
Try ostream_iterators
*/
#include <boost/config.hpp>
#include <boost/algorithm/hex.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <string>
#include <iostream>
#include <deque>
#include <list>
template <typename char_type>
void test_to_hex ( const char_type ** tests ) {
typedef std::basic_string<char_type> String;
typedef std::basic_ostringstream<char_type> Stream;
typedef std::ostream_iterator<char_type, char_type> Iter;
for ( const char_type **p = tests; *p; p++ ) {
String arg, argh;
Stream one, two, three;
arg.assign ( *p );
boost::algorithm::hex ( *p, Iter ( one ));
boost::algorithm::hex ( arg, Iter ( two ));
boost::algorithm::hex ( arg.begin (), arg.end (), Iter ( three ));
boost::algorithm::hex ( arg );
BOOST_CHECK ( one.str () == two.str ());
BOOST_CHECK ( one.str () == three.str ());
argh = one.str ();
one.str (String()); two.str (String()); three.str (String());
boost::algorithm::unhex ( argh.c_str (), Iter ( one ));
boost::algorithm::unhex ( argh, Iter ( two ));
boost::algorithm::unhex ( argh.begin (), argh.end (), Iter ( three ));
BOOST_CHECK ( one.str () == two.str ());
BOOST_CHECK ( one.str () == three.str ());
BOOST_CHECK ( one.str () == arg );
}
}
template <typename char_type>
void test_from_hex_success ( const char_type ** tests ) {
typedef std::basic_string<char_type> String;
typedef std::basic_ostringstream<char_type> Stream;
typedef std::ostream_iterator<char_type, char_type> Iter;
for ( const char_type **p = tests; *p; p++ ) {
String arg, argh;
Stream one, two, three;
arg.assign ( *p );
boost::algorithm::unhex ( *p, Iter ( one ));
boost::algorithm::unhex ( arg, Iter ( two ));
boost::algorithm::unhex ( arg.begin (), arg.end (), Iter ( three ));
BOOST_CHECK ( one.str () == two.str ());
BOOST_CHECK ( one.str () == three.str ());
argh = one.str ();
one.str (String()); two.str (String()); three.str (String());
boost::algorithm::hex ( argh.c_str (), Iter ( one ));
boost::algorithm::hex ( argh, Iter ( two ));
boost::algorithm::hex ( argh.begin (), argh.end (), Iter ( three ));
BOOST_CHECK ( one.str () == two.str ());
BOOST_CHECK ( one.str () == three.str ());
BOOST_CHECK ( one.str () == arg );
}
}
const char *tohex [] = {
"",
"a",
"\001",
"12",
"asdfadsfsad",
"01234567890ABCDEF",
NULL // End of the list
};
const wchar_t *tohex_w [] = {
L"",
L"a",
L"\001",
L"12",
L"asdfadsfsad",
L"01234567890ABCDEF",
NULL // End of the list
};
const char *fromhex [] = {
"20",
"2122234556FF",
NULL // End of the list
};
const wchar_t *fromhex_w [] = {
L"11223320",
L"21222345010256FF",
NULL // End of the list
};
int test_main( int , char* [] )
{
test_to_hex ( tohex );
test_to_hex ( tohex_w );
test_from_hex_success ( fromhex );
test_from_hex_success ( fromhex_w );
return 0;
}

79
test/iota_test1.cpp Normal file
View File

@ -0,0 +1,79 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <boost/config.hpp>
#include <boost/algorithm/cxx11/iota.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <list>
// Test to make sure a sequence is "correctly formed"; i.e, ascending by one
template <typename Iterator, typename T>
bool test_iota_results ( Iterator first, Iterator last, T initial_value ) {
if ( first == last ) return true;
if ( initial_value != *first ) return false;
Iterator prev = first;
while ( ++first != last ) {
if (( *first - *prev ) != 1 )
return false;
prev = first;
}
return true;
}
template <typename Range, typename T>
bool test_iota_results ( const Range &r, T initial_value ) {
return test_iota_results (boost::begin (r), boost::end (r), initial_value );
}
void test_ints () {
std::vector<int> v;
std::list<int> l;
v.clear (); v.reserve ( 10 );
boost::algorithm::iota ( v.begin (), v.end (), 23 );
BOOST_CHECK ( test_iota_results ( v.begin (), v.end (), 23 ));
v.clear (); v.reserve ( 19 );
boost::algorithm::iota ( v, 18 );
BOOST_CHECK ( test_iota_results ( v, 18 ));
v.clear ();
boost::algorithm::iota_n ( std::back_inserter(v), 99, 20 );
BOOST_CHECK ( test_iota_results ( v, 99 ));
/*
l.clear (); l.reserve ( 5 );
boost::algorithm::iota ( l.begin (), l.end (), 123 );
BOOST_CHECK ( test_iota_results ( l.begin (), l.end (), 123 ));
l.clear (); l.reserve ( 9 );
boost::algorithm::iota ( l.begin (), l.end (), 87 );
BOOST_CHECK ( test_iota_results ( l.begin (), l.end (), 87 ));
*/
l.clear ();
boost::algorithm::iota_n ( std::back_inserter(l), 99, 20 );
BOOST_CHECK ( test_iota_results ( l, 99 ));
l.clear ();
boost::algorithm::iota_n ( std::front_inserter(l), 123, 20 );
BOOST_CHECK ( test_iota_results ( l.rbegin (), l.rend (), 123 ));
}
int test_main( int , char* [] )
{
test_ints ();
return 0;
}

View File

@ -0,0 +1,63 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <iostream>
#include <boost/config.hpp>
#include <boost/algorithm/cxx11/is_partitioned.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <string>
#include <vector>
#include <list>
namespace ba = boost::algorithm;
// namespace ba = boost;
template <typename T>
struct less_than {
public:
less_than ( T foo ) : val ( foo ) {}
less_than ( const less_than &rhs ) : val ( rhs.val ) {}
bool operator () ( const T &v ) const { return v < val; }
private:
less_than ();
less_than operator = ( const less_than &rhs );
T val;
};
void test_sequence1 () {
std::vector<int> v;
v.clear ();
for ( int i = 5; i < 15; ++i )
v.push_back ( i );
BOOST_CHECK ( ba::is_partitioned ( v, less_than<int>(3))); // no elements
BOOST_CHECK ( ba::is_partitioned ( v, less_than<int>(6))); // only the first element
BOOST_CHECK ( ba::is_partitioned ( v, less_than<int>(10))); // in the middle somewhere
BOOST_CHECK ( ba::is_partitioned ( v, less_than<int>(99))); // all elements satisfy
// With bidirectional iterators.
std::list<int> l;
for ( int i = 5; i < 15; ++i )
l.push_back ( i );
BOOST_CHECK ( ba::is_partitioned ( l.begin (), l.end (), less_than<int>(3))); // no elements
BOOST_CHECK ( ba::is_partitioned ( l.begin (), l.end (), less_than<int>(6))); // only the first element
BOOST_CHECK ( ba::is_partitioned ( l.begin (), l.end (), less_than<int>(10))); // in the middle somewhere
BOOST_CHECK ( ba::is_partitioned ( l.begin (), l.end (), less_than<int>(99))); // all elements satisfy
}
int test_main( int , char* [] )
{
test_sequence1 ();
return 0;
}

View File

@ -0,0 +1,49 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <iostream>
#include <boost/config.hpp>
#include <boost/algorithm/cxx11/is_permutation.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <string>
#include <vector>
#include <list>
namespace ba = boost::algorithm;
// namespace ba = boost;
void test_sequence1 () {
std::vector<int> v, v1;
v.clear ();
for ( std::size_t i = 5; i < 15; ++i )
v.push_back ( i );
v1 = v;
BOOST_CHECK ( ba::is_permutation ( v.begin (), v.end (), v.begin ())); // better be a permutation of itself!
BOOST_CHECK ( ba::is_permutation ( v.begin (), v.end (), v1.begin ()));
// With bidirectional iterators.
std::list<int> l;
std::copy ( v.begin (), v.end (), std::back_inserter ( l ));
BOOST_CHECK ( ba::is_permutation ( l.begin (), l.end (), l.begin ())); // better be a permutation of itself!
BOOST_CHECK ( ba::is_permutation ( l.begin (), l.end (), v1.begin ()));
for ( std::size_t i = 0; i < l.size (); ++i ) {
l.push_back ( *l.begin ()); l.pop_front (); // rotation
BOOST_CHECK ( ba::is_permutation ( l.begin (), l.end (), v1.begin ()));
}
}
int test_main( int , char* [] )
{
test_sequence1 ();
return 0;
}

96
test/none_of_test.cpp Normal file
View File

@ -0,0 +1,96 @@
/*
Copyright (c) Marshall Clow 2010-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <boost/config.hpp>
#include <boost/algorithm/cxx11/none_of.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <functional>
#include <vector>
#include <list>
template<typename T>
struct is_ : public std::unary_function<T, bool> {
is_ ( T v ) : val_ ( v ) {}
~is_ () {}
bool operator () ( T comp ) const { return val_ == comp; }
private:
is_ (); // need a value
T val_;
};
namespace ba = boost::algorithm;
void test_none()
{
// Note: The literal values here are tested against directly, careful if you change them:
int some_numbers[] = { 1, 5, 0, 18, 1 };
std::vector<int> vi(some_numbers, some_numbers + 5);
std::list<int> li(vi.begin(), vi.end ());
int some_letters[] = { 'a', 'q', 'n', 'y', 'n' };
std::vector<char> vc(some_letters, some_letters + 5);
BOOST_CHECK ( ba::none_of_equal ( vi, 100 ));
BOOST_CHECK ( ba::none_of ( vi, is_<int> ( 100 )));
BOOST_CHECK ( ba::none_of_equal ( vi.begin(), vi.end(), 100 ));
BOOST_CHECK ( ba::none_of ( vi.begin(), vi.end(), is_<int> ( 100 )));
BOOST_CHECK (!ba::none_of_equal ( vi, 1 ));
BOOST_CHECK (!ba::none_of ( vi, is_<int> ( 1 )));
BOOST_CHECK (!ba::none_of_equal ( vi.begin(), vi.end(), 1 ));
BOOST_CHECK (!ba::none_of ( vi.begin(), vi.end(), is_<int> ( 1 )));
BOOST_CHECK ( ba::none_of_equal ( vi.end(), vi.end(), 0 ));
BOOST_CHECK ( ba::none_of ( vi.end(), vi.end(), is_<int> ( 0 )));
// 5 is not in { 0, 18, 1 }, but 1 is
BOOST_CHECK ( ba::none_of_equal ( vi.begin() + 2, vi.end(), 5 ));
BOOST_CHECK ( ba::none_of ( vi.begin() + 2, vi.end(), is_<int> ( 5 )));
BOOST_CHECK (!ba::none_of_equal ( vi.begin() + 2, vi.end(), 1 ));
BOOST_CHECK (!ba::none_of ( vi.begin() + 2, vi.end(), is_<int> ( 1 )));
// 18 is not in { 1, 5, 0 }, but 5 is
BOOST_CHECK ( ba::none_of_equal ( vi.begin(), vi.begin() + 3, 18 ));
BOOST_CHECK ( ba::none_of ( vi.begin(), vi.begin() + 3, is_<int> ( 18 )));
BOOST_CHECK (!ba::none_of_equal ( vi.begin(), vi.begin() + 3, 5 ));
BOOST_CHECK (!ba::none_of ( vi.begin(), vi.begin() + 3, is_<int> ( 5 )));
BOOST_CHECK ( ba::none_of_equal ( vc, 'z' ));
BOOST_CHECK ( ba::none_of ( vc, is_<char> ( 'z' )));
BOOST_CHECK (!ba::none_of_equal ( vc, 'a' ));
BOOST_CHECK (!ba::none_of ( vc, is_<char> ( 'a' )));
BOOST_CHECK (!ba::none_of_equal ( vc, 'n' ));
BOOST_CHECK (!ba::none_of ( vc, is_<char> ( 'n' )));
BOOST_CHECK ( ba::none_of_equal ( vi.begin(), vi.begin(), 1 ));
BOOST_CHECK ( ba::none_of_equal ( vc.begin(), vc.begin(), 'a' ));
BOOST_CHECK ( ba::none_of ( vi.begin(), vi.begin(), is_<int> ( 1 )));
BOOST_CHECK ( ba::none_of ( vc.begin(), vc.begin(), is_<char> ( 'a' )));
BOOST_CHECK ( ba::none_of_equal ( li, 100 ));
BOOST_CHECK ( ba::none_of ( li, is_<int> ( 100 )));
BOOST_CHECK ( ba::none_of_equal ( li.begin(), li.end(), 100 ));
BOOST_CHECK ( ba::none_of ( li.begin(), li.end(), is_<int> ( 100 )));
std::list<int>::iterator l_iter = li.begin ();
l_iter++; l_iter++; l_iter++;
BOOST_CHECK ( ba::none_of_equal ( li.begin(), l_iter, 18 ));
BOOST_CHECK ( ba::none_of ( li.begin(), l_iter, is_<int> ( 18 )));
BOOST_CHECK (!ba::none_of ( li.begin(), l_iter, is_<int> ( 5 )));
}
int test_main( int , char* [] )
{
test_none();
return 0;
}

101
test/one_of_test.cpp Normal file
View File

@ -0,0 +1,101 @@
/*
Copyright (c) Marshall Clow 2008-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <boost/config.hpp>
#include <boost/algorithm/cxx11/one_of.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <functional>
#include <vector>
#include <list>
template<typename T>
struct is_ : public std::unary_function<T, bool> {
is_ ( T v ) : val_ ( v ) {}
~is_ () {}
bool operator () ( T comp ) const { return val_ == comp; }
private:
is_ (); // need a value
T val_;
};
namespace ba = boost::algorithm;
void test_one ()
{
// Note: The literal values here are tested against directly, careful if you change them:
int some_numbers[] = { 1, 1, 2, 3, 5 };
std::vector<int> vi(some_numbers, some_numbers + 5);
std::list<int> li(vi.begin(), vi.end ());
int some_letters[] = { 'a', 'q', 'n', 'y', 'n' };
std::vector<char> vc(some_letters, some_letters + 5);
BOOST_CHECK (!ba::one_of_equal ( vi, 1 ));
BOOST_CHECK (!ba::one_of ( vi, is_<int> ( 1 )));
BOOST_CHECK (!ba::one_of_equal ( vi.begin(), vi.end(), 1 ));
BOOST_CHECK (!ba::one_of ( vi.begin(), vi.end(), is_<int> ( 1 )));
BOOST_CHECK (!ba::one_of_equal ( vi, 0 ));
BOOST_CHECK (!ba::one_of ( vi, is_<int> ( 0 )));
BOOST_CHECK (!ba::one_of_equal ( vi.begin(), vi.end(), 0 ));
BOOST_CHECK (!ba::one_of ( vi.begin(), vi.end(), is_<int> ( 0 )));
BOOST_CHECK ( ba::one_of_equal ( vi, 2 ));
BOOST_CHECK ( ba::one_of ( vi, is_<int> ( 2 )));
BOOST_CHECK ( ba::one_of_equal ( vi.begin(), vi.end(), 2 ));
BOOST_CHECK ( ba::one_of ( vi.begin(), vi.end(), is_<int> ( 2 )));
// Check for a match at the end
BOOST_CHECK ( ba::one_of_equal ( vi, 5 ));
BOOST_CHECK ( ba::one_of ( vi, is_<int> ( 5 )));
BOOST_CHECK ( ba::one_of_equal ( vi.begin(), vi.end(), 5 ));
BOOST_CHECK ( ba::one_of ( vi.begin(), vi.end(), is_<int> ( 5 )));
BOOST_CHECK ( ba::one_of_equal ( vi.begin() + 1, vi.end(), 1 ));
BOOST_CHECK ( ba::one_of ( vi.begin() + 1, vi.end(), is_<int> ( 1 )));
BOOST_CHECK ( ba::one_of_equal ( vc.begin() + 1, vc.begin() + 2, 'q' ));
BOOST_CHECK ( ba::one_of ( vc.begin() + 1, vc.begin() + 2, is_<char> ( 'q' )));
BOOST_CHECK (!ba::one_of_equal ( vc, '!' ));
BOOST_CHECK (!ba::one_of ( vc, is_<char> ( '!' )));
BOOST_CHECK (!ba::one_of_equal ( vc, 'n' ));
BOOST_CHECK (!ba::one_of ( vc, is_<char> ( 'n' )));
// Empty range check
BOOST_CHECK (!ba::one_of_equal ( vi.begin(), vi.begin(), 1 ));
BOOST_CHECK (!ba::one_of_equal ( vc.begin(), vc.begin(), 'a' ));
BOOST_CHECK (!ba::one_of ( vi.begin(), vi.begin(), is_<int> ( 1 )));
BOOST_CHECK (!ba::one_of ( vc.begin(), vc.begin(), is_<char> ( 'a' )));
BOOST_CHECK (!ba::one_of_equal ( li, 1 ));
BOOST_CHECK (!ba::one_of ( li, is_<int> ( 1 )));
BOOST_CHECK (!ba::one_of_equal ( li.begin(), li.end(), 1 ));
BOOST_CHECK (!ba::one_of ( li.begin(), li.end(), is_<int> ( 1 )));
std::list<int>::iterator l_iter = li.begin ();
l_iter++; l_iter++; l_iter++;
BOOST_CHECK (!ba::one_of_equal ( li.begin(), l_iter, 1 ));
BOOST_CHECK (!ba::one_of ( li.begin(), l_iter, is_<int> ( 1 )));
BOOST_CHECK ( ba::one_of_equal ( li.begin(), l_iter, 2 ));
BOOST_CHECK ( ba::one_of ( li.begin(), l_iter, is_<int> ( 2 )));
BOOST_CHECK (!ba::one_of_equal ( li.begin(), l_iter, 3 ));
BOOST_CHECK (!ba::one_of ( li.begin(), l_iter, is_<int> ( 3 )));
}
int test_main( int , char* [] )
{
test_one ();
return 0;
}

154
test/ordered_test.cpp Normal file
View File

@ -0,0 +1,154 @@
// Copyright (c) 2010 Nuovation System Designs, LLC
// Grant Erickson <gerickson@nuovations.com>
//
// Reworked by Marshall Clow; August 2010
//
// Distributed under 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)
//
// See http://www.boost.org/ for latest version.
#include <algorithm>
#include <iostream>
#include <boost/algorithm/cxx11/is_sorted.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
using namespace boost;
/* Preprocessor Defines */
#define elementsof(v) (sizeof (v) / sizeof (v[0]))
#define a_begin(v) (&v[0])
#define a_end(v) (v + elementsof (v))
#define a_range(v) v
#define b_e(v) a_begin(v),a_end(v)
namespace ba = boost::algorithm;
static void
test_ordered(void)
{
const int strictlyIncreasingValues[] = { 1, 2, 3, 4, 5 };
const int randomValues[] = { 3, 6, 1, 2, 7 };
const int constantValues[] = { 1, 2, 2, 2, 5 };
int nonConstantArray[] = { 1, 2, 2, 2, 5 };
const int inOrderUntilTheEnd [] = { 0, 1, 2, 3, 4, 5, 6, 7, 6 };
// Begin/end checks
BOOST_CHECK ( ba::is_sorted (b_e(strictlyIncreasingValues)));
BOOST_CHECK ( !ba::is_sorted (b_e(randomValues)));
BOOST_CHECK ( ba::is_sorted (b_e(strictlyIncreasingValues), std::less<int>()));
BOOST_CHECK ( !ba::is_sorted (b_e(strictlyIncreasingValues), std::greater<int>()));
// Range checks
BOOST_CHECK ( ba::is_sorted (a_range(strictlyIncreasingValues)));
BOOST_CHECK ( !ba::is_sorted (a_range(randomValues)));
BOOST_CHECK ( ba::is_sorted (a_range(strictlyIncreasingValues), std::less<int>()));
BOOST_CHECK ( !ba::is_sorted (a_range(strictlyIncreasingValues), std::greater<int>()));
BOOST_CHECK ( ba::is_sorted_until ( b_e(strictlyIncreasingValues)) == a_end(strictlyIncreasingValues));
BOOST_CHECK ( ba::is_sorted_until ( b_e(strictlyIncreasingValues), std::less<int>()) == a_end(strictlyIncreasingValues));
BOOST_CHECK ( ba::is_sorted_until ( a_range(strictlyIncreasingValues)) == boost::end(strictlyIncreasingValues));
BOOST_CHECK ( ba::is_sorted_until ( a_range(strictlyIncreasingValues), std::less<int>()) == boost::end(strictlyIncreasingValues));
// Check for const and non-const arrays
BOOST_CHECK ( ba::is_sorted_until ( b_e(constantValues), std::less<int>()) != a_end(constantValues));
BOOST_CHECK ( ba::is_sorted_until ( a_range(constantValues), std::less<int>()) != boost::end(constantValues));
BOOST_CHECK ( ba::is_sorted_until ( b_e(nonConstantArray), std::less<int>()) != a_end(nonConstantArray));
BOOST_CHECK ( ba::is_sorted_until ( a_range(nonConstantArray), std::less<int>()) != boost::end(nonConstantArray));
BOOST_CHECK ( ba::is_sorted_until ( b_e(randomValues), std::less<int>()) == &randomValues[2] );
BOOST_CHECK ( ba::is_sorted_until ( b_e(randomValues)) == &randomValues[2] );
BOOST_CHECK ( ba::is_sorted_until ( a_range(randomValues), std::less<int>()) == &randomValues[2] );
BOOST_CHECK ( ba::is_sorted_until ( a_range(randomValues)) == &randomValues[2] );
BOOST_CHECK ( ba::is_sorted_until ( a_range(inOrderUntilTheEnd), std::less<int>()) == &inOrderUntilTheEnd[8] );
BOOST_CHECK ( ba::is_sorted_until ( a_range(inOrderUntilTheEnd)) == &inOrderUntilTheEnd[8] );
// For zero and one element collections, the comparison predicate should never be called
BOOST_CHECK ( ba::is_sorted_until ( a_begin(randomValues), a_begin(randomValues), std::equal_to<int>()) == a_begin(randomValues));
BOOST_CHECK ( ba::is_sorted_until ( a_begin(randomValues), a_begin(randomValues)) == a_begin(randomValues));
BOOST_CHECK ( ba::is_sorted_until ( a_begin(randomValues), a_begin(randomValues) + 1, std::equal_to<int>()) == a_begin(randomValues) + 1);
BOOST_CHECK ( ba::is_sorted_until ( a_begin(randomValues), a_begin(randomValues) + 1 ) == a_begin(randomValues) + 1);
}
static void
test_increasing_decreasing(void)
{
const int strictlyIncreasingValues[] = { 1, 2, 3, 4, 5 };
const int strictlyDecreasingValues[] = { 9, 8, 7, 6, 5 };
const int increasingValues[] = { 1, 2, 2, 2, 5 };
const int decreasingValues[] = { 9, 7, 7, 7, 5 };
const int randomValues[] = { 3, 6, 1, 2, 7 };
const int constantValues[] = { 7, 7, 7, 7, 7 };
// Test a strictly increasing sequence
BOOST_CHECK ( ba::is_strictly_increasing (b_e(strictlyIncreasingValues)));
BOOST_CHECK ( ba::is_increasing (b_e(strictlyIncreasingValues)));
BOOST_CHECK ( !ba::is_strictly_decreasing (b_e(strictlyIncreasingValues)));
BOOST_CHECK ( !ba::is_decreasing (b_e(strictlyIncreasingValues)));
BOOST_CHECK ( ba::is_strictly_increasing (a_range(strictlyIncreasingValues)));
BOOST_CHECK ( ba::is_increasing (a_range(strictlyIncreasingValues)));
BOOST_CHECK ( !ba::is_strictly_decreasing (a_range(strictlyIncreasingValues)));
BOOST_CHECK ( !ba::is_decreasing (a_range(strictlyIncreasingValues)));
// Test a strictly decreasing sequence
BOOST_CHECK ( !ba::is_strictly_increasing (b_e(strictlyDecreasingValues)));
BOOST_CHECK ( !ba::is_increasing (b_e(strictlyDecreasingValues)));
BOOST_CHECK ( ba::is_strictly_decreasing (b_e(strictlyDecreasingValues)));
BOOST_CHECK ( ba::is_decreasing (b_e(strictlyDecreasingValues)));
// Test an increasing sequence
BOOST_CHECK ( !ba::is_strictly_increasing (b_e(increasingValues)));
BOOST_CHECK ( ba::is_increasing (b_e(increasingValues)));
BOOST_CHECK ( !ba::is_strictly_decreasing (b_e(increasingValues)));
BOOST_CHECK ( !ba::is_decreasing (b_e(increasingValues)));
// Test a decreasing sequence
BOOST_CHECK ( !ba::is_strictly_increasing (b_e(decreasingValues)));
BOOST_CHECK ( !ba::is_increasing (b_e(decreasingValues)));
BOOST_CHECK ( !ba::is_strictly_decreasing (b_e(decreasingValues)));
BOOST_CHECK ( ba::is_decreasing (b_e(decreasingValues)));
// Test a random sequence
BOOST_CHECK ( !ba::is_strictly_increasing (b_e(randomValues)));
BOOST_CHECK ( !ba::is_increasing (b_e(randomValues)));
BOOST_CHECK ( !ba::is_strictly_decreasing (b_e(randomValues)));
BOOST_CHECK ( !ba::is_decreasing (b_e(randomValues)));
// Test a constant sequence
BOOST_CHECK ( !ba::is_strictly_increasing (b_e(constantValues)));
BOOST_CHECK ( ba::is_increasing (b_e(constantValues)));
BOOST_CHECK ( !ba::is_strictly_decreasing (b_e(constantValues)));
BOOST_CHECK ( ba::is_decreasing (b_e(constantValues)));
// Test an empty sequence
BOOST_CHECK ( ba::is_strictly_increasing (strictlyIncreasingValues, strictlyIncreasingValues));
BOOST_CHECK ( ba::is_increasing (strictlyIncreasingValues, strictlyIncreasingValues));
BOOST_CHECK ( ba::is_strictly_decreasing (strictlyIncreasingValues, strictlyIncreasingValues));
BOOST_CHECK ( ba::is_decreasing (strictlyIncreasingValues, strictlyIncreasingValues));
// Test a one-element sequence
BOOST_CHECK ( ba::is_strictly_increasing (strictlyIncreasingValues, strictlyIncreasingValues+1));
BOOST_CHECK ( ba::is_increasing (strictlyIncreasingValues, strictlyIncreasingValues+1));
BOOST_CHECK ( ba::is_strictly_decreasing (strictlyIncreasingValues, strictlyIncreasingValues+1));
BOOST_CHECK ( ba::is_decreasing (strictlyIncreasingValues, strictlyIncreasingValues+1));
// Test a two-element sequence
BOOST_CHECK ( ba::is_strictly_increasing (strictlyIncreasingValues, strictlyIncreasingValues+2));
BOOST_CHECK ( ba::is_increasing (strictlyIncreasingValues, strictlyIncreasingValues+2));
BOOST_CHECK ( !ba::is_strictly_decreasing (strictlyIncreasingValues, strictlyIncreasingValues+2));
BOOST_CHECK ( !ba::is_decreasing (strictlyIncreasingValues, strictlyIncreasingValues+2));
}
int test_main( int, char * [] )
{
test_ordered ();
test_increasing_decreasing ();
return 0;
}

View File

@ -0,0 +1,87 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <iostream>
#include <boost/config.hpp>
#include <boost/algorithm/cxx11/partition_copy.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <boost/algorithm/cxx11/all_of.hpp>
#include <boost/algorithm/cxx11/none_of.hpp>
#include <string>
#include <vector>
#include <list>
namespace ba = boost::algorithm;
// namespace ba = boost;
template <typename Container, typename Predicate>
void test_sequence ( const Container &c, Predicate comp ) {
std::vector<typename Container::value_type> v1, v2;
v1.clear (); v2.clear ();
ba::partition_copy ( c.begin (), c.end (),
std::back_inserter (v1), std::back_inserter (v2), comp );
// std::cout << "Sizes(1): " << c.size () << " -> { " << v1.size () << ", " << v2.size () << " }" << std::endl;
BOOST_CHECK ( v1.size () + v2.size () == c.size ());
BOOST_CHECK ( ba::all_of ( v1.begin (), v1.end (), comp ));
BOOST_CHECK ( ba::none_of ( v2.begin (), v2.end (), comp ));
v1.clear (); v2.clear ();
ba::partition_copy ( c, std::back_inserter (v1), std::back_inserter ( v2 ), comp );
// std::cout << "Sizes(2): " << c.size () << " -> { " << v1.size () << ", " << v2.size () << " }" << std::endl;
BOOST_CHECK ( v1.size () + v2.size () == c.size ());
BOOST_CHECK ( ba::all_of ( v1, comp ));
BOOST_CHECK ( ba::none_of ( v2, comp ));
}
template <typename T>
struct less_than {
public:
less_than ( T foo ) : val ( foo ) {}
less_than ( const less_than &rhs ) : val ( rhs.val ) {}
bool operator () ( const T &v ) const { return v < val; }
private:
less_than ();
less_than operator = ( const less_than &rhs );
T val;
};
bool is_even ( int v ) { return v % 2 == 0; }
void test_sequence1 () {
std::vector<int> v;
v.clear ();
for ( int i = 5; i < 15; ++i )
v.push_back ( i );
test_sequence ( v, less_than<int>(3)); // no elements
test_sequence ( v, less_than<int>(6)); // only the first element
test_sequence ( v, less_than<int>(10));
test_sequence ( v, less_than<int>(99)); // all elements satisfy
// With bidirectional iterators.
std::list<int> l;
for ( int i = 5; i < 16; ++i )
l.push_back ( i );
test_sequence ( l, less_than<int>(3)); // no elements
test_sequence ( l, less_than<int>(6)); // only the first element
test_sequence ( l, less_than<int>(10));
test_sequence ( l, less_than<int>(99)); // all elements satisfy
}
int test_main( int , char* [] )
{
test_sequence1 ();
return 0;
}

View File

@ -0,0 +1,98 @@
/*
Copyright (c) Marshall Clow 2011-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <iostream>
#include <boost/config.hpp>
#include <boost/algorithm/cxx11/partition_point.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <string>
#include <vector>
#include <list>
namespace ba = boost::algorithm;
// namespace ba = boost;
template <typename Container>
typename Container::iterator offset_to_iter ( Container &v, int offset ) {
typename Container::iterator retval;
if ( offset >= 0 ) {
retval = v.begin ();
std::advance ( retval, offset );
}
else {
retval = v.end ();
std::advance ( retval, offset + 1 );
}
return retval;
}
template <typename Container, typename Predicate>
void test_sequence ( Container &v, Predicate comp, int expected ) {
typename Container::iterator res, exp;
res = ba::partition_point ( v.begin (), v.end (), comp );
exp = offset_to_iter ( v, expected );
std::cout << "Expected(1): " << std::distance ( v.begin (), exp )
<< ", got: " << std::distance ( v.begin (), res ) << std::endl;
BOOST_CHECK ( exp == res );
// Duplicate the last element; this checks for any even/odd problems
v.push_back ( * v.rbegin ());
res = ba::partition_point ( v.begin (), v.end (), comp );
exp = offset_to_iter ( v, expected );
std::cout << "Expected(2): " << std::distance ( v.begin (), exp )
<< ", got: " << std::distance ( v.begin (), res ) << std::endl;
BOOST_CHECK ( exp == res );
}
template <typename T>
struct less_than {
public:
less_than ( T foo ) : val ( foo ) {}
less_than ( const less_than &rhs ) : val ( rhs.val ) {}
bool operator () ( const T &v ) const { return v < val; }
private:
less_than ();
less_than operator = ( const less_than &rhs );
T val;
};
void test_sequence1 () {
std::vector<int> v;
v.clear ();
for ( int i = 5; i < 15; ++i )
v.push_back ( i );
test_sequence ( v, less_than<int>(3), 0 ); // no elements
test_sequence ( v, less_than<int>(6), 1 ); // only the first element
test_sequence ( v, less_than<int>(10), 5 );
test_sequence ( v, less_than<int>(99), -1 ); // all elements satisfy
// With bidirectional iterators.
std::list<int> l;
for ( int i = 5; i < 15; ++i )
l.push_back ( i );
test_sequence ( l, less_than<int>(3), 0 ); // no elements
test_sequence ( l, less_than<int>(6), 1 ); // only the first element
test_sequence ( l, less_than<int>(10), 5 );
test_sequence ( l, less_than<int>(99), -1 ); // all elements satisfy
}
int test_main( int , char* [] )
{
test_sequence1 ();
return 0;
}

26
test/search_fail1.cpp Normal file
View File

@ -0,0 +1,26 @@
/*
Copyright (c) Marshall Clow 2010-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <vector>
#include <boost/algorithm/searching/boyer_moore.hpp>
int main( int argc, char *argv [] )
{
std::vector<char> cv;
std::vector<int> iv;
// Should fail to compile because the underlying types are different
// They are (almost certainly) different sizes
(void) boost::algorithm::boyer_moore_search (
cv.begin (), cv.end (), iv.begin (), iv.end ());
(void) argv; (void) argc;
return 0;
}

27
test/search_fail2.cpp Normal file
View File

@ -0,0 +1,27 @@
/*
Copyright (c) Marshall Clow 2010-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <vector>
#include <boost/cstdint.hpp>
#include <boost/algorithm/searching/boyer_moore.hpp>
int main( int argc, char *argv [] )
{
std::vector<boost::uint8_t> cv;
std::vector<boost:: int8_t> iv;
// Should fail to compile because the underlying types are different
// They are the same size, but one is signed, and the other is not.
(void) boost::algorithm::boyer_moore_search (
cv.begin (), cv.end (), iv.begin (), iv.end ());
(void) argv; (void) argc;
return 0;
}

20
test/search_fail3.cpp Normal file
View File

@ -0,0 +1,20 @@
/*
Copyright (c) Marshall Clow 2010-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <vector>
#include <boost/algorithm/searching/boyer_moore.hpp>
int main( int argc, char *argv [] )
{
// Should fail to compile because the search objects are not default-constructible
boost::algorithm::boyer_moore<std::vector<char>::iterator> bm;
(void) argv; (void) argc;
return 0;
}

272
test/search_test1.cpp Normal file
View File

@ -0,0 +1,272 @@
/*
Copyright (c) Marshall Clow 2010-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <boost/algorithm/searching/boyer_moore.hpp>
#include <boost/algorithm/searching/boyer_moore_horspool.hpp>
#include <boost/algorithm/searching/knuth_morris_pratt.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <iostream>
#include <string>
#include <vector>
namespace ba = boost::algorithm;
template <typename Iter>
std::string make_str ( Iter first, std::size_t len ) {
std::string retVal ( len + 2, '\'' );
std::copy ( first, first+len, retVal.begin () + 1);
return retVal;
}
namespace {
// Check using iterators
template<typename Container>
void check_one_iter ( const Container &haystack, const std::string &needle, int expected ) {
typedef typename Container::const_iterator iter_type;
typedef std::string::const_iterator pattern_type;
iter_type hBeg = haystack.begin ();
iter_type hEnd = haystack.end ();
pattern_type nBeg = needle.begin ();
pattern_type nEnd = needle.end ();
iter_type it0 = std::search (hBeg, hEnd, nBeg, nEnd);
iter_type it1 = ba::boyer_moore_search (hBeg, hEnd, nBeg, nEnd);
iter_type it1r = ba::boyer_moore_search (haystack, nBeg, nEnd);
iter_type it2 = ba::boyer_moore_horspool_search (hBeg, hEnd, nBeg, nEnd);
iter_type it3 = ba::knuth_morris_pratt_search (hBeg, hEnd, nBeg, nEnd);
const int dist = it1 == hEnd ? -1 : std::distance ( hBeg, it1 );
std::cout << "(Iterators) Pattern is " << needle.length () << ", haysstack is " << haystack.length () << " chars long; " << std::endl;
try {
if ( it0 != it1 ) {
throw std::runtime_error (
std::string ( "results mismatch between std::search and boyer-moore search" ));
}
if ( it1 != it1r ) {
throw std::runtime_error (
std::string ( "results mismatch between iterator and range boyer_moore search" ));
}
if ( it1 != it2 ) {
throw std::runtime_error (
std::string ( "results mismatch between boyer-moore and boyer-moore-horspool search" ));
}
if ( it1 != it3 )
throw std::runtime_error (
std::string ( "results mismatch between boyer-moore and knuth-morris-pratt search" ));
}
catch ( ... ) {
std::cout << "Searching for: " << needle << std::endl;
std::cout << "Expected: " << expected << "\n";
std::cout << " std: " << std::distance ( hBeg, it0 ) << "\n";
std::cout << " bm: " << std::distance ( hBeg, it1 ) << "\n";
std::cout << " bm(r): " << std::distance ( hBeg, it1r ) << "\n";
std::cout << " bmh: " << std::distance ( hBeg, it2 ) << "\n";
std::cout << " kpm: " << std::distance ( hBeg, it3 )<< "\n";
std::cout << std::flush;
throw ;
}
BOOST_CHECK_EQUAL ( dist, expected );
}
// Check using pointers
// We're assuming that the container implements contiguous storage here.
template<typename Container>
void check_one_pointer ( const Container &haystack, const std::string &needle, int expected ) {
typedef const typename Container::value_type *ptr_type;
ptr_type hBeg = haystack.size () == 0 ? NULL : &*haystack.begin ();
ptr_type hEnd = hBeg + haystack.size ();
ptr_type nBeg = needle.size () == 0 ? NULL : &*needle.begin ();
ptr_type nEnd = nBeg + needle.size ();
ptr_type it0 = std::search (hBeg, hEnd, nBeg, nEnd);
ptr_type it1 = ba::boyer_moore_search (hBeg, hEnd, nBeg, nEnd);
ptr_type it2 = ba::boyer_moore_horspool_search (hBeg, hEnd, nBeg, nEnd);
ptr_type it3 = ba::knuth_morris_pratt_search (hBeg, hEnd, nBeg, nEnd);
const int dist = it1 == hEnd ? -1 : std::distance ( hBeg, it1 );
std::cout << "(Pointers) Pattern is " << needle.length () << ", haysstack is " << haystack.length () << " chars long; " << std::endl;
try {
if ( it0 != it1 ) {
throw std::runtime_error (
std::string ( "results mismatch between std::search and boyer-moore search" ));
}
if ( it1 != it2 ) {
throw std::runtime_error (
std::string ( "results mismatch between boyer-moore and boyer-moore-horspool search" ));
}
if ( it1 != it3 )
throw std::runtime_error (
std::string ( "results mismatch between boyer-moore and knuth-morris-pratt search" ));
}
catch ( ... ) {
std::cout << "Searching for: " << needle << std::endl;
std::cout << "Expected: " << expected << "\n";
std::cout << " std: " << std::distance ( hBeg, it0 ) << "\n";
std::cout << " bm: " << std::distance ( hBeg, it1 ) << "\n";
std::cout << " bmh: " << std::distance ( hBeg, it2 ) << "\n";
std::cout << " kpm: " << std::distance ( hBeg, it3 )<< "\n";
std::cout << std::flush;
throw ;
}
BOOST_CHECK_EQUAL ( dist, expected );
}
// Check using objects
template<typename Container>
void check_one_object ( const Container &haystack, const std::string &needle, int expected ) {
typedef typename Container::const_iterator iter_type;
typedef std::string::const_iterator pattern_type;
iter_type hBeg = haystack.begin ();
iter_type hEnd = haystack.end ();
pattern_type nBeg = needle.begin ();
pattern_type nEnd = needle.end ();
ba::boyer_moore<pattern_type> bm_r = ba::make_boyer_moore ( needle );
ba::boyer_moore<pattern_type> bm ( nBeg, nEnd );
ba::boyer_moore_horspool<pattern_type> bmh ( nBeg, nEnd );
ba::knuth_morris_pratt<pattern_type> kmp ( nBeg, nEnd );
iter_type it0 = std::search (hBeg, hEnd, nBeg, nEnd);
iter_type it1 = bm (hBeg, hEnd);
iter_type it1r = bm (haystack);
iter_type rt1 = bm_r (hBeg, hEnd);
iter_type rt1r = bm_r (haystack);
iter_type it2 = bmh (hBeg, hEnd);
iter_type it3 = kmp (hBeg, hEnd);
const int dist = it1 == hEnd ? -1 : std::distance ( hBeg, it1 );
std::cout << "(Objects) Pattern is " << needle.length () << ", haysstack is " << haystack.length () << " chars long; " << std::endl;
try {
if ( it0 != it1 ) {
throw std::runtime_error (
std::string ( "results mismatch between std::search and boyer-moore search" ));
}
if ( it1 != it1r ) {
throw std::runtime_error (
std::string ( "results mismatch between iterator and range boyer_moore search(1)" ));
}
if ( it1 != rt1 ) {
throw std::runtime_error (
std::string ( "results mismatch between iterator and range boyer_moore search(2)" ));
}
if ( rt1 != rt1r ) {
throw std::runtime_error (
std::string ( "results mismatch between iterator and range boyer_moore search(3)" ));
}
if ( it1 != it2 ) {
throw std::runtime_error (
std::string ( "results mismatch between boyer-moore and boyer-moore-horspool search" ));
}
if ( it1 != it3 )
throw std::runtime_error (
std::string ( "results mismatch between boyer-moore and knuth-morris-pratt search" ));
}
catch ( ... ) {
std::cout << "Searching for: " << needle << std::endl;
std::cout << "Expected: " << expected << "\n";
std::cout << " std: " << std::distance ( hBeg, it0 ) << "\n";
std::cout << " bm: " << std::distance ( hBeg, it1 ) << "\n";
std::cout << " bm(r1): " << std::distance ( hBeg, it1r ) << "\n";
std::cout << " bm(r2): " << std::distance ( hBeg, rt1 ) << "\n";
std::cout << " bm(r3): " << std::distance ( hBeg, rt1r ) << "\n";
std::cout << " bmh: " << std::distance ( hBeg, it2 ) << "\n";
std::cout << " kpm: " << std::distance ( hBeg, it3 )<< "\n";
std::cout << std::flush;
throw ;
}
BOOST_CHECK_EQUAL ( dist, expected );
}
template<typename Container>
void check_one ( const Container &haystack, const std::string &needle, int expected ) {
check_one_iter ( haystack, needle, expected );
check_one_pointer ( haystack, needle, expected );
check_one_object ( haystack, needle, expected );
}
}
int test_main( int , char* [] )
{
std::string haystack1 ( "NOW AN FOWE\220ER ANNMAN THE ANPANMANEND" );
std::string needle1 ( "ANPANMAN" );
std::string needle2 ( "MAN THE" );
std::string needle3 ( "WE\220ER" );
std::string needle4 ( "NOW " ); // At the beginning
std::string needle5 ( "NEND" ); // At the end
std::string needle6 ( "NOT FOUND" ); // Nowhere
std::string needle7 ( "NOT FO\340ND" ); // Nowhere
std::string haystack2 ( "ABC ABCDAB ABCDABCDABDE" );
std::string needle11 ( "ABCDABD" );
std::string haystack3 ( "abra abracad abracadabra" );
std::string needle12 ( "abracadabra" );
std::string needle13 ( "" );
std::string haystack4 ( "" );
check_one ( haystack1, needle1, 26 );
check_one ( haystack1, needle2, 18 );
check_one ( haystack1, needle3, 9 );
check_one ( haystack1, needle4, 0 );
check_one ( haystack1, needle5, 33 );
check_one ( haystack1, needle6, -1 );
check_one ( haystack1, needle7, -1 );
check_one ( needle1, haystack1, -1 ); // cant find long pattern in short corpus
check_one ( haystack1, haystack1, 0 ); // find something in itself
check_one ( haystack2, haystack2, 0 ); // find something in itself
check_one ( haystack2, needle11, 15 );
check_one ( haystack3, needle12, 13 );
check_one ( haystack1, needle13, 0 ); // find the empty string
check_one ( haystack4, needle1, -1 ); // can't find in an empty haystack
// Mikhail Levin <svarneticist@gmail.com> found a problem, and this was the test
// that triggered it.
const std::string mikhail_pattern =
"GATACACCTACCTTCACCAGTTACTCTATGCACTAGGTGCGCCAGGCCCATGCACAAGGGCTTGAGTGGATGGGAAGGA"
"TGTGCCCTAGTGATGGCAGCATAAGCTACGCAGAGAAGTTCCAGGGCAGAGTCACCATGACCAGGGACACATCCACGAG"
"CACAGCCTACATGGAGCTGAGCAGCCTGAGATCTGAAGACACGGCCATGTATTACTGTGGGAGAGATGTCTGGAGTGGT"
"TATTATTGCCCCGGTAATATTACTACTACTACTACTACATGGACGTCTGGGGCAAAGGGACCACG"
;
const std::string mikhail_corpus = std::string (8, 'a') + mikhail_pattern;
check_one ( mikhail_corpus, mikhail_pattern, 8 );
return 0;
}

145
test/search_test2.cpp Normal file
View File

@ -0,0 +1,145 @@
/*
Copyright (c) Marshall Clow 2010-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <boost/algorithm/searching/boyer_moore.hpp>
#include <boost/algorithm/searching/boyer_moore_horspool.hpp>
#include <boost/algorithm/searching/knuth_morris_pratt.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <iostream>
#include <algorithm>
#include <vector>
typedef std::vector<char> vec;
#define NUM_TRIES 100
#define runOne(call, refDiff) { \
std::clock_t bTime, eTime; \
bTime = std::clock (); \
for ( i = 0; i < NUM_TRIES; ++i ) { \
res = boost::algorithm::call \
( haystack.begin (), haystack.end (), \
needle.begin (), needle.end ()); \
if ( res != exp ) { \
std::cout << "On run # " << i << " expected " \
<< exp - haystack.begin () << " got " \
<< res - haystack.begin () << std::endl; \
throw std::runtime_error \
( "Unexpected result from " #call ); \
} \
} \
eTime = std::clock (); \
printRes ( #call, eTime - bTime, refDiff ); }
#define runObject(obj, refDiff) { \
std::clock_t bTime, eTime; \
bTime = std::clock (); \
boost::algorithm::obj <vec::const_iterator> \
s_o ( needle.begin (), needle.end ()); \
for ( i = 0; i < NUM_TRIES; ++i ) { \
res = s_o ( haystack.begin (), haystack.end ()); \
if ( res != exp ) { \
std::cout << "On run # " << i << " expected " \
<< exp - haystack.begin () << " got " \
<< res - haystack.begin () << std::endl; \
throw std::runtime_error \
( "Unexpected result from " #obj " object" ); \
} \
} \
eTime = std::clock (); \
printRes ( #obj " object", eTime - bTime, refDiff ); }
namespace {
vec ReadFromFile ( const char *name ) {
std::ifstream in ( name, std::ios_base::binary | std::ios_base::in );
vec retVal;
std::istream_iterator<char, char> begin(in);
std::istream_iterator<char, char> end;
std::copy ( begin, end, std::back_inserter ( retVal ));
return retVal;
}
void printRes ( const char *prompt, unsigned long diff, unsigned long stdDiff ) {
std::cout
<< std::setw(34) << prompt << " "
<< std::setw(6) << ( 1.0 * diff) / CLOCKS_PER_SEC << " seconds\t"
<< std::setw(5) << (100.0 * diff) / stdDiff << "% \t"
<< std::setw(12) << diff;
if ( diff > stdDiff )
std::cout << " !!";
std::cout << std::endl;
}
void check_one ( const vec &haystack, const vec &needle, int expected ) {
std::size_t i;
std::clock_t sTime;
unsigned long stdDiff;
vec::const_iterator res;
vec::const_iterator exp; // the expected result
if ( expected >= 0 )
exp = haystack.begin () + expected;
else if ( expected == -1 )
exp = haystack.end (); // we didn't find it!
else if ( expected == -2 )
exp = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
else
throw std::logic_error ( "Expected must be -2, -1, or >= 0" );
std::cout << "Pattern is " << needle.size () << " entries long" << std::endl;
std::cout << "Corpus is " << haystack.size () << " entries long" << std::endl;
// First, the std library search
sTime = std::clock ();
for ( i = 0; i < NUM_TRIES; ++i ) {
res = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
if ( res != exp ) {
std::cout << "On run # " << i << " expected " << exp - haystack.begin () << " got " << res - haystack.begin () << std::endl;
throw std::runtime_error ( "Unexpected result from std::search" );
}
}
stdDiff = std::clock () - sTime;
printRes ( "std::search", stdDiff, stdDiff );
runOne ( boyer_moore_search, stdDiff );
runObject ( boyer_moore, stdDiff );
runOne ( boyer_moore_horspool_search, stdDiff );
runObject ( boyer_moore_horspool, stdDiff );
runOne ( knuth_morris_pratt_search, stdDiff );
runObject ( knuth_morris_pratt, stdDiff );
}
}
int test_main( int , char* [] )
{
vec c1 = ReadFromFile ( "search_test_data/0001.corpus" );
vec p1b = ReadFromFile ( "search_test_data/0001b.pat" );
vec p1e = ReadFromFile ( "search_test_data/0001e.pat" );
vec p1n = ReadFromFile ( "search_test_data/0001n.pat" );
vec p1f = ReadFromFile ( "search_test_data/0001f.pat" );
std::cout << std::ios::fixed << std::setprecision(4);
// std::cout << "Corpus is " << c1.size () << " entries long\n";
std::cout << "--- Beginning ---" << std::endl;
check_one ( c1, p1b, 0 ); // Find it at position zero
std::cout << "---- Middle -----" << std::endl;
check_one ( c1, p1f, -2 ); // Don't know answer
std::cout << "------ End ------" << std::endl;
check_one ( c1, p1e, c1.size() - p1e.size ());
std::cout << "--- Not found ---" << std::endl;
check_one ( c1, p1n, -1 ); // Not found
return 0;
}

145
test/search_test3.cpp Normal file
View File

@ -0,0 +1,145 @@
/*
Copyright (c) Marshall Clow 2010-2012.
Distributed under 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)
For more information, see http://www.boost.org
*/
#include <boost/algorithm/searching/boyer_moore.hpp>
#include <boost/algorithm/searching/boyer_moore_horspool.hpp>
#include <boost/algorithm/searching/knuth_morris_pratt.hpp>
#include <boost/test/included/test_exec_monitor.hpp>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
typedef std::vector<std::string> vec;
#define NUM_TRIES 100
#define runOne(call, refDiff) { \
std::clock_t bTime, eTime; \
bTime = std::clock (); \
for ( i = 0; i < NUM_TRIES; ++i ) { \
res = boost::algorithm::call \
( haystack.begin (), haystack.end (), \
needle.begin (), needle.end ()); \
if ( res != exp ) { \
std::cout << "On run # " << i << " expected " \
<< exp - haystack.begin () << " got " \
<< res - haystack.begin () << std::endl; \
throw std::runtime_error \
( "Unexpected result from " #call ); \
} \
} \
eTime = std::clock (); \
printRes ( #call, eTime - bTime, refDiff ); }
#define runObject(obj, refDiff) { \
std::clock_t bTime, eTime; \
bTime = std::clock (); \
boost::algorithm::obj <vec::const_iterator> \
s_o ( needle.begin (), needle.end ()); \
for ( i = 0; i < NUM_TRIES; ++i ) { \
res = s_o ( haystack.begin (), haystack.end ()); \
if ( res != exp ) { \
std::cout << "On run # " << i << " expected " \
<< exp - haystack.begin () << " got " \
<< res - haystack.begin () << std::endl; \
throw std::runtime_error \
( "Unexpected result from " #obj " object" ); \
} \
} \
eTime = std::clock (); \
printRes ( #obj " object", eTime - bTime, refDiff ); }
namespace {
vec ReadFromFile ( const char *name ) {
std::ifstream in ( name, std::ios_base::binary | std::ios_base::in );
std::string temp;
vec retVal;
while ( std::getline ( in, temp ))
retVal.push_back ( temp );
return retVal;
}
void printRes ( const char *prompt, unsigned long diff, unsigned long stdDiff ) {
std::cout
<< std::setw(34) << prompt << " "
<< std::setw(6) << ( 1.0 * diff) / CLOCKS_PER_SEC << " seconds\t"
<< std::setw(5) << (100.0 * diff) / stdDiff << "% \t"
<< std::setw(12) << diff;
if ( diff > stdDiff )
std::cout << " !!";
std::cout << std::endl;
}
void check_one ( const vec &haystack, const vec &needle, int expected ) {
std::size_t i;
std::clock_t sTime;
unsigned long stdDiff;
vec::const_iterator res;
vec::const_iterator exp; // the expected result
if ( expected >= 0 )
exp = haystack.begin () + expected;
else if ( expected == -1 )
exp = haystack.end (); // we didn't find it1
else if ( expected == -2 )
exp = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
else
throw std::logic_error ( "Expected must be -2, -1, or >= 0" );
std::cout << "Pattern is " << needle.size () << " entries long" << std::endl;
std::cout << "Corpus is " << haystack.size () << " entries long" << std::endl;
// First, the std library search
sTime = std::clock ();
for ( i = 0; i < NUM_TRIES; ++i ) {
res = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
if ( res != exp ) {
std::cout << "On run # " << i << " expected " << exp - haystack.begin () << " got " << res - haystack.begin () << std::endl;
throw std::runtime_error ( "Unexpected result from std::search" );
}
}
stdDiff = std::clock () - sTime;
printRes ( "std::search", stdDiff, stdDiff );
runOne ( boyer_moore_search, stdDiff );
runObject ( boyer_moore, stdDiff );
runOne ( boyer_moore_horspool_search, stdDiff );
runObject ( boyer_moore_horspool, stdDiff );
runOne ( knuth_morris_pratt_search, stdDiff );
runObject ( knuth_morris_pratt, stdDiff );
}
}
int test_main( int , char* [] )
{
vec c1 = ReadFromFile ( "search_test_data/0001.corpus" );
vec p1b = ReadFromFile ( "search_test_data/0002b.pat" );
vec p1e = ReadFromFile ( "search_test_data/0002e.pat" );
vec p1n = ReadFromFile ( "search_test_data/0002n.pat" );
vec p1f = ReadFromFile ( "search_test_data/0002f.pat" );
std::cout << std::ios::fixed << std::setprecision(4);
// std::cout << "Corpus is " << c1.size () << " entries long\n";
std::cout << "--- Beginning ---" << std::endl;
check_one ( c1, p1b, 0 ); // Find it at position zero
std::cout << "---- Middle -----" << std::endl;
check_one ( c1, p1f, -2 ); // Don't know answer
std::cout << "------ End ------" << std::endl;
check_one ( c1, p1e, c1.size() - p1e.size ());
std::cout << "--- Not found ---" << std::endl;
check_one ( c1, p1n, -1 ); // Not found
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
TU0AKgAfhPqScHN4dnZ2e3p5e3h7eXl4dnd1dnV3enp5dnd3dHV1dHNzd3l3eHh5
eXZ4dXd2dHNwcHFwcXBxc3h0dHN1eHVzcXV1dXV2c3h5dHV3eHVwcHF

View File

@ -0,0 +1,2 @@
iBJbmMuLCBhbGwg
cmlnaHRzIHJlc2VydmVkLgAAAAA=

View File

@ -0,0 +1,2 @@
q/y9PZ3uHj5ufo6UJDQ0NFQz8+RUZBQEBAOzo6Ozs4Nz06Ojs4Ojo9PT47Ojk0
Nzc7OjQ6NzU6OjgxMzg1OjY2NjU3NTU1Nzc3NTU1NzU

View File

@ -0,0 +1,2 @@
TIzMjIyMjM0MjM1nTQzNTc3MzY1NDU2NzQ2MjEwMjU1MTQ2NzU0NDI1
NDMyMzQxMzQ0NDU1MjU2NTc5NzU1NDc4ODY1

View File

@ -0,0 +1,170 @@
TU0AKgAfhPqScHN4dnZ2e3p5e3h7eXl4dnd1dnV3enp5dnd3dHV1dHNzd3l3eHh5
eXZ4dXd2dHNwcHFwcXBxc3h0dHN1eHVzcXV1dXV2c3h5dHV3eHVwcHF1d3V0dXJy
cXNzcHBwcHJyc3R0dXl7eHJycnF1dHV2d3h4eHV0cnRycXN1dXN0c3R0c3R0cXJx
cHNxb3B0c29scHFybm9sbGpscXJ1c3NycXN0cHFvb3JzdHBycG9vb29vb29ubXBt
bG9vcW5tbGptb3Fwb3Bwb25vbXFtbGtvbGlrbnBuamxsbW1rbW1vbm1ub3Btamxw
bWpsbG9xcG5ua2tpamhqZ2hnam5saWhsbG1nZmZnZ2lnamtxa2ppZWZmZWlrZ2hp
Z2hraWRmZ2psa2pmZWVkZmplZWZiYF1gZGVlYmJiY2RhY2NiYVxdW1xgXl9iZV9d
X11hXF5gZWJhYF5dXWFmYl9hXl5gXmBhZGFhYV1cYWFiX2FgXFxgYF5iYmNiYWRk
YWFjYGFgXl9jYmVlZGZiYV1cXFtbW1pYV1dVV1VWVlFQT1FRUVBRTkxLSktNTVFP
UU1RUVBSUlBPUlNTUVRWWFpcVldXWldXVVhYVlpbWV1dX1tbW11fYWFdXV5iY2Rg
YFxeYmNmZGJgYFxdYmdjYWFhYGJoZGReXF9gX2BhYWJhXltdXVtaXGJlYV5gYF9f
XVxcX2JiYWJkZmNjZGNhYmFcW15dXmBgX1xdYF5fXF5eX15bWV1dXl9eWlldXGJf
XmFgXVpcXF1dXlpdXl9dXWRlYF5cXFtfYF1eYl1hX1xbXV1ZV1hZWltbW1peW1lb
XlteW1xeXlxbXVpYW11dY19fW1xfX2NhXV5hZWNfX2FjZGJlZmVoaWtlY2FkXl5f
YWJjX19fX15dXWBjYmJeWlteXVlaXmBeXF1fXVxdXFtaW19dXFtfWllZWVxeXlxb
XV9eW1xcXF5cW1paVVdbWVteW1pbWlZeYV1ZV1tYVlVWV1hbWVhcWVhVWlhbWFtX
V1ZWWFtXVlZaVlRVVVdVVldWVlNRU1NTUVNXVVlZWVZVVFNWVlRTU1JVV1ZWVFRU
UVFVWVpZWlZWWFpYWllcXVpYWFdWWFxbWFlYWVhVVVRVV1dZWllYV1lcXVpcWVhY
V1VbW1tVVVdaXFpXVlZZW1leW1lWWFdaXVpXWlZXW1xdXFxgX1xYXVxcXFhaW1tb
WlxcWltdWldXVldXWVZVUVJVWFlcW1tcWVpgXF9hX11aWVpdXFxeXFtbX19aW1lb
W1paWlxdXVpaXVxeX1xdX2JjYV9gYl9cW1xbWFpeXl1gYGBgYFtdY2JhYmBgYGBe
YGJkY2NjYmNjYGNiY2JgX19hYV1gX2BgX19hZWRiZWJjZWVgYmFiZGRmaWdmYWJj
YmJjZGFhY2FhY2RkZmVmY2FhYWVnaWVjZGNhY2RlZWZqZ2doZ2RjZGRmaGVlZmZm
Z2dnaGhoZ2hmY2VmZWZjZWNlaWdlZmVoZ2hpamlra2hram1samtqZWpuc2tpa21u
bmtraWtqYWNmZmZmZGVpZ2p0kMLk8vv+/////////5drcHZ1dnd7fHt6end0c3V1
dnR0d3l3d3Z3fH16dnV2d3h0d3l2d3h4dXZ3d3d3dnBucW5vb3BxdHR3d3Jzd3Vz
dndzc3V6eHVyc3JydXZxc3Z1d3V0eHZ1c3Bvc3V0dnR0dXR0dHd4dnRxc3J0c3d3
dXNycXd1dnVzcHJ0d3h0dHFwcXFzc3N0dXFxcXFwcHFwcnFycHJwcHJzc3Fwc3Nx
cnRyc29ucHJ0cnBwb29ub3Fwc3R0cnJubnBycG1ucHBxcXBuc3FwbGpoamlsb3By
c25qaW1tcW1qbXFua25xb21vcG9tbG5qa2doaW1sbGpqamxsaWpmZ2VlZ2tqZ2Zn
amVoa2tvZ2ttamxpamlmZmdoZ2dnZ2traWZmaGlpa2loaGdmZ2ZoZmRnZ2ZmZ2Vl
ZmJiZWBhYmBhZGBhX2BfXVxfYmJkZF5dY2JjYWNhY2BgXl5gXl5dXl5cXFxgZGVh
Xl5eXlxeXl5iYl9fYF9iYWFhZWRkY2RgX2BhX19gY2VlZWRkZF1gYV9bWV1dWVxX
WldXVlZVU1BQUE5QUU9SUU5NUE9OTk9NT1FRUk5PUVRUUVJSVFVYWVpXVldVVlRV
V1dZXl9bW1pYWVhaXl9gXl5bYGJhYWFhX19jZGZmZGJgYF9eX19fYWRmX2RgYWBe
XmFhYWNhYmBeXV5eW1xdYF5dX2NiX19hX11dYmVoY2RlZWFeYF5fXV5hYGFgYF9i
Y19dXl5dYGNgXFZbXlxZWVxhYl5gYF9cXV1cXFxdX19gYVxZW11dX2NjXF5eXF5e
Xl9eYGJfXl9eW1xcX11ZW1xdW15eW11gXl1dW11cX15dXl1cXF5iX2BgYV9iYmJf
XF1mY2NiamZiYWNiY2JiYmVpbGdkYGBmY2VoY11dXFxcX15iYmFiYmBeW19hX19h
XV5aYlxZWlxcW1xcW2BfW1hZXF5cXVtcXlxbWldYW1xcXVpYWFlYWllbW1paWFpe
XFtYWFdUU1ZVWFhVWFteWFdYW1pYVlhVU1RVWVZXVVdXVVFSU1ZWVFNSVVtSUlJT
UlNUVVVWVVVWVVJWVVVTVldXXFlXVVlbVVNUWVtXWVtVVVZVWltZWltYVVVZWVlY
V1ZXWVVUV1dXWl1dW1tcX1lZWl5cXVtcWVVXXFxZXVxZVVRUWVlcWVZWWFhaWFtd
WV5YVlZZWVxbXFxdXFtbXl5dXVtbWV5dYF9cXl9eXF9iXl5bWlhbWltZWFpgXlpa
W15iXF1jYVtcYGBfXVpbXFxcWlxbXFtZXFxaWllaXl1aW11gXV5fX19fX19hXl5f
YGFgYWBhXmBiXlxfXFtcXmBgYmJkYWJgYmNgYGJiYWBfX19jZWBeYWJgYFxcY2Vj
ZGJfX2JiYWNmY2RjYmFhYWFjYWNpZmNjZ2ZkZGBiYmVmZ2VjYmNlZV9iZWhlZWJi
Y2JmZWdoZWVoZmdrZ2VmZmhmZGRkZ2VmZmVkZmppZmVnaGhqamhiZmZnaWdnamZm
ZmtubGtpZWhna21rZmRpaWVlZ2l0bGtrbG1obmdmamZnaGVkZGNobYekwePx+///
////////l2pzdnh3fHt8enp5fnl2d3Vyc3d5eXd1d3d3eXx+eHp3eHR0d3d6enl1
dHNzc3d1dXNwcHJ0c3Byc3V3eXVycnZ5enl3dnh3dnJxdHZ3dXh8eHl1dXZ3dnZ1
dHV0ent2dXl3dXV1d3h3dnZ3enV0d3d0dXN3dXZ1dnd3d3h6eHZzc3JwcnN0dHJy
cXFub3FycW9vcHBvbGxsbXFzcHF1c3N0dHR0c3Bvc3N1cnFvcW9tbXFzcm5ub3Bw
b21ucXBxcXBvc3Bvbm5sa25sbW1vbnJ0b2trbWpqbGtsbnFxcG9vbm1xbm5tbGpp
amtqbm1rbW9sa21taWhoZmlqaGlramxqaWdraGdqaWluam9ua2psamhkZmxpaWpq
aWVlZWdnaGZjY2RpZmZnZmZmZ2ZnZGFhZWNgZGJhY11dXV5hXF9lZGRiY2JhYV5f
YGZgYF5fYWJgYmBgX15gZF9eYF1gYlxeYV5fYV5eYF5gYWJkX2JhZGNlZGJjYmFh
YWNgY2VhZGZkY2JgYWBjY15fXFtaWllaXFlYVlNRUVNTUU5PUlNSVlRPU09PUVJS
U1FNT1JVUk9RU1NRU1NSVFRWVllWWFtXWFhaWlpeXl1hYV9cXV5fXl9gXmFgYGBh
ZmJjYmJjYV9fX19dYWFiZmRiYWBeX2FcW15fYWBfXmNkX11cXF1cXVxfYl9hYWJd
X2BhY2JjX2BkZGFgYWFfYWFgYF9eX2JiZGVjY19dYF9eXV1eXF9hXmBeXF1fXV9b
XGFhY2FkX11dW1peXl9hYWJgX19jYV5dYGFgYGBdWV5cXV9hYGBcX2BhYF5gZWBb
X19dXWBeXl1eYWNhXl1eYGFhYGFgYWFhZGNiZGZoZWdnZWNgXWFhX2NlY2NjYGBl
Y2NjY11bXl9eXmBiYGFgXF9kYF5iYF9iYl9cW15aWV5fXFtaWVpdW1xfYGBfXV5d
XFtcWlhXVlZWWFhYV1ZWV1daWlhbWlpcXFhaWFdYVldYWFlZWWFYWltYWVhSVFdV
VlpWV1RYV1VTVFRYVVRWU1RUVVhWVVRUVFZXVFVXV1VWV1ZYV1lcbltbWV5ZWlpX
V1VSWFtfW1laXV5bWFpZWlpYWVhYW1hYV1daWVlZV15dWlxgXVpZWV1hXFpbW1dY
WlpZVldXWlpWVlZXWlhaWVlZWVpZW1xbWltcWVhaXVxdWVxZWVtaX2BfXFlaWVte
XV5dXV9eXF9bW1xbXl9hXFdcXlxbWVpbXFpcWF1gXV9gYF9aW11cX15dX19gXFtY
WVtZW1tdXWBiYWBfXV5cXV5dX15eXV1iZWRhYWFiYF9eYmBeXV5dYWBdXWBlY2Fh
YWRfYF9hY2RhZGJjZGZjYmJfYV5fZGJkYWBgYGBjY2RlaGNhY2BjYF9eYWJgY2Vk
Y2JlZWRhYmRlY2FjY2RjY2RjY2NjYWBkY2NjZGVjYWRnaGhramtqZmdnZmhoZ2pn
aGhoZmhpa2lpaGhoZ2hlZmdqaGZsbWhpamlqamppa21qaGhmaGxqZWVra25sbW5p
aWhraWprbW1pZ2ZoZ2hsfKXG4/D7//////////+UbnR5e3t6eHmAfH58eHZ2dHd2
d3x3dHZ2dnl4eHt8fHh4dXVydXR3eXd2dXR4d3Z1dXZ1dnhydHd5d3ZzdHV4dXR2
eX13dnV2dHN1eXh4eHd3dnd2d3Z3dXZ3dXZ3eXh5dnR4eHV2eHt8e3l1d3d1dndz
dXV2d3Z1eHh0dXR2d3V0dnNxcXFvb29yc3FucnJycW9ycnBvbG5ycXF0cnNyc3Nz
cnFydHFvcHFycnNucXJvb3FzcHBxc3NxcG1ucG9wb3NxcXJwa2xtbXFwbnJtbnFv
b25uamtqbG1scHJwa25tbXBycG9tbW5vbnBvb2xtb2xxbmtsbGtpamtrbGtnamlq
a2pnaGhmZmptaGhoaGxqaGhpaGhpaWlpZmVkZWdoZ2lmY2RgYmhmamdlamdhYWNg
X2BgYmNhYV1eYWFmZGRkZF9cXWBgX19fY2NdYWFiYWJhXl5kYWJhXF5eX19hYmZi
Xl1gYmJiYV5iY2FhYmRhX2BlYWFiY2FfYWJhYmRjZGJeYmNmZGBhYmFaWVpaXFtZ
V1ZUU1NSVVVXWVNSUE5NT1JPTk1NT09OUlVOTk1PU1NRU1JTVFRRU1NWV1dXWlhb
W19bX11cX15fXFpeXV1dXV9fX15hYGBhZWJhX2FhYGBeXmFmZmJhYV9fYWFeXl1b
XFxcXWJgYGFgXV5eW1peX2BgYF5iY2RiYV9gYmFhX2BhYmNiYWBhYWJfYWFfYF1f
YWBgY19fXV5kYVlcX2FgYF1eW11gX15dXGBgX11hXltbW1teX2FdX15cW11cXF1e
X2BfYGRmW1tfYFxeYWNiX15dXmBcXF5gX2RfW2BjYmFhY19bWl9hXl9hYmBeYWVk
YmRiYmNjY2NjY2FjZGNgZGJjYmBfX19eYmJeXl1eXF5gXV1dXV1cXFtbW15fXV1e
XlxdW1xeXmBbWVpYVltgYF5dXV1eWVlbW1xZVlZVWFhcXl1aWllWWllbXVxbWFha
WFpbW1lZVldXVVZdV1daW1hYV1hVV1hTV1VUWFlXVVNVVVJSVVVWVlJWVlZWVFRW
U1VVUlVUV1RWUlJYVldXVFdcXVlYV1JQVVlTVVZXV1ZTU1dYV1VUWV5bV1RWV1pY
WFlbWldZWlpaWFdZXVlcXlpcXFlcWltfW1hZWltZXVteWFRSV1hZWlpZWFhXWFla
WFheWVtZV1laW1tcWFlcXF1eXVtYWlpbXF1dX1xbWltcXl5hYVtZWl5ZWVxeXV5d
XltaVlhaWVxcW1pbXV5eXlxdXV9eWllbW1tfXlxeXWBeXGFeXl5gX2BfXlxgY2Ji
YWFhZWJgXWBfYV9dXl1cX2BeXl9eXFtcX19gX15hY2NgY2NnZWFjY2FkZGJjZGJi
Y2BhYmNkY2NhYWJjZWJiYGJkY2BhZWVmYmRkZmVmZGNiX2FkZGNkZGJjZWRlZGJi
YmRjYmhjYGJmaGlmY2NnZWhlaWtramhmZmZqZGhpaGZnZmRnaGloZGhqbW9tamdp
bGtubGlsbmxpbW9wbGtra3ZoZGdpamhnZmhpaGhtbW1ra21qaGt+psnk8Pr+////
/////3ZnbnV6fHh2eHp7fHx6d3h3dXV6eHd5dXNzc3h5eXl1d3d3d3h2dnd0dXR0
d3h5eXh6dnV1cXR1dHV1dHR2d3h3d3p4enp5c3Z3dXV0dXl4dXV4eXt5dnZ0dnp5
eHZ4dnd1dnNzdHJ4fHx8eX16eXh2dnR0dHV2eHV0eXRycnB0cnNwc3dzb3FvcXNv
b3Fyc3Bxc3JwbmxucXJycnRzcXBwdHV1dnVzdHJvcnFycnZxcXFxcXJwb3BvcXRw
bXFvbXBubGpwcXFtbG5ub25xcW9rbG1tbGxta2xrcnRxcm5qaWxra25wb3Byc3Zw
b2xsbWtub21ra2xpam5tbG9ybGxrampramlpbHVza21maGxqaGhnaWxrbHBsa2tp
amhnZ2ZmZWViYGNjZmRjZWRoZ2VhX2JjY2JiYGFhYGBfY2dnY2FiY2BiX19fX2Fh
YWJgY2JjYGFgYV9dXF5fYFxfYWJkYmJeX2BiYmFiYGFkZGJfX19iZGlhYGBkZGJj
YmRlZWRhYWBhYmBcXV1dXVxbW1xbW1ZXVFBXVFNUUFRUUk5RVldQT1FPTkxMT1JR
UFFRUFBRU1NRUFBRU1RRUlRVUlNWWFhaWV1eW1tdX2BgXllYXV1bXWBgZWNgYV9g
X2JfX2JlY2VmZ2RmZWZiYl9fX19hX2BeW15hYF9dW15gYWRiXVlbXF9hYmNjZWBm
YmFdY2RkYWFhXV9gZGFhY2JeY2FeXmFgXl9iYl5dYGFcX15dYF5dXVpZXGBfXl1d
W19gYF9cXF1cXl1bX2JeXl9aW11cXF5fYGBhY2ReYF9dYWFjYmFfXlxcXVtdXlpe
X19lY2NgYWBeYmJdXl1hY2JiYl5fYGBhYmRkZGJjY2JjYmJiYGFiYmBfXV5eXV1g
Y2VgX1xbW1teXVpZW15fXVxeXVteW1lZW1pcXFxfW1tZWmBeWl1eXV1eXlxYWlxc
WlhZWFlYWFdbWltdWVlZXFlaW1xaWFdYXFtaWFhYVVZZWVhYWVdWVVZZWFxXW1lU
WVhVU1dXU1JVVVZYWVlaWllYWVZWVldWV1hWVlhXXllYV1ZYVlZVW1lYWFRUU1RX
VlZYWVlYWFhTWFZYW1xaW1lYWVtZVVZXWVpXWltZXFxaWFpXWV9fWltYVVhdWlla
WltZV1hYWVxbV1hWWFxbWl1cWlddWVlbW11aV1daXFlZW1xbWlpeW1pdW1lXW11e
W1tbXFhaXl1bX19cW1tcXF5cXF1aV15eWlpbWl5cXlxcWltcXFxbWlpcXFxdXV1i
X1tcX11gX2BhYWNhYF1eYmJfXmFnZWBeX2JeX2FfX2FjYWNeX2BfYmRkYWBfXl1f
YmNgX2BiYGFhYmNmZmZlZmRjZGVlZWZkYF9kZGNfXl9gX2BjZWVlYmJhZGJlZGJl
Y2JkZmRjY2ZnZGVkaGZlamJiYGRlZGNhY2hoZGNiaGVpZmtpZmBkZ2plYmRnaWdl
ZWdpZGZnaGdkZGlta2pqaGlnZ2RoamlmZ2pta2lqa2tqbG1sbGtqZmtsamhqbGlr
aGloa2dnbmpwZ2lra3uly+Hv+P7/////////cHR9e3x6d3Z3eX16eXh3d3p6dnh3
e3l0dnVxc3Z3dnd5dHV2eXh1c3N0d3Z4eXl8fXyAenl4c3RzcnJ2enZ2dnV0dnl+
e3d0c3V2dXR4eHh2dnZ1eHZ2dHh4d3V3dXR1dnZ1dHR0dHd3eX97eXl2d3R1dnd2
dnd5c3JzdXJ1c3Z3dXZ2eXRwc3FycHBwbnBvbnB3dXV1c3RwcW9ydXJzcnR3eHZ1
eHR0dXRzb29wc3FwbXBtb21ubWxtcnNxbm1rb3Fubm9ubm5vbmlqbmxpamxvbW1s
bm9vb3FycHJsamtra21rbW1vcG5xb25tbGlpbWttbmxsbGxpa2hoamtrbWxqamxt
bW9ub21rbnBoamdlZ2ppbW5tbW1vbmxqZWdmY2VlZGNjZWZlYmVjZGBiZGBfYmJp
Z2NkZWNgX2NjYmNhX15lZWBdYF5iXVxbYWBgYmJgYF5gX15cX19jY2BeXmBfYGJi
YV9gYmFfYWJjYF5gY2RiX2FdYWJlZGRkZWVmZ2NhX2FhXmNiXVtcXV1dXVxaWFZX
WFVUUlNTU1VTVVNVT05QUFFNTU5MTU9RT1JTUFBRU1BRU1VUVVVTU1NWVFZaW1pY
WlpaX11eX15cXVxdXlteXF5hZF9fX2BiYWFgXmBhYmJiZGVkY2RjYGBfXWBiXVxg
YWJhX19jYF9hYGFfXFpbXWJjYmFgYGFiYmNiY2VhXV9fZmNkYWFiZGNjYF5cXVtb
Xl5eX2RkZF9eXF5dYF5hXlxbXFlYW2FiY2JfYlxZXl5dXV9dXV5gXl1cW1tbWVpd
Yl9fYl9eY2FdXV5eXlxdXFtbXmBgYGJiYmhlX2FeXl5fYF9fX11fYGBiYGFiYWFl
Y2NiYmBiYWJnZ2FfY2NgX2JkYmNlYl9fYFxdXV5fXVxZWlpdXF1cYF9gX19eXlla
XWBiXlxYWFxcXVtdXFpfXmFgW1lbWlpYW1pbW1tZWFtdYF1aWVpZXWFfWFZUVlZX
WVtaWFZWWVZUV1dYWFVUVFZVWFxcXVtaW1hWVlVUU1ZXWVhbWFlWVFhaW1lYVlVU
V1pYVllZWFdaW1pYWFtVVlpcWlRUWFdXWVlWWVtbW15YWVtbXFtXWllWVVdZVlZY
V1hZWFlYV1daVVZZV1tcXF5cW1paWVheXl5dW1xcWVpbWFhXWllYW1hZXlpWXFxc
W15aWVpZWllZW15dWlxbW1lbXVxaXF5cXFpaWlpbXVtcXFxcXl1aWFpcYWNfXFxc
XF1dX2FaWVtaWVpbXVxbVltaWVpfXF1cYWBeYWFeX19dX2FfXmBfX2NqZGFfYGJg
YGBjY2VhYGFmZGFgYWJgYV9eXl5fYmNiYWJiYF9eX15gYGBiYGFjZGNjY2JjZmdj
ZGFhX2JfYGJhY2RjYWRjYmNiZGBkZmZmZWRkZmVmZmVlZGlmZ2lpaGZmZWdkZWRl
aWhjY2FjZmNmaGlnZmtqZ2dkZWdkZWVkZGdkZ2hpamhoZ2ltZmZnZWVlY2dpamtr
a25wbWppbW9vcHFxb2xxbGxva2xoamlpaWprbGprb21mZ2h3gqDN4u/3/f//////
//9ueHx9fnx5eHl8eXp7fnl4eX14e3l5d3l3dHV0dXZ4dHZ1c3N0dXRzdnR3eXd4
dHV6e359eXd4dnZ5d3d3dXZzdHZ0eHh3d3h3dXh1cnB0c3R2d3Zyc3R4enp3eXh4
dnd2d3p7e3x6dXh2eHd2dHd5dHR0dXd5d3V0dXR1dHRzdnZ3eHhzdHd4eHJxbmxu
b29wcnJzdnV0dXBydnNxcHFwcnV2dHd1dHV3dXRycnRzdHFtb3FxcXBubm9wbG9w
b29vbnFycXBsbW1xc3Jtbm9ubW9ubWxtb25wdG9tbm1wcWttbW5sbWtwbnFsamps
bGtoaWtvcW9tbGxsa25vbWtoaWtsa2psa2tpbWxqbGloZ2loaWtsbG5tbGxraWlq
a2lnZWVlY2JiYGJnY2JkZV9hY2JjYmBga2dhYWNkY2ZkYWBfXmBgXlpdYl9bW11h
ZGRhX19fXGFcXWFfX19hXmBhYGBiZGZlY11cXWNkY2ZmYmJgXl9eXmFhZGFjY2Nm
Z2hmZGJjYl9eYGNhXl9eXFpcXVxbXFhWU1FRUlNSUE1OUFFNTE1NTUxPT0xKT1JY
U1JSUE9SVFZTUlJTVVdZWlhZWlhZWVhdXF9hXV9cXVxeYl9dYWBdXV9gYl9fXmBg
ZGNfX2NjY2NkYl9jYGFjY2FfYV5gYV9gY2JhYV9lXWBiXmFjX2BfXV9eXF5dX2Bf
ZWNkZWhmX19dYF9jYmFfY2NhXF1dYV1dXFxdXl9gYGFdXGBeXmFhXFtdXVxcXl5g
YmFeXVtcYGBcXl9dYFxfXl9fXl9eXV1eYWBeXVxdYGNhX2FfYWFgYV9eYGNgYWJj
X19gX11cXl5dXl5hX19hYWFkZGJiZGNiYmJjYWFjY2FfXmFkY2RlZmdhX2BhXmBi
ZGRiY19dXVxZXF1eXV1gYV9eYl5hX19eX2JdWl1cXVxcXmFeXF5eXV5bXmBkXFla
WFtbWltbWllbW1hbWVlZWltZW1hXWFdaWlpZW1tVVldYV1ZXWFRWU1NWV1hYWVpY
V1hWVlRTV1ZXVlVTUVNaVlVUWFdVVVNUWl5bWldYWFpbWlhZV1ZYVldcWltaWVdY
WVdVV1lbW1hXWFpXVVZWVlVUV1dZVVVVVVZVWFpXVlhaWlpYWFtaXWFdWllZWltb
W1pbW1lYWVxZWFhUVlhZXF9bWVtYXFxcW1pdXV5YWFlXWltcWldaWVlbW1pXV1pa
W15hXVxgXVlZW11aW1laW11bXF1ZWmBcXFxdXF9cX15aWlpZXFteWl1gYl9hW1la
Xl1eXV1eXV9dXl1dXV9hYGFhX11dX2BgX2RlZWNlYl9hYWNgX2BfW1tdXV9iZGJg
YF9gYGNiYGFjZ2FgZGFgYWVhY2ZkZWdgYGBmZGFgYWFiYmBfY2RlZWRkZGVkYmVn
Z2RnamdoZ2VjY2ZnZGJiZmplZmVlaGNkZ2ZmZWFiY2ZmZ2trbGtpZ2hqa2xqaGZn

View File

@ -0,0 +1,120 @@
5eXl5uXk5eTl5eXl5eXm5eXl5eXl5ebl5ufl5efl5ebm5+bm5ubm5ebm5ufm5ufm
5uXm5+bl5+bl5ufm5+bm5ebn5ufm5ubn5+bm5+bm6Ofn5+fm6Ofn5+jn5ubn6Ofn
5+fm5+fn5+fn6Ofo5ujo5+fo5+fn6Ofo6Ojn6Ojn5+nn5+fn5+jn5+fo5+fo6Ojn
6Ofn5+np6Ofo5ufo6Ojn6Ojn6Ojn5+no5+bn6Ofn5+fn5ufn5+fo5+fo5+fm6Obn
6Ofn5+jo6Ofo6Ojn6Ojo6Ono6eno6ejo5+jo6Ojo6Ono6Ono5Ofo6Ono6ejo6Orp
6ejp6enp6Ojo6Onq6Onp6ejo6eno6enp6eno6ejp6Onp6enp6unp6eno6Onp6unp
6ejp6enq6ejp6unp6enp6Ono6eno6uno6enp6Orp6enq6uno6unp6enp6erp6Orq
6Onq6eno6unp6unp6urp6urq6enp6urq6uno6urp6erp6erq6urp6urq6erq6uvr
6erq6enq6ejq6urp6uvr6erq6urp6unq6unq6Orp6+nq6unp6err6unp6+rp6urp
6ejq6erp6enp6erp6erp6eno6ujp6unq6+rq6urp6+vq6uvr6urq6urp6+rq6urr
6+nq6unq6urq6uvr6+rq6uvr6+rq6uvq6+rr6urr6uvr6+vr6+vq6+vr6+zr6+vr
6+zr6+rr6uvr6+rr6urq6+vr6uzr6+zs6+zs6+zr6+zs7Ovr7Ozr7O3r7Ozs7Ozs
7e3s7ezr6+3r7Ozs7e3t7O7t7O3t7ezt7u3t7u3t7u3t7+/t7e7u7+7u7+3u7+7v
7u7u7u7v7+/w7u/v7/Dv7+/w7+/v7u/w7+/w8O/w8PDw8PDw8PHy8PHw8PHx8PLx
8fLx8vGVjoV7dW1kYmJYVlRVVFRWVldZW1xdYGJjZmlqbG5wcnZ3en1+gYKFh4qL
jY6OkZKTlJaXmZqdnqGjpqipq6yur7Gxs7S0tLa2uLm5u7u9vr7AwMHCw8PDxsbI
ycrJy8zNz8/S09PU1dfX2dnZ2dja2tra2tvb2tra2tvb29rb3Nzd3d3d3t/e3d/f
3t/f39/f197f39/f3+Df39/e3t7e3t/f3d7d3t7e397e39/e3uDg4ODg4OHh4ODg
4d/f3+De3uDf39/g3d7d3Nza29va2tja2tnZ2NjW1tjX1tbW1tXU1dXV1dXV1dXV
1dXW1dTT09PS0tLS0dHS0NHR09PS09LT0tTU1NPT0tPT09TS09PT0tLR09PT09PT
09TU1NTU1NTU1dXV1dXU1dXV1dXV1dXW1tXX2NfX19fX2djZ2dnZ2drZ2tvb2trb
29vc29vb29vc3Nzd3N7d3d/e3d7e397f3t7e39/f3uDg3t/g4OHg4ODh4d/h4OHh
4OHh4eHh4eHi4uLi4uLj4ePi4+Li4uPj4+Pi4uPj4+Pj4+Ti5OPj4+Xj5eTk5OTk
5OXj5OTk5OTk5OTk5OTj5OPj4+Tk5OTj5uXl5OXl5OTl5eTl5OXl5ebl5ebk5eXl
5ubk5OXn5ubl5eXl5uXl5+Xk5eXl5ebl5ebm5ubl5uXm5ufn5uXn5ubn5ubm5+fm
5ubl5ubn5ufm5ufm5ujn5ubn5+fn5ufm5+jo6Ofn5ubm5+bm5+fn5ufn5+fo6Ofo
5+bn5+jn5ujn5+fn5+fo6Ofo6Ojn6Ofo6Ofn6Ojp5ufo6Ojo6ejn6efn6eno6ejo
6Ojo5+fn6Ojp6Ojo6ejo5+no6Ojo6Ofo5+fo6Onp6Ojn6Obn6Ofm5+fn6Ojn6Ojo
5+jo6Ojo5+jo6Ofo6Onp6Ojo6Ojn6Ojo6Ojo6eno6ejo6enp6Ojp6ejp6unp6Onp
6enp6Onp6Onp6eno6Ono6enp6enp6Ono6enp6OXp6Ojq6ero6unp6unp6enp6unp
6unp6eno6enp6urq6enp6enq6unq6enp6erq6urq6unq6unp6Orp6enp6erq6erp
6erp6urq6urq6enq6+rp6urq6unp6ujp6unq6enq6evq6unq6unq6uvq6unq6urq
6+vp6ujq6unq6urp6unq6unp6+rq6evq6urp6unq6+rq6urq6erp6urr6+nq6urp
6unq6+nq6erp6erq6erq6erp6urq6urq6evq6enp6enp6ero6unq6+nr6urq6+rr
6urq6uvr6urq6+vr6+vq6+zq6+vr6+vq6urr6+rr6+vr6urr6urq6+zr6+rq6+vr
6+vr6uzt6uvr6+vr6+vr7Ovs6+vs6+zs6+vs6+rr6+rr6+vr6+vr6+vr6+zr6+zt
7Ozr7Ovr7Ovr6+zt6+zs7e3t7O3s7O3t7ezt7O3t7ezs7O3u7ezt7O3s7u3t7e3u
7ezu7e3u7e/u7u3u7+3u7u/u7u/v7u/u7+/v8O/v7+/v7+/v8PDv7/Dv7+7v7/Dx
8PDw8PDx8PHv8fHy8PHw8fDx8fHw8fHy8vLy8qOdlpGLhH56dXRycHFxcnR1d3l6
fH+ChIeJi42PkpSWmZyfoaKmqKqrra+vsLK0s7W3uLm6vL2+wMLExcfGyMrKzczN
zs/OztDQ0tLT09TV1tbW1dfY2NfY2dra2trc3Nzd3N7e3t7e39/f39/f4ODg4ODg
4eHg3+Hh4eDg4OHg4ODh4uHh4OHh4uHh4eHj4eHi4OHh4uHi4eDh4eHg4eHh4eHi
4eHg4eHg4eDi4eLg4eLj4+Li4+Li4+Hi4eLg4eHh4uHi4uLh4OHg4eDh4N/e4ODf
4ODf397e3d/f3d7f393e3t/d3t7d3d7d3d3d3d3d3tze3d3c3tzb3d3d3Nzc3N3d
3d3e3d3d3d3d3d3d3t7e3tze3d3e3d3e3dzf3d7e3d7d3t7d3t7e3t7e3t7e3t7f
3eDg3+Df4N/f4ODf4N/g4N/g4ODh4OHh4eHg4eDi4eHi4OHh4uHh4uLh4eLi4uLj
4eLj4uLj4+Lh4uPj5OLj5OLj5OPk4+Tk4uPj4+Tj4+Ti5OPk4+Pj5OTl5OXj5OTj
5OPk4+Tk5OXk5eXl5eXl5ubm5eXl5eXm5uXk5eTl5ubl5eXk5Obl5eTj5OXl5OTl
5uXm5ubl4+bl5uXl5ebk5uXl5eXm5uTm5ubn5ubm5uXn5ubm5ufl5ebm5uXm5+Xm
5ufm5+fm5ebm5ubn5ujn5ubl5ubn5ufn5ufn5+fn6Ojn5+fn5+jn5+fm5ufm5+fo
5+fn5+nn5ufn5+bm6Ofm6Ojn5+jo6ejn6Ofp6Ojo5+jo6ejo6Ojn5+jp6ejo6Ojo
6eno6Ojo6Onp6efn6ejo6Ojo6ejo6enp6Ojo6ejo6eno6ejp6eno6ejo6Ojn6Ono
6Ojp6enp6Ojp5+fo6Ojn6Ojo6ejo6ejo6enp6Ofo6ejo6ejp6Ojo6eno6ejp6erp
6Ono6Ojo6eno6eno6enq6erp6uno6ero6Orp6unp6erp6unq6unq6urp6uno6ero
6Orp5eno6erq6urp6unp6erp6Onr6erp6+nq6unq6enq6+nq6urp6urq6erp6urp
6urq6urq6urq6urq6+rp6+rq6uvq6Orq6unr6urs6urr6urp6unq6urq6urq6+rq
6erp6urp6urq6urq6urq6err6err6+rq6+rr6urq6+rr6urr6urq6+vq6uvq6+zq
6urr6uvr6+vq6+rr6urr6uvq6uvq6uvq6+vr6urq6err6evq6uvr6urr6urp6urq
6+rq6unp6urq6urq6urq6uvq6urq6+vr6+vr6+vr6uvs7Ovr6+rq6+vq6+vq6+vq
6+vq6+vr6urr6+zq6uzr6+zr6uvs6uvs6+zr6+zr6+zs6+vr6uzs7Ozs6+vq6+zr
6+zs6+zr6+zs6+zs7Ovr7Ovs7Ovs7Ozs7Ozs7Ozs7O3s7Ozs7Ozt7O3s7Ozs7u3t
7e3t7O3t7e3t7e3t7u3u7e3u7e3t7e3t7e7t7u7u7u7u7u3v7u3v7+/u7+7u7+7w
7+7u7u/w8O7v7+/w8O/x8PDv8PDw8fHw7/Dv8fHx8fDx8fHx8fHx8fHw8fHx8vLy
8vLxs6+qpqGcmJWRkI6Oj5CQkZOVl5mbnaCipKepq62wsrS2uLu9vsDDxMXGx8jI
yszNzc7P0NDS0tLU1dXY2NjY2dnc3Nvc3Nzc3Nzd3d3d3t7e397e4N/f39/g4eHh
4OLg4eHh4eHi4eLh4uDh4uHi4eLi4uPi4+Hh4ePh4uHi4+Lh4uLj4uLi4uPi4uLj
4uPi4uLi4uLi4+Pi4uPi4uHi4uPj4uLj4uLi4uPh4eLi4uLi4+Li4+Pj4+Li4+Pj
4uLi4uLi4uPi4+Lh4uHi4uLi4uPi4eHi4eDh4eHf4eHh4eLi4OLh4ODg4eDh4eHh
4eDh4eDh4eLf4eHg4N/h4ODi4ODg4OHh4eDg4OHh4eDh4uDg4uHi4eLg4OHh4eDh
4OHg4uHh4eHh4eDg4eHi4eHi4eHi4eLh4uLi4uHi4uLi4uPj4uPj4uHi5OPk4+Pj
4+Pj4uPk5OLi5OPj4+Pk5OTi4+Pj5OPk5OPj5OPk5OPk5OTk5OXk5OTk4+Tl5eTk
5eXk4+Tk5OTk5OXk5OXl5eXk5eXm5eXk5OXk5uXl5ebl5uXl5ubn5eXm5ubl5ubm
5uXl5eXm5uXm5uXl5eXl5eXk5eXm5uXl5ubn5ubl5ubl5+Xm5ubm5ubn5ubn5efm
5+fm5ubn5+fn6Ofn5+fm5ufo5ubn5+bm5+fn5+fn5+fn5+jm6Ofn5ujn5+fn5+fn
6Ojo6Ojn6Ojn5+jo6Ofn6Ofo5+fn5+jo6Ofo5+jn5+jn5+jn5+jn6Ojo5+jo6Ono
5+no6Ofo6Ojo6Ofp6ejn6Ojo6Onn6Onp6enp6eno6efo5+jo6Ono6Ojo6enp6Ojo
6enp6enp6Ojq6Ojo6eno6Onp6ejp6unp6ujq6unq6enp6Ojp6Orp6Onp6enq6enq
6eno6Onp6eno6ejp6eno6Onp6erp6ejq6eno6erp6enp6enq6urp6Onq6unp6urp
6+nq6enp6enq6unp6erp6+nq6enp6unp6enp6erq6unr6uvq6erp6+rp6erp6unq
6urq6urp6urq6err6uvq6urq6urp6+rq6uvr6uvq6+rp6urq6urq6uvp6+nq6urr
6unq6+vq6+rr6urq6urq6uvq6urp6urq6urr6urq6urq6urr6+rr6urq6uvq6urr
6uvq6erq6uvr6+rr6urr7Ovq6uvr6+vr6+vq6+vr6+rq6+rr6+vr6urq6+vr6uvq
6uvq6+vq6+zq6uvr6+rq6uvq6+rq6urr6+vq6urq6+rq6urq6uvr6+vq6+rq6uvr
6+zr6+vr6uvr6+vr6+vs6+vr6+vr7Ozr7Orr7evr6+rr6uvs6+vr6+rq6+zs6+vs
7Ovs7Ozs7Ovs6+zs7Ozs7Ovs6+zs7Ovs7Ovs6+zs7O3s7Ovs7Ozr7Ozr7Ozs7Ozs
7O3s7O3s7e3t7Ozr7Ozs7uzt7ezs7O3t7uzs7e3t7uzt7ezu7e7t7u3u7u7u7e7u
7e7u7u/u7u/v7e/u7+7v7+/v7u/u7u/w7+/v7u/w7vHv7u/v7vDw8PDw8PHx8fHx
8PDw8fDx8PLx8vLx8fDw8fHy8vLy8vLy8/MAEAEAAAMAAAABBJcAAAEBAAMAAAAB
Bt4AAAECAAMAAAABAAgAAAEDAAMAAAABAAEAAAEGAAMAAAABAAEAAAERAAQAAAAQ
AB+FwAESAAMAAAABAAEAAAEVAAMAAAABAAEAAAEWAAMAAAABAG8AAAEXAAQAAAAQ
AB+GAAEaAAUAAAABAB+GQAEbAAUAAAABAB+GSAEcAAMAAAABAAEAAAEoAAMAAAAB
AAIAAAFTAAMAAAABAAEAAIdzAAcAAASkAB+GUAAAAAAAAAAIAAH9gQAD+voABfhz
AAf17AAJ82UAC/DeAA3uVwAP69AAEelJABPmwgAV5DsAF+G0ABnfLQAb3KYAHdof
AAH9eQAB/XkAAf15AAH9eQAB/XkAAf15AAH9eQAB/XkAAf15AAH9eQAB/XkAAf15
AAH9eQAB/XkAAf15AAGq2yWAAAAAIAAAJYAAAAAgAAAAAASkYXBwbAIgAABzY25y
R1JBWVhZWiAH0wAHAAEAAAAAAABhY3NwQVBQTAAAAABub25lAAAAAAAAAAAAAAAA
AAAAAAAA9tYAAQAAAADTLWFwcGyYcjd2/nI/x5EwPxA3BfUzAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAVkZXNjAAAA5AAAAEF3dHB0AAAAwAAAABRrVFJD
AAAA1AAAAA5jcHJ0AAAEYAAAAEFkc2NtAAABKAAAAzZYWVogAAAAAAAA81EAAQAA
AAEWzGN1cnYAAAAAAAAAAQHNAABkZXNjAAAAAAAAABVTY2FubmVyIEdyYXkgUHJv
ZmlsZQAAAAAAAAAAAAAAFVNjYW5uZXIgR3JheSBQcm9maWxlAAAAAG1sdWMAAAAA
AAAADwAAAAxlblVTAAAAKAAAAw5lc0VTAAAAMAAAAYpkYURLAAAAPAAAAjZkZURF
AAAAOgAAAeJmaUZJAAAAMgAAAMRmckZVAAAALgAAATBpdElUAAAALAAAAuJubE5M
AAAAKAAAAnJub05PAAAAKAAAAbpwdEJSAAAALgAAArRzdlNFAAAAOgAAAPZqYUpQ
AAAAGgAAAV5rb0tSAAAAGgAAApp6aFRXAAAAEgAAAXh6aENOAAAAGgAAAhwAUwBr
AGEAbgBuAGUAcgBpAG4AIABIAGEAcgBtAGEAYQAtAHAAcgBvAGYAaQBpAGwAaQBH
AHIA5QBzAGsAYQBsAGUAcAByAG8AZgBpAGwAIABmAPYAcgAgAEIAaQBsAGQAbADk
AHMAYQByAGUAUAByAG8AZgBpAGwAIABHAHIAaQBzACAAZAB1ACAAUwBjAGEAbgBu
AGUAdQByMLkwrTDjMMowsDDsMKQw1zDtMNUwoTCkMOtjg2PPVmhwcJaOgnJfaWPP
j/AAUABlAHIAZgBpAGwAIABHAHIAaQBzACAAcABhAHIAYQAgAEUAcwBjAOEAbgBl
AHIARwByAOUAdABvAG4AZQBzAGsAYQBuAG4AZQByAHAAcgBvAGYAaQBsAEcAcgBh
AHUAcwB0AHUAZgBlAG4ALQBQAHIAbwBmAGkAbAAgAGYA/AByACAAUwBjAGEAbgBu
AGUAcmJrY89O6gAgAEcAcgBhAHkAIGPPj/Blh072AEcAcgDlAHQAbwBuAGUAYgBl
AHMAawByAGkAdgBlAGwAcwBlACAAdABpAGwAIABTAGMAYQBuAG4AZQByAEcAcgBp
AGoAcwBwAHIAbwBmAGkAZQBsACAAUwBjAGEAbgBuAGUAcsKkzpCxCAAgAEcAcgBh
AHkAINUEuFzTDMd8AFAAZQByAGYAaQBsACAAQwBpAG4AegBhACAAZABlACAAUwBj
AGEAbgBuAGUAcgBQAHIAbwBmAGkAbABvACAARwByAGkAZwBpAG8AIABTAGMAYQBu
AG4AZQByAFMAYwBhAG4AbgBlAHIAIABHAHIAYQB5ACAAUAByAG8AZgBpAGwAZQAA
dGV4dAAAAABDb3B5cmlnaHQgMjAwMyBBcHBsZSBDb21wdXRlciBJbmMuLCBhbGwg
cmlnaHRzIHJlc2VydmVkLgAAAAA=

View File

@ -0,0 +1,136 @@
TUxOT1JVUFNUVlVRT1VYWVdXUlJUT1FPU1VPT01PUE9WVlFSUFJRTkxKTU1PTEtJ
R0JDR0RDQEBBQD8/PDs/PD0+Pz44NzY1NjY5ODw5OT08Nzk5ODs8QUNBQj9BQUND
QklLSk5KSU9TXlhLT0xWUlFaVFdMTVdVW1VgWVdWXV9dWFtWUlFSTkVERTk1NTUz
MzUzNjU0ODg1ODY2Nzk6PTo6P0NETE1JR1RSTFBISkpKVVVLSUpUTU5STVZRVFpT
Vk5XXGBYUFhVWFJTV19kXVdVUFdVVlZUW1xbWlhZV1pcWE9TWlRWWVlXUE1MTlJD
PDo8Ozo+P0pOTVhWVFJWW15oYFxbXlpUVlpZXFhYVVdXUFlcYFhUVFdaW1RQXVxc
XltXUVBSTU1RUVRYVVNNSU1RUFFWVFFST05QUk9OSU5QTk1KS1BVSkxLTE5LT1RO
VlRZWlZYVE1FRkVHR0ZLSU9LTlFOXWaJo7CspZ2WlZOJfXFmYmFqdG9eS0E+OTk4
ODtBQTw9Ojg5PD5EQT8/P0BAPDc6OEE+Pzo+QENAPDtBQENDRkNDR0A6QEQ8ODU0
MTQ3NTg3Mzc2NDg0OTs/RUpTS05JT1xYWVlUXFZWVVtdWVlXUE5TUlJQT1BUVlZR
VFVYW1NRTkxMUlZUUEtMTk9PTE1MSERESUpLSkxJRklJSUtLRkRJSEVCRENERUZE
QkNBQ0JEQ0FAPjk6PDo3OTc3ODU2ODY2NTc+Rk9YYmdqaGhna3B3e3x+gYGBgYaH
iYuKi4uKioWCfXdwbmpnaWlsb3eCiIuMjYmJjo6SkJCTl5ORjIaBfnZnVEc/Ojo6
ODo7P0RJSkxPUlVWWVhWVlVSVFFRT05JRkVARD5BPkBCRERDQ0ZGRUdFSUpKSkpK
SklOS0xNTkxOT05MS0tMTk9NT1ZWU1dZWl1eXWJkZ2hqbm91dXV4fH5/gYB/gYOC
hYmGiIiHh4iGh4qLi4qMjY2Li4uLjZKTlpeWlpSPjo+SkZOQkpGRlZiXlpaZmZuZ
mZibl5mZmJiampual5aYnKCpr7KqmImGiJWosbzAvLu5u7i1tbGwsbKzt7a8vcC/
vL29vr6/v7q8vLq8vrq4ube1tLe3t7S0ta2ysrK1tKyginBfXVhTUlBOTVBMTU9M
S0tLSUpLSkhJSkdPT05KSUdNS0lJSE1LSkxKTk9MTUtNSk9OTUxPUU5NUE9OT0xM
Tk5QUVFQUU9QUVJSVFVSUlNTU1JRTlJTUFBSVFRSUlFTT09RUlBSUVNTUU9QUVNV
VVVVUVFSU1FVU1JSUFFSU1hUUVFPUVRQUVJRU1NUVVZYWFZWWlhYVFFVWFhXVlhW
WFhaWltbWF5bV1dYVlhbWFZYWVlaWVlYV1laWVpZV1taWVlaWlpaWVtcXV1cXF1d
YF9dYF5dXV1dYF5bXV1cWlxWV1dYV1ZWWFdYV1ZZXIO9ydPa3uHk5efo6el7enh5
ent8eHd1dnl2dnh6enl4eXdwZ1pMR0VFSkVEQz09Q0hKQ0A/P0I/PEJCQT4+PTpA
RURFQ0RHQ0RBPT5ARkhJSkxMTk1JS05QTklKTk5QUVNUU1FXU1ddWVVRUFFTU1JQ
UlBQT0tRVVVVU1JSUFJNSktPT0tJSUhHREVFQ0dEQkNAPj0+PTw7Ozs6OTw2Nzk4
ODg6PDs5OTg3Nzs4Ojw7Ozw9PURBQkQ/RktGS0tISUpRVU5RTUpTT1lTV1VOVlNc
WV1cWVddY1xdXllPT1JVT0pAODc1MzU5Njc6OTs3Njg2NTc7ODg4OTg+Q0dPUEpH
VVRMUUxRSkpUTklOSVNSTU1KV1RSWlFYVFRVWVdNUFJeVFRVYWFdXVZQUVVYV1VZ
VFdYWVhZXGVhVlRbW1pXUU1LTFBMTkhAOTg6OTk7Q1BSVVldWFpeXmFhY2VjXlNR
U1BXWFVVUVZYWFdWU1NTVVZaV09WWVlaWlNQTUtOUE1OUlhZVFFXUE1NUFBQTlFS
UFJWTU1OS0pRSkVJUFBNSkpNUEtPVFVXV1lXVldXU0hGRUdJSVBJSUhOVE9RWnWU
qauroZiVkYl8c2xmY2VrdWlSQTs6Ozg7OTw8Oz08PDw7Ozw7PTtAPj09Pj1BQUJA
OTo+QUQ9OD1FQUM+RUJCOzY9Q0E4ODU0NDY2NjQ0MzI1Njg4Oz1ESkpISkpTWlhY
W1ZZV1hTVldOUVNOTE5OUlFQVFlYU01XV1dWU09MSktOUlRTUU1PT0xQTklFR0ZL
TU1LS0dHR0dJSkpGRUNGSExHQ0RDREVBQD9APz5AOzs+QD88Pjw4NjY0Njc5Nzg7
QUpTXmRmaGdoaGxwdHp7fXmBh4eHhoyQj5CNjYuJhYJ8dnN1b2xtbGtze4SJjI6M
iImOj5KUlpWVk5GQi4B3a11RRj5APkFAQUFCSEpLTVBQU1hYWFZWV1NRUlBQTkxJ
RkdDQT5AP0NDQkNARERJR0lJRkhHSUtQUE1MS0tNTExNTE1NT1FSUFBVVVVXWF1f
XmNjZGdsbG5zdXZ1dnt9f4CDg4F/goOFhYaGh4uHhoWJi4mKi4mIiouNjIuMkZGR
lpSUj5GQkpKSkpWTkpaXl5OVlpmbmpiYmZmZmJqWlZeYl5iZmp+jqrO5s6aTgXeB
mK64vby7urq9ure0srSztba1t7m9vsDDwr69vb+9uru+wL69vbi3tbSztbq1tLe4
rrOztrW1saylknplXFZUVVNPTU9PTk5NTU1NSkhISkpJR0lKS0lKUEpKS0xPTVBL
TUxKS01KTExMTkpPTktQUE5PT09QTU5NUFBSUlNST1BPT05ST05PUVFTVlJSU1NS
UlRTUVJTUVBRUU5RTlFSU1NQTk5NUFVTUlBSUVBRVFRTU1NSVFJQUlVUVlNUVFFS
UFNVU1JUVVVWVVZXV1VWV1dWVVVYWVhZW1pYWVtdXF5aW1hZWFZZWVhYWlpYV1dY
WFZXW1tZWFlYWVhWWVlZXFxcW11cXltcXltdXlxdX19dXl5bXVtbWFlYV1VXV1ZU
VlVVVVdgfLvJ0dre4eTm5+jp6nl7e3x7eHp6dnh5dnd4dXd4dnZ5cmlgUkhCQEJH
QEM/PkFCRERBQERDQz4/QkU7PD1CPkBBQUFAQEFDR0I9PENCR0dISEdJTklMT01P
UlFNUFBRUlJZVVVWV1ZUU1hSVFZVUlJTUlBRUVNTVFVSUFFOUE5NTExPTUtIREhH
RENDQkJFQj5APkE/Pz87Oj08Oz04Nzc4NzxBODQ1Nzc4Ozo6Ojg2OTs7Ozs+QT9D
SUdISEZGRkpQS01LRElHTEpLVVRaWVhZXFtZVlhgX1xXV1BVblVUSkA5NzQ1NDc1
NTQzNDQ0NDg1Njc2NTg7PD8+PkpJTUZNT0dPS1JNSFBLRkxIS0hLSk1UVFlgVl5X
UVJUVUxRT1ZVUlFZXVpWVFJTVllZV1dUVFtaWltfZl1VWFtcVlZVT0tTUElIR0Q5
NzY3Njk/SVJWWmxlWlxdWWBpYV9kV1JUUVJcWlhTT1NSV1pTVFNTVlVXVlZVWFJU
WlNPS01VVVpaWVVYV1VWUU5QTk5PUFVRTE1LS0xIRU5KSEpOTk1JR01MSVBVWlxT
VFhcWFpZTkdDQEFFS0VISElTUU9WYniWpqiooJeOhn92a2NgYGZwbV5JOzs/QkI7
ODs9OkA+PDw6OT1APj4+SDw6Oz4/QkA7O0A9Pz5CPDs8QTxDQkJJPzpBPzo8Ozg2
NzQ3NjczMjQ2Nzg7PT9HS0RJR01SUldSUE9OT01VWFJWVE5LTlFTUlBSVldSVFhW
VFJWUVBNTEhLTFJUTExNS05OSUZITE1LS0pKT0pGREVGRkdIRklKSUlERURCQ0NC
Q0E+PDk9QD9BPzw6ODo4OTo9Ojg5PUdQW2VqamlrbWttcnd6fH19fYKDiI2Ojo2N
jo6LjIiIhX58eXVzcW9sb3d/hIyOkI+Lio6QkZOYlpSTjYuHgXJkWE1IRD89QEJF
RUZMT0xPUVNUVlhaW1lXVVNSUlJPTUtNS0dDQUJEQkJDRUZGR0hFR0dHQ0dHSEtI
SEtJS05LS0xSUVNQTlFUUlVZWFlcXWFlZ2hsbW9zcnV8fH9+fX+AgYGBg4SEg4KD
hYOCh4eHh4eJi4qKi4uOjI2KjpGSlZWUmZaSkpeWkI6TmJWYmpiXmJiampuXnJmY
lpaZmJqYmZmbnJ2jrLGwsbSwopSDfIeXrLu/vr28urq4s7OzsrK0trW3ubu8v8G/
v7++vr27ur27vLy7ubW2uby7t7e1ube1tbe2tLW0sa+mmIFmWldXUlBRT0xOS0xO
TVJPTUtKR0lKTEpKTUpJSUlLTUxJTE1PUExJS0tNS0xOTU5MS0xLS09PUVFTUE9R
UFNSU1FRVFJNT09OTlBQUlNSUVBRT1JUVFFPUVRUUVNRUE5QUVFSUFFPSk5RUE9P
UVNTVlFRTFBPUVJSUlJRT09SUlBQUE9RUlJTVVVTVFVWV1ZYWFZYV1hVVVRTV1ta
W11bWVxaXV1aWlpcWllZWllaXV5bV1dXWFpZWldXWVpZVlVXWVlbXFxaXF9cX11f
XFxcX15iYWBdXFhaW1pfXFtZV1RWVllXU1NXW2Z9usjT2d/h4+bn6OnpeXp7enl7
d3t7enl6eHp4eHl1dG9rZFtRSkdDQkBAQUY/PEVESUREREM9QUFEQUVBPT9BPT8/
Pz8+QT5BRENHQkNFRkhJS0xNTkxQTE1SU1NQUlNRUlVWVVVZWlZVU1VWU1ZWVFJQ
VlJPUFNXWFZVU1RUUFFPTkxISEdJTEpGREJCQUBAQENHQj07PTo8OzU5Nzc4ODg3
Nzg1ODk4ODc5Ozg6ODk3OTk4PD5FQj5AQEBFREU/QlFPSklIR0dHSkxUU1xZUVVZ
YFhPU2BaV1RYUU9UWFZKQDo3NzI0NTAyNjQ0Ozg4Njc2Nzk5ODw6Ozo+S0ZLRUdF
Q1RMWlVMUU9KT0pPTFVWSlVTVFtTWlNUVlJSTFNOUlRQSlRUWVdaWVVSUldZWlVT
U1dUU1pdXFZXW15VVVVOTldSTUdHRzo2NzU2OTk+TV1eYmJYX11aYGleX2lYTVJR
Vl5gXFhRUVNYXFJSWl1ZVlFWWlJSU1JcVVhTTlhYWFNTU1lYVVhSTU9RUVRTT05F
SEhJRk9NS01OTU9KS1FJTFFRUlNUV1FTV1xdX1lRSERBQkJHRkpJRVJRU1dVYnqW
pKekno+Jg3pybWhkZW1yZ1BEPDw+PTs3PDpEQ0E9Ozs7PDs/PEdCOjk9Oz1AQkA9
QEFEQj06Ojw7PT9ASUhAPEFCPDg4OTczNDM2NDQ1MzU2ODk6PD5FRk1JUE5WXlJU
UkxMTFVVT1BSUFRVVk5ISlNVVVRWWFRUVltYWE9LTUtKSkxJSUhLTU9NSUlMTkxI
TU9NR0NHSElLS0xISkhKRkNBQ0RCREJCQz49PDtAPjw6ODg5PDs5Ozg2OkBLWGNo
am1tbWtubXB1enp7e36Bg4aGiZKRjo2NjY2LiIiFhoKCd3Vua25vdH2DjI6NjIyO
kpGQkpOVko+NiYN4aV5XU01LSUI+PUNHTFFSU05RUlVUWVtcXFZUUlFUU1FPTkxK
R0ZCQUBAQUFEQz5CR0pIR0hESUhHRElKSklLS05MUFJVU1JRU1VaWFxdX19iY2lr
bW9ycnR3enp5e318fX9/gH6Cg4SFgIOFhoeGh4mMiouOjo6PjY+MjY2RlJKSlJuX
lZSUlZaQkpKWl5qTk5aYmpqbm5yampyam5mWl5uenZ+lqK2ytby9tqmcmJiRjJit
uL6/vru6uLKuq62vs7a2t7e6u73BwcHAwcG/vcC9vLm4u7e4t7i4ur29urq4tre6
uLa5trWzs62onohtXFVUVFJRT01NS0tKS05RS0tKS0xPTklJS0pJSUdLTEtJTEpO
S0tHSUpNT05QTk5LS0xQTlBPUFJRTVBRTk9OT05PUlJPUlBQTk9QUFFRT1FRVVNU
VFRTUlFWU1JQU1JRUFNVV1RPT1BRT1FSUVNUU1JOTlBPUFBQU1RSUVBSUVNSUVNR
UVNVVFRTVVRWVFJTVlhXWVdXU1NTWFtbWl5dXFlZWFhZWFxYVlpYWFlbWVpZWVZX
V1dYWVhYWFdXVVRZW1pZWlxdW1peXl1cXGBgX19gYV9fW1pZW1lcW1hWVFVXVVlW
U1NVaoS8ytPa3uLk5+jo6el4eXh1eXh9eHt7e3t4eHZ1eHh0cm5jWEtLTEY/PTs8
P0NGSklGREVBOz0+RD9BRENAPkE/Oj0+P0A9Pz0+Q0NCQkRJSUlKSUtMTEpLTFBU
VlVUVlZSWVteXFpYU1RXWFlVWFlXV1VTVVJPUlZaVldTUVJRUVFOUE1KTE1LSElF
QUVEQkVCRUNERD8/Pjs8QDw6Ojo6Ozw5Nzk5PDc2NDQ4Ojg6OTk4Ojc4PEQ7Oj0/
PUNCRkNBSUtHSERJTEdKR1BLUVlVV1ZiV1BLU1JVVVZWU1RbWVBJQzo9NzY3NzYy
Mjc3ODg0MzU3OTk/Pjo8Oz1ERk9FRkVJSklXUkxWUVBRSlFPV1ZHTU9SXlVdVVdc
VlZMUk1QWVJRUFNZWF5eWU9PU1VWVFRSWFBPVllbWlZYWVdUVFFYXFhTUkxKQTo0
MjQ1OT5DVFhPV1paYFtgX15gX1FPUlRUWltbVlNPUVdWUlhXXVZVVldaVlNWVllZ
VFNPTVNRTVFPUlNUUVVUUlhVU1ZRS0lLRk1LSFFPTVFNTUpLT01LUlRMTVNVU1BU
V1tiWFVQSUNDQEVDSEhHVVJYWlBYXn6Ypqiil4qBfHp4cGttcHNtYFBDOz47Ojo3
OT07ODo7Oz88OjxAREA8Pj07OjxBQTw4PUFEQTxAPTtBRUVGR0U+QEI+ODUzMzc2
Njc4ODQxNDY3OTs8P0RKR0hSTlVfVVtRT09RU1VSUVJTU1JQS05OTVJXVVZUUVNY
VVRSTUxOSUtMSktKTEpJTEpKRkdLTE1NT01NSklJSktOTkpGREdGQUFERUREREI9
Pj4/Ozc5ODo5Njc6OTs5NzpBSlhja21vb3RxcHBucnp9eXl6fH+EhIWGjo2Njo+N
j4+MiYuLhH54cm5tb3BzfYaLjo6MjpKSkpORlJeWkpCHfnNrYVdWVVRMQj0/RE9V
UVJQUVFRVFtcXF1dXFlWVlZXV1FRTk9NS0VDQ0FBQUFAP0FER0dHR0dHSUhKSkxL
TEpJTlJOUFFUVlNWVltcYGBfZGhnaW5wcnR2dXh6eXt8f4GBgoKAg4GBgoODgoSE
iIiHio6Ni4+Sk46KjY6Qk5WVkpGUlJOSlpKSlJWTkpOYmJiYmZial5iZm5mZmpye
nZ+foKGip7Cyt7e5vLyznpKcn5aVorO5wcC/wLm2sa2rrK+zuLa4uL2/v768vMDA
wsG+wL68vra1tLK1tri8vbi6ubi2tre3tra1tbW4trGroY1tW1hUVFNNTk5KSktP
T0tLSkpMSktNTExLS0tLSkxKSUlMTUtLSk5JSE1OTk9MTE9RT0xNUFBRU1BPTU1P
UFBTUlFPUlFOUVNRUFFRUU9OUFFTU1NTUlNUVFJTUU5QUlJUVVRUU1ZST1BPUFFS
UVBOUVJPUFJSUFJRU1NRUFFSVFNSVFNUVFFRU1RXVlVXVFlYWFhZWFhVWFZUWFdX
XV1cWFdYWVdaWFdaVVVaWVlaWVdaWVlYVVdaWVlXWFlbWFdYWVpdW1xcXlpbX2Fj
YmBhYV9fX15cXl9aWFlVUFZWV1lYWVlXU1VvorzJ0tre4eTm5+jq6nl3d3l4d3h6
ent8fHh2dXN1d3NxbGFUSkdGSEM7Pj89QUhJRkZFQ0RFQ0JCQj09PTg8PUE7Oj4+
Qz0/QEFDQkVHR0pJSUxLTU1MTExLT1FSVFNTVVRVWFdXV1ZRUlNWVlVXWFlXWlta
VFZXWlxZV1VTVVBTUU1NTEtNS05MR0pMSEVER0ZISEVERD4+Ozs6Ozs6OTk6Ojc1
NTY5ODY2Njg2NzY4ODk3PDo4Pjw8PD9CRUFBPT5GRkVLTEZLTVFKSkxSW1daV11Z
SlJWVlNSV1pUU1dXVlZQQjo7OTU1NDMyNjc0NTZINzc3OTo8PT07QUJDUkpOS0hN
R1RRTlRQTlFIUFJVVEhSUVJgV1ZSWmFeYFJVTk5VUlJQV1lUVVZQSk5OUVZYVFBP
UFNUWV1XUlRZWFlXVFVcXlpWWFBCOTIyMzc2PUNNV01TWlpbW1paXl1VVFZXVVZZ
V1lcUk1OU1BVXVlaVlNTUVNYVVVbUk9VT05JTE9SUU9QUVZVUlNVWFlUS05LTFFU
V09SUFNSUVRNSkpNUk5OV1FNVFpSTlRcYVxYW1FKQ0JER0NFR0hTTFFUTlVWbYma
paOelImBfXx7dnRxcXBpWkY9Oj1COTQ5Ozs7QTk6Pzw7Ozs/QEJDPDo6PkBFPjtA
QkRFQjk6PUJGREZEQkFCRj04MzQ1ODk1NTM5NzQ0NTk6Oj49P0JFSFRRWFlSXFNS
VlZXVVRTU1ZTUFNNTU5PUFRUV1lRTk5SU09MTU5PUVBKS01MSkhIS0pJR0hDR0tL
TUtFSk1OS0tIR0VHRkhEQ0NGRENBPj89PT87PDs4Ojw4OTo4Njk9QUxZZG1vb3By
cnFzcnR2fH99eHh7gISHjJKJjpGRk5WSkpKOiomIgHx0cm5vcXV+hIeLjo+SlZiY
mJWUlZmSjIJ4cG1jVE5NTkxIQ0ZMVFhXVldUVldYXWBiX19gXFxbWlhXU1FPTk1L

View File

@ -0,0 +1,136 @@
TUxOT1JVUFNUVlVRT1VYWVdXUlJUT1FPU1VPT01PUE9WVlFSUFJRTkxKTU1PTEtJ
R0JDR0RDQEBBQD8/PDs/PD0+Pz44NzY1NjY5ODw5OT08Nzk5ODs8QUNBQj9BQUND
QklLSk5KSU9TXlhLT0xWUlFaVFdMTVdVW1VgWVdWXV9dWFtWUlFSTkVERTk1NTUz
MzUzNjU0ODg1ODY2Nzk6PTo6P0NETE1JR1RSTFBISkpKVVVLSUpUTU5STVZRVFpT
Vk5XXGBYUFhVWFJTV19kXVdVUFdVVlZUW1xbWlhZV1pcWE9TWlRWWVlXUE1MTlJD
PDo8Ozo+P0pOTVhWVFJWW15oYFxbXlpUVlpZXFhYVVdXUFlcYFhUVFdaW1RQXVxc
XltXUVBSTU1RUVRYVVNNSU1RUFFWVFFST05QUk9OSU5QTk1KS1BVSkxLTE5LT1RO
VlRZWlZYVE1FRkVHR0ZLSU9LTlFOXWaJo7CspZ2WlZOJfXFmYmFqdG9eS0E+OTk4
ODtBQTw9Ojg5PD5EQT8/P0BAPDc6OEE+Pzo+QENAPDtBQENDRkNDR0A6QEQ8ODU0
MTQ3NTg3Mzc2NDg0OTs/RUpTS05JT1xYWVlUXFZWVVtdWVlXUE5TUlJQT1BUVlZR
VFVYW1NRTkxMUlZUUEtMTk9PTE1MSERESUpLSkxJRklJSUtLRkRJSEVCRENERUZE
QkNBQ0JEQ0FAPjk6PDo3OTc3ODU2ODY2NTc+Rk9YYmdqaGhna3B3e3x+gYGBgYaH
iYuKi4uKioWCfXdwbmpnaWlsb3eCiIuMjYmJjo6SkJCTl5ORjIaBfnZnVEc/Ojo6
ODo7P0RJSkxPUlVWWVhWVlVSVFFRT05JRkVARD5BPkBCRERDQ0ZGRUdFSUpKSkpK
SklOS0xNTkxOT05MS0tMTk9NT1ZWU1dZWl1eXWJkZ2hqbm91dXV4fH5/gYB/gYOC
hYmGiIiHh4iGh4qLi4qMjY2Li4uLjZKTlpeWlpSPjo+SkZOQkpGRlZiXlpaZmZuZ
mZibl5mZmJiampual5aYnKCpr7KqmImGiJWosbzAvLu5u7i1tbGwsbKzt7a8vcC/
vL29vr6/v7q8vLq8vrq4ube1tLe3t7S0ta2ysrK1tKyginBfXVhTUlBOTVBMTU9M
S0tLSUpLSkhJSkdPT05KSUdNS0lJSE1LSkxKTk9MTUtNSk9OTUxPUU5NUE9OT0xM
Tk5QUVFQUU9QUVJSVFVSUlNTU1JRTlJTUFBSVFRSUlFTT09RUlBSUVNTUU9QUVNV
VVVVUVFSU1FVU1JSUFFSU1hUUVFPUVRQUVJRU1NUVVZYWFZWWlhYVFFVWFhXVlhW
WFhaWltbWF5bV1dYVlhbWFZYWVlaWVlYV1laWVpZV1taWVlaWlpaWVtcXV1cXF1d
YF9dYF5dXV1dYF5bXV1cWlxWV1dYV1ZWWFdYV1ZZXIO9ydPa3uHk5efo6el7enh5
ent8eHd1dnl2dnh6enl4eXdwZ1pMR0VFSkVEQz09Q0hKQ0A/P0I/PEJCQT4+PTpA
RURFQ0RHQ0RBPT5ARkhJSkxMTk1JS05QTklKTk5QUVNUU1FXU1ddWVVRUFFTU1JQ
UlBQT0tRVVVVU1JSUFJNSktPT0tJSUhHREVFQ0dEQkNAPj0+PTw7Ozs6OTw2Nzk4
ODg6PDs5OTg3Nzs4Ojw7Ozw9PURBQkQ/RktGS0tISUpRVU5RTUpTT1lTV1VOVlNc
WV1cWVddY1xdXllPT1JVT0pAODc1MzU5Njc6OTs3Njg2NTc7ODg4OTg+Q0dPUEpH
VVRMUUxRSkpUTklOSVNSTU1KV1RSWlFYVFRVWVdNUFJeVFRVYWFdXVZQUVVYV1VZ
VFdYWVhZXGVhVlRbW1pXUU1LTFBMTkhAOTg6OTk7Q1BSVVldWFpeXmFhY2VjXlNR
U1BXWFVVUVZYWFdWU1NTVVZaV09WWVlaWlNQTUtOUE1OUlhZVFFXUE1NUFBQTlFS
UFJWTU1OS0pRSkVJUFBNSkpNUEtPVFVXV1lXVldXU0hGRUdJSVBJSUhOVE9RWnWU
qauroZiVkYl8c2xmY2VrdWlSQTs6Ozg7OTw8Oz08PDw7Ozw7PTtAPj09Pj1BQUJA
OTo+QUQ9OD1FQUM+RUJCOzY9Q0E4ODU0NDY2NjQ0MzI1Njg4Oz1ESkpISkpTWlhY
W1ZZV1hTVldOUVNOTE5OUlFQVFlYU01XV1dWU09MSktOUlRTUU1PT0xQTklFR0ZL
TU1LS0dHR0dJSkpGRUNGSExHQ0RDREVBQD9APz5AOzs+QD88Pjw4NjY0Njc5Nzg7
QUpTXmRmaGdoaGxwdHp7fXmBh4eHhoyQj5CNjYuJhYJ8dnN1b2xtbGtze4SJjI6M
iImOj5KUlpWVk5GQi4B3a11RRj5APkFAQUFCSEpLTVBQU1hYWFZWV1NRUlBQTkxJ
RkdDQT5AP0NDQkNARERJR0lJRkhHSUtQUE1MS0tNTExNTE1NT1FSUFBVVVVXWF1f
XmNjZGdsbG5zdXZ1dnt9f4CDg4F/goOFhYaGh4uHhoWJi4mKi4mIiouNjIuMkZGR
lpSUj5GQkpKSkpWTkpaXl5OVlpmbmpiYmZmZmJqWlZeYl5iZmp+jqrO5s6aTgXeB
mK64vby7urq9ure0srSztba1t7m9vsDDwr69vb+9uru+wL69vbi3tbSztbq1tLe4
rrOztrW1saylknplXFZUVVNPTU9PTk5NTU1NSkhISkpJR0lKS0lKUEpKS0xPTVBL
TUxKS01KTExMTkpPTktQUE5PT09QTU5NUFBSUlNST1BPT05ST05PUVFTVlJSU1NS
UlRTUVJTUVBRUU5RTlFSU1NQTk5NUFVTUlBSUVBRVFRTU1NSVFJQUlVUVlNUVFFS
UFNVU1JUVVVWVVZXV1VWV1dWVVVYWVhZW1pYWVtdXF5aW1hZWFZZWVhYWlpYV1dY
WFZXW1tZWFlYWVhWWVlZXFxcW11cXltcXltdXlxdX19dXl5bXVtbWFlYV1VXV1ZU
VlVVVVdgfLvJ0dre4eTm5+jp6nl7e3x7eHp6dnh5dnd4dXd4dnZ5cmlgUkhCQEJH
QEM/PkFCRERBQERDQz4/QkU7PD1CPkBBQUFAQEFDR0I9PENCR0dISEdJTklMT01P
UlFNUFBRUlJZVVVWV1ZUU1hSVFZVUlJTUlBRUVNTVFVSUFFOUE5NTExPTUtIREhH
RENDQkJFQj5APkE/Pz87Oj08Oz04Nzc4NzxBODQ1Nzc4Ozo6Ojg2OTs7Ozs+QT9D
SUdISEZGRkpQS01LRElHTEpLVVRaWVhZXFtZVlhgX1xXV1BVblVUSkA5NzQ1NDc1
NTQzNDQ0NDg1Njc2NTg7PD8+PkpJTUZNT0dPS1JNSFBLRkxIS0hLSk1UVFlgVl5X
UVJUVUxRT1ZVUlFZXVpWVFJTVllZV1dUVFtaWltfZl1VWFtcVlZVT0tTUElIR0Q5
NzY3Njk/SVJWWmxlWlxdWWBpYV9kV1JUUVJcWlhTT1NSV1pTVFNTVlVXVlZVWFJU
WlNPS01VVVpaWVVYV1VWUU5QTk5PUFVRTE1LS0xIRU5KSEpOTk1JR01MSVBVWlxT
VFhcWFpZTkdDQEFFS0VISElTUU9WYniWpqiooJeOhn92a2NgYGZwbV5JOzs/QkI7
ODs9OkA+PDw6OT1APj4+SDw6Oz4/QkA7O0A9Pz5CPDs8QTxDQkJJPzpBPzo8Ozg2
NzQ3NjczMjQ2Nzg7PT9HS0RJR01SUldSUE9OT01VWFJWVE5LTlFTUlBSVldSVFhW
VFJWUVBNTEhLTFJUTExNS05OSUZITE1LS0pKT0pGREVGRkdIRklKSUlERURCQ0NC
Q0E+PDk9QD9BPzw6ODo4OTo9Ojg5PUdQW2VqamlrbWttcnd6fH19fYKDiI2Ojo2N
jo6LjIiIhX58eXVzcW9sb3d/hIyOkI+Lio6QkZOYlpSTjYuHgXJkWE1IRD89QEJF
RUZMT0xPUVNUVlhaW1lXVVNSUlJPTUtNS0dDQUJEQkJDRUZGR0hFR0dHQ0dHSEtI
SEtJS05LS0xSUVNQTlFUUlVZWFlcXWFlZ2hsbW9zcnV8fH9+fX+AgYGBg4SEg4KD
hYOCh4eHh4eJi4qKi4uOjI2KjpGSlZWUmZaSkpeWkI6TmJWYmpiXmJiampuXnJmY
lpaZmJqYmZmbnJ2jrLGwsbSwopSDfIeXrLu/vr28urq4s7OzsrK0trW3ubu8v8G/
v7++vr27ur27vLy7ubW2uby7t7e1ube1tbe2tLW0sa+mmIFmWldXUlBRT0xOS0xO
TVJPTUtKR0lKTEpKTUpJSUlLTUxJTE1PUExJS0tNS0xOTU5MS0xLS09PUVFTUE9R
UFNSU1FRVFJNT09OTlBQUlNSUVBRT1JUVFFPUVRUUVNRUE5QUVFSUFFPSk5RUE9P
UVNTVlFRTFBPUVJSUlJRT09SUlBQUE9RUlJTVVVTVFVWV1ZYWFZYV1hVVVRTV1ta
W11bWVxaXV1aWlpcWllZWllaXV5bV1dXWFpZWldXWVpZVlVXWVlbXFxaXF9cX11f
XFxcX15iYWBdXFhaW1pfXFtZV1RWVllXU1NXW2Z9usjT2d/h4+bn6OnpeXp7enl7
d3t7enl6eHp4eHl1dG9rZFtRSkdDQkBAQUY/PEVESUREREM9QUFEQUVBPT9BPT8/
Pz8+QT5BRENHQkNFRkhJS0xNTkxQTE1SU1NQUlNRUlVWVVVZWlZVU1VWU1ZWVFJQ
VlJPUFNXWFZVU1RUUFFPTkxISEdJTEpGREJCQUBAQENHQj07PTo8OzU5Nzc4ODg3
Nzg1ODk4ODc5Ozg6ODk3OTk4PD5FQj5AQEBFREU/QlFPSklIR0dHSkxUU1xZUVVZ
YFhPU2BaV1RYUU9UWFZKQDo3NzI0NTAyNjQ0Ozg4Njc2Nzk5ODw6Ozo+S0ZLRUdF
Q1RMWlVMUU9KT0pPTFVWSlVTVFtTWlNUVlJSTFNOUlRQSlRUWVdaWVVSUldZWlVT
U1dUU1pdXFZXW15VVVVOTldSTUdHRzo2NzU2OTk+TV1eYmJYX11aYGleX2lYTVJR
Vl5gXFhRUVNYXFJSWl1ZVlFWWlJSU1JcVVhTTlhYWFNTU1lYVVhSTU9RUVRTT05F
SEhJRk9NS01OTU9KS1FJTFFRUlNUV1FTV1xdX1lRSERBQkJHRkpJRVJRU1dVYnqW
pKekno+Jg3pybWhkZW1yZ1BEPDw+PTs3PDpEQ0E9Ozs7PDs/PEdCOjk9Oz1AQkA9
QEFEQj06Ojw7PT9ASUhAPEFCPDg4OTczNDM2NDQ1MzU2ODk6PD5FRk1JUE5WXlJU
UkxMTFVVT1BSUFRVVk5ISlNVVVRWWFRUVltYWE9LTUtKSkxJSUhLTU9NSUlMTkxI
TU9NR0NHSElLS0xISkhKRkNBQ0RCREJCQz49PDtAPjw6ODg5PDs5Ozg2OkBLWGNo
am1tbWtubXB1enp7e36Bg4aGiZKRjo2NjY2LiIiFhoKCd3Vua25vdH2DjI6NjIyO
kpGQkpOVko+NiYN4aV5XU01LSUI+PUNHTFFSU05RUlVUWVtcXFZUUlFUU1FPTkxK
R0ZCQUBAQUFEQz5CR0pIR0hESUhHRElKSklLS05MUFJVU1JRU1VaWFxdX19iY2lr
bW9ycnR3enp5e318fX9/gH6Cg4SFgIOFhoeGh4mMiouOjo6PjY+MjY2RlJKSlJuX
lZSUlZaQkpKWl5qTk5aYmpqbm5yampyam5mWl5uenZ+lqK2ytby9tqmcmJiRjJit
uL6/vru6uLKuq62vs7a2t7e6u73BwcHAwcG/vcC9vLm4u7e4t7i4ur29urq4tre6
uLa5trWzs62onohtXFVUVFJRT01NS0tKS05RS0tKS0xPTklJS0pJSUdLTEtJTEpO
S0tHSUpNT05QTk5LS0xQTlBPUFJRTVBRTk9OT05PUlJPUlBQTk9QUFFRT1FRVVNU
VFRTUlFWU1JQU1JRUFNVV1RPT1BRT1*SUVNUU1JOTlBPUFBQU1RSUVBSUVNSUVNR
UVNVVFRTVVRWVFJTVlhXWVdXU1NTWFtbWl5dXFlZWFhZWFxYVlpYWFlbWVpZWVZX
V1dYWVhYWFdXVVRZW1pZWlxdW1peXl1cXGBgX19gYV9fW1pZW1lcW1hWVFVXVVlW
U1NVaoS8ytPa3uLk5+jo6el4eXh1eXh9eHt7e3t4eHZ1eHh0cm5jWEtLTEY/PTs8
P0NGSklGREVBOz0+RD9BRENAPkE/Oj0+P0A9Pz0+Q0NCQkRJSUlKSUtMTEpLTFBU
VlVUVlZSWVteXFpYU1RXWFlVWFlXV1VTVVJPUlZaVldTUVJRUVFOUE1KTE1LSElF
QUVEQkVCRUNERD8/Pjs8QDw6Ojo6Ozw5Nzk5PDc2NDQ4Ojg6OTk4Ojc4PEQ7Oj0/
PUNCRkNBSUtHSERJTEdKR1BLUVlVV1ZiV1BLU1JVVVZWU1RbWVBJQzo9NzY3NzYy
Mjc3ODg0MzU3OTk/Pjo8Oz1ERk9FRkVJSklXUkxWUVBRSlFPV1ZHTU9SXlVdVVdc
VlZMUk1QWVJRUFNZWF5eWU9PU1VWVFRSWFBPVllbWlZYWVdUVFFYXFhTUkxKQTo0
MjQ1OT5DVFhPV1paYFtgX15gX1FPUlRUWltbVlNPUVdWUlhXXVZVVldaVlNWVllZ
VFNPTVNRTVFPUlNUUVVUUlhVU1ZRS0lLRk1LSFFPTVFNTUpLT01LUlRMTVNVU1BU
V1tiWFVQSUNDQEVDSEhHVVJYWlBYXn6Ypqiil4qBfHp4cGttcHNtYFBDOz47Ojo3
OT07ODo7Oz88OjxAREA8Pj07OjxBQTw4PUFEQTxAPTtBRUVGR0U+QEI+ODUzMzc2
Njc4ODQxNDY3OTs8P0RKR0hSTlVfVVtRT09RU1VSUVJTU1JQS05OTVJXVVZUUVNY
VVRSTUxOSUtMSktKTEpJTEpKRkdLTE1NT01NSklJSktOTkpGREdGQUFERUREREI9
Pj4/Ozc5ODo5Njc6OTs5NzpBSlhja21vb3RxcHBucnp9eXl6fH+EhIWGjo2Njo+N
j4+MiYuLhH54cm5tb3BzfYaLjo6MjpKSkpORlJeWkpCHfnNrYVdWVVRMQj0/RE9V
UVJQUVFRVFtcXF1dXFlWVlZXV1FRTk9NS0VDQ0FBQUFAP0FER0dHR0dHSUhKSkxL
TEpJTlJOUFFUVlNWVltcYGBfZGhnaW5wcnR2dXh6eXt8f4GBgoKAg4GBgoODgoSE
iIiHio6Ni4+Sk46KjY6Qk5WVkpGUlJOSlpKSlJWTkpOYmJiYmZial5iZm5mZmpye
nZ+foKGip7Cyt7e5vLyznpKcn5aVorO5wcC/wLm2sa2rrK+zuLa4uL2/v768vMDA
wsG+wL68vra1tLK1tri8vbi6ubi2tre3tra1tbW4trGroY1tW1hUVFNNTk5KSktP
T0tLSkpMSktNTExLS0tLSkxKSUlMTUtLSk5JSE1OTk9MTE9RT0xNUFBRU1BPTU1P
UFBTUlFPUlFOUVNRUFFRUU9OUFFTU1NTUlNUVFJTUU5QUlJUVVRUU1ZST1BPUFFS
UVBOUVJPUFJSUFJRU1NRUFFSVFNSVFNUVFFRU1RXVlVXVFlYWFhZWFhVWFZUWFdX
XV1cWFdYWVdaWFdaVVVaWVlaWVdaWVlYVVdaWVlXWFlbWFdYWVpdW1xcXlpbX2Fj
YmBhYV9fX15cXl9aWFlVUFZWV1lYWVlXU1V#orzJ0tre4eTm5+jq6nl3d3l4d3h6
ent8fHh2dXN1d3NxbGFUSkdGSEM7Pj89QUhJRkZFQ0RFQ0JCQj09PTg8PUE7Oj4+
Qz0/QEFDQkVHR0pJSUxLTU1MTExLT1FSVFNTVVRVWFdXV1ZRUlNWVlVXWFlXWlta
VFZXWlxZV1VTVVBTUU1NTEtNS05MR0pMSEVER0ZISEVERD4+Ozs6Ozs6OTk6Ojc1
NTY5ODY2Njg2NzY4ODk3PDo4Pjw8PD9CRUFBPT5GRkVLTEZLTVFKSkxSW1daV11Z
SlJWVlNSV1pUU1dXVlZQQjo7OTU1NDMyNjc0NTZINzc3OTo8PT07QUJDUkpOS0hN
R1RRTlRQTlFIUFJVVEhSUVJgV1ZSWmFeYFJVTk5VUlJQV1lUVVZQSk5OUVZYVFBP
UFNUWV1XUlRZWFlXVFVcXlpWWFBCOTIyMzc2PUNNV01TWlpbW1paXl1VVFZXVVZZ
V1lcUk1OU1BVXVlaVlNTUVNYVVVbUk9VT05JTE9SUU9QUVZVUlNVWFlUS05LTFFU
V09SUFNSUVRNSkpNUk5OV1FNVFpSTlRcYVxYW1FKQ0JER0NFR0hTTFFUTlVWbYma
paOelImBfXx7dnRxcXBpWkY9Oj1COTQ5Ozs7QTk6Pzw7Ozs/QEJDPDo6PkBFPjtA
QkRFQjk6PUJGREZEQkFCRj04MzQ1ODk1NTM5NzQ0NTk6Oj49P0JFSFRRWFlSXFNS
VlZXVVRTU1ZTUFNNTU5PUFRUV1lRTk5SU09MTU5PUVBKS01MSkhIS0pJR0hDR0tL
TUtFSk1OS0tIR0VHRkhEQ0NGRENBPj89PT87PDs4Ojw4OTo4Njk9QUxZZG1vb3By
cnFzcnR2fH99eHh7gISHjJKJjpGRk5WSkpKOiomIgHx0cm5vcXV+hIeLjo+SlZiY
mJWUlZmSjIJ4cG1jVE5NTkxIQ0ZMVFhXVldUVldYXWBiX19gXFxbWlhXU1FPTk1L