forked from boostorg/algorithm
Merge branch 'develop' into apolukhin/constexpr
This commit is contained in:
@ -68,6 +68,8 @@ alias unit_test_framework
|
||||
[ run sort_subrange_test.cpp unit_test_framework : : : : sort_subrange_test ]
|
||||
[ run partition_subrange_test.cpp unit_test_framework : : : : partition_subrange_test ]
|
||||
|
||||
# Is_palindrome tests
|
||||
[ run is_palindrome_test.cpp unit_test_framework : : : : is_palindrome_test ]
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,6 @@
|
||||
template<typename T>
|
||||
struct is_ : public std::unary_function<T, bool> {
|
||||
BOOST_CXX14_CONSTEXPR is_ ( T v ) : val_ ( v ) {}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool operator () ( T comp ) const { return val_ == comp; }
|
||||
private:
|
||||
is_ (); // need a value
|
||||
|
@ -20,7 +20,6 @@
|
||||
template<typename T>
|
||||
struct is_ : public std::unary_function<T, bool> {
|
||||
BOOST_CXX14_CONSTEXPR is_ ( T v ) : val_ ( v ) {}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool operator () ( T comp ) const { return val_ == comp; }
|
||||
private:
|
||||
is_ (); // need a value
|
||||
|
@ -26,56 +26,56 @@ BOOST_AUTO_TEST_CASE( test_main )
|
||||
BOOST_CHECK (
|
||||
boost::algorithm::boyer_moore_search (
|
||||
cs.begin (), cs.end (), estr.begin (), estr.end ())
|
||||
== cs.begin ()
|
||||
== std::make_pair(cs.begin(), cs.begin())
|
||||
);
|
||||
|
||||
BOOST_CHECK (
|
||||
boost::algorithm::boyer_moore_horspool_search (
|
||||
cs.begin (), cs.end (), estr.begin (), estr.end ())
|
||||
== cs.begin ()
|
||||
== std::make_pair(cs.begin(), cs.begin())
|
||||
);
|
||||
|
||||
BOOST_CHECK (
|
||||
boost::algorithm::knuth_morris_pratt_search (
|
||||
cs.begin (), cs.end (), estr.begin (), estr.end ())
|
||||
== cs.begin ()
|
||||
== std::make_pair(cs.begin(), cs.begin())
|
||||
);
|
||||
|
||||
// empty corpus, non-empty pattern
|
||||
BOOST_CHECK (
|
||||
boost::algorithm::boyer_moore_search (
|
||||
estr.begin (), estr.end (), str.begin (), str.end ())
|
||||
== estr.end ()
|
||||
== std::make_pair(estr.end(), estr.end())
|
||||
);
|
||||
|
||||
BOOST_CHECK (
|
||||
boost::algorithm::boyer_moore_horspool_search (
|
||||
estr.begin (), estr.end (), str.begin (), str.end ())
|
||||
== estr.end ()
|
||||
== std::make_pair(estr.end(), estr.end())
|
||||
);
|
||||
|
||||
BOOST_CHECK (
|
||||
boost::algorithm::knuth_morris_pratt_search (
|
||||
estr.begin (), estr.end (), str.begin (), str.end ())
|
||||
== estr.end ()
|
||||
== std::make_pair(estr.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 ()
|
||||
== std::make_pair(str.begin(), str.begin())
|
||||
);
|
||||
|
||||
BOOST_CHECK (
|
||||
boost::algorithm::boyer_moore_horspool_search (
|
||||
str.begin (), str.end (), estr.begin (), estr.end ())
|
||||
== str.begin ()
|
||||
== std::make_pair(str.begin(), str.begin())
|
||||
);
|
||||
|
||||
BOOST_CHECK (
|
||||
boost::algorithm::knuth_morris_pratt_search (
|
||||
str.begin (), str.end (), estr.begin (), estr.end ())
|
||||
== str.begin ()
|
||||
== std::make_pair(str.begin(), str.begin())
|
||||
);
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/hex.hpp>
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
@ -42,6 +43,31 @@ void test_to_hex ( const typename String::value_type ** tests ) {
|
||||
}
|
||||
}
|
||||
|
||||
template<typename String>
|
||||
void test_to_hex_lower ( 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_lower ( *p, std::back_inserter ( one ));
|
||||
boost::algorithm::hex_lower ( arg, std::back_inserter ( two ));
|
||||
boost::algorithm::hex_lower ( arg.begin (), arg.end (), std::back_inserter ( three ));
|
||||
four = boost::algorithm::hex_lower ( 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 ) {
|
||||
@ -61,6 +87,11 @@ void test_from_hex_success ( const typename String::value_type ** tests ) {
|
||||
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::algorithm::to_lower( arg );
|
||||
boost::algorithm::to_lower( one );
|
||||
boost::algorithm::to_lower( two );
|
||||
boost::algorithm::to_lower( three );
|
||||
boost::algorithm::to_lower( four );
|
||||
BOOST_CHECK ( one == two );
|
||||
BOOST_CHECK ( one == three );
|
||||
BOOST_CHECK ( one == four );
|
||||
@ -113,6 +144,7 @@ const wchar_t *tohex_w [] = {
|
||||
const char *fromhex [] = {
|
||||
"20",
|
||||
"2122234556FF",
|
||||
"2122234556ff",
|
||||
NULL // End of the list
|
||||
};
|
||||
|
||||
@ -120,6 +152,7 @@ const char *fromhex [] = {
|
||||
const wchar_t *fromhex_w [] = {
|
||||
L"00101020",
|
||||
L"2122234556FF3456",
|
||||
L"2122234556ff3456",
|
||||
NULL // End of the list
|
||||
};
|
||||
|
||||
@ -129,6 +162,8 @@ const char *fromhex_fail [] = {
|
||||
"H",
|
||||
"234",
|
||||
"21222G4556FF",
|
||||
"h",
|
||||
"21222g4556ff",
|
||||
NULL // End of the list
|
||||
};
|
||||
|
||||
@ -139,6 +174,8 @@ const wchar_t *fromhex_fail_w [] = {
|
||||
L"H",
|
||||
L"234",
|
||||
L"21222G4556FF",
|
||||
L"h",
|
||||
L"21222g4556ff",
|
||||
NULL // End of the list
|
||||
};
|
||||
|
||||
@ -146,10 +183,12 @@ const wchar_t *fromhex_fail_w [] = {
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_to_hex<std::string> ( tohex );
|
||||
test_to_hex_lower<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_to_hex_lower<std::wstring> ( tohex_w );
|
||||
test_from_hex_success<std::wstring> ( fromhex_w );
|
||||
test_from_hex_failure<std::wstring> ( fromhex_fail_w );
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ Try ostream_iterators
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/hex.hpp>
|
||||
#include <boost/exception/get_error_info.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
79
test/is_palindrome_test.cpp
Normal file
79
test/is_palindrome_test.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
Copyright (c) Alexander Zaitsev <zamazan4ik@gmail.com>, 2016
|
||||
|
||||
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 <boost/config.hpp>
|
||||
#include <boost/algorithm/is_palindrome.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool funcComparator(const T& v1, const T& v2)
|
||||
{
|
||||
return v1 == v2;
|
||||
}
|
||||
|
||||
struct functorComparator
|
||||
{
|
||||
template <typename T>
|
||||
bool operator()(const T& v1, const T& v2) const
|
||||
{
|
||||
return v1 == v2;
|
||||
}
|
||||
};
|
||||
|
||||
#define Begin(arr) (arr)
|
||||
#define End(arr) (arr+(sizeof(arr)/(sizeof(arr[0]))))
|
||||
|
||||
void test_is_palindrome()
|
||||
{
|
||||
const std::list<int> empty;
|
||||
const std::vector<char> singleElement(1, 'z');
|
||||
int oddNonPalindrome[] = {3,2,2};
|
||||
const int oddPalindrome[] = {1,2,3,2,1};
|
||||
const int evenPalindrome[] = {1,2,2,1};
|
||||
int evenNonPalindrome[] = {1,4,8,8};
|
||||
const char* stringNullPtr = NULL;
|
||||
|
||||
// Test a default operator==
|
||||
BOOST_CHECK ( ba::is_palindrome(empty));
|
||||
BOOST_CHECK ( ba::is_palindrome(singleElement));
|
||||
BOOST_CHECK (!ba::is_palindrome(Begin(oddNonPalindrome), End(oddNonPalindrome)));
|
||||
BOOST_CHECK ( ba::is_palindrome(Begin(oddPalindrome), End(oddPalindrome)));
|
||||
BOOST_CHECK ( ba::is_palindrome(Begin(evenPalindrome), End(evenPalindrome)));
|
||||
BOOST_CHECK (!ba::is_palindrome(Begin(evenNonPalindrome), End(evenNonPalindrome)));
|
||||
|
||||
//Test the custom comparators
|
||||
BOOST_CHECK ( ba::is_palindrome(empty.begin(), empty.end(), functorComparator()));
|
||||
BOOST_CHECK (!ba::is_palindrome(Begin(oddNonPalindrome), End(oddNonPalindrome), funcComparator<int>));
|
||||
BOOST_CHECK ( ba::is_palindrome(evenPalindrome, std::equal_to<int>()));
|
||||
|
||||
//Test C-strings like cases
|
||||
BOOST_CHECK ( ba::is_palindrome(stringNullPtr));
|
||||
BOOST_CHECK ( ba::is_palindrome(""));
|
||||
BOOST_CHECK ( ba::is_palindrome("a"));
|
||||
BOOST_CHECK ( ba::is_palindrome("abacaba", std::equal_to<char>()));
|
||||
BOOST_CHECK ( ba::is_palindrome("abba"));
|
||||
BOOST_CHECK (!ba::is_palindrome("acab"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_is_palindrome ();
|
||||
}
|
@ -20,7 +20,6 @@
|
||||
template<typename T>
|
||||
struct is_ : public std::unary_function<T, bool> {
|
||||
BOOST_CXX14_CONSTEXPR is_ ( T v ) : val_ ( v ) {}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool operator () ( T comp ) const { return val_ == comp; }
|
||||
private:
|
||||
is_ (); // need a value
|
||||
|
@ -20,7 +20,6 @@
|
||||
template<typename T>
|
||||
struct is_ : public std::unary_function<T, bool> {
|
||||
BOOST_CXX14_CONSTEXPR is_ ( T v ) : val_ ( v ) {}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR bool operator () ( T comp ) const { return val_ == comp; }
|
||||
private:
|
||||
is_ (); // need a value
|
||||
|
@ -7,6 +7,20 @@
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#include <random>
|
||||
|
||||
std::default_random_engine gen;
|
||||
template<typename RandomIt>
|
||||
void do_shuffle(RandomIt first, RandomIt last)
|
||||
{ std::shuffle(first, last, gen); }
|
||||
#else
|
||||
template<typename RandomIt>
|
||||
void do_shuffle(RandomIt first, RandomIt last)
|
||||
{ std::random_shuffle(first, last); }
|
||||
#endif
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
|
||||
template <typename Iter>
|
||||
@ -72,14 +86,14 @@ BOOST_AUTO_TEST_CASE( test_main )
|
||||
// BOOST_CHECK_EQUAL(v[5], 5);
|
||||
|
||||
// Mix them up and try again - single element
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::partition_subrange(b, v.end(), b + 7, b + 8);
|
||||
check_sequence (b, v.end(), b + 7, b + 8);
|
||||
|
||||
// BOOST_CHECK_EQUAL(v[7], 7);
|
||||
|
||||
// Mix them up and try again - at the end
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::partition_subrange(b, v.end(), b + 7, v.end());
|
||||
check_sequence (b, v.end(), b + 7, v.end());
|
||||
|
||||
@ -88,7 +102,7 @@ BOOST_AUTO_TEST_CASE( test_main )
|
||||
// BOOST_CHECK_EQUAL(v[9], 9);
|
||||
|
||||
// Mix them up and try again - at the beginning
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::partition_subrange(b, v.end(), b, b + 2);
|
||||
check_sequence (b, v.end(), b, b + 2);
|
||||
|
||||
@ -96,12 +110,12 @@ BOOST_AUTO_TEST_CASE( test_main )
|
||||
// BOOST_CHECK_EQUAL(v[1], 1);
|
||||
|
||||
// Mix them up and try again - empty subrange
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::partition_subrange(b, v.end(), b, b);
|
||||
check_sequence (b, v.end(), b, b);
|
||||
|
||||
// Mix them up and try again - entire subrange
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::partition_subrange(b, v.end(), b, v.end());
|
||||
check_sequence (b, v.end(), b, v.end());
|
||||
}
|
||||
@ -120,14 +134,14 @@ BOOST_AUTO_TEST_CASE( test_main )
|
||||
// BOOST_CHECK_EQUAL(v[5], 4);
|
||||
|
||||
// Mix them up and try again - single element
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::partition_subrange(b, v.end(), b + 7, b + 8, std::greater<int>());
|
||||
check_sequence (b, v.end(), b + 7, b + 8, std::greater<int>());
|
||||
|
||||
// BOOST_CHECK_EQUAL(v[7], 2);
|
||||
|
||||
// Mix them up and try again - at the end
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::partition_subrange(b, v.end(), b + 7, v.end(), std::greater<int>());
|
||||
check_sequence (b, v.end(), b + 7, v.end(), std::greater<int>());
|
||||
|
||||
@ -136,7 +150,7 @@ BOOST_AUTO_TEST_CASE( test_main )
|
||||
// BOOST_CHECK_EQUAL(v[9], 0);
|
||||
|
||||
// Mix them up and try again - at the beginning
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::partition_subrange(b, v.end(), b, b + 2, std::greater<int>());
|
||||
check_sequence (b, v.end(), b, b + 2, std::greater<int>());
|
||||
|
||||
@ -144,12 +158,12 @@ BOOST_AUTO_TEST_CASE( test_main )
|
||||
// BOOST_CHECK_EQUAL(v[1], 8);
|
||||
|
||||
// Mix them up and try again - empty subrange
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::partition_subrange(b, v.end(), b, b, std::greater<int>());
|
||||
check_sequence (b, v.end(), b, b, std::greater<int>());
|
||||
|
||||
// Mix them up and try again - entire subrange
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::partition_subrange(b, v.end(), b, v.end(), std::greater<int>());
|
||||
check_sequence (b, v.end(), b, v.end(), std::greater<int>());
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ namespace {
|
||||
template<typename Container>
|
||||
void check_one_iter ( const Container &haystack, const std::string &needle, int expected ) {
|
||||
typedef typename Container::const_iterator iter_type;
|
||||
typedef typename std::pair<iter_type, iter_type> ret_type;
|
||||
typedef std::string::const_iterator pattern_type;
|
||||
|
||||
iter_type hBeg = haystack.begin ();
|
||||
@ -41,33 +42,40 @@ namespace {
|
||||
pattern_type nBeg = needle.begin ();
|
||||
pattern_type nEnd = needle.end ();
|
||||
|
||||
// iter_type ret0 = std::search (hBeg, hEnd, nBeg, nEnd);
|
||||
ret_type ret1 = ba::boyer_moore_search (hBeg, hEnd, nBeg, nEnd);
|
||||
ret_type ret1r = ba::boyer_moore_search (haystack, nBeg, nEnd);
|
||||
ret_type ret2 = ba::boyer_moore_horspool_search (hBeg, hEnd, nBeg, nEnd);
|
||||
ret_type ret3 = ba::knuth_morris_pratt_search (hBeg, hEnd, nBeg, nEnd);
|
||||
|
||||
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 );
|
||||
// iter_type it1 = ret1.first;
|
||||
// iter_type it1r = ret1r.first;
|
||||
// iter_type it2 = ret2.first;
|
||||
// iter_type it3 = ret3.first;
|
||||
const int dist = ret1.first == hEnd ? -1 : std::distance ( hBeg, ret1.first );
|
||||
|
||||
std::cout << "(Iterators) Pattern is " << needle.length () << ", haysstack is " << haystack.length () << " chars long; " << std::endl;
|
||||
try {
|
||||
if ( it0 != it1 ) {
|
||||
if ( it0 != ret1.first ) {
|
||||
throw std::runtime_error (
|
||||
std::string ( "results mismatch between std::search and boyer-moore search" ));
|
||||
}
|
||||
|
||||
if ( it1 != it1r ) {
|
||||
if ( ret1.first != ret1r.first || ret1.second != ret1r.second ) {
|
||||
throw std::runtime_error (
|
||||
std::string ( "results mismatch between iterator and range boyer_moore search" ));
|
||||
}
|
||||
|
||||
if ( it1 != it2 ) {
|
||||
if ( ret1.first != ret2.first || ret1.second != ret2.second ) {
|
||||
throw std::runtime_error (
|
||||
std::string ( "results mismatch between boyer-moore and boyer-moore-horspool search" ));
|
||||
}
|
||||
|
||||
if ( it1 != it3 )
|
||||
if ( ret1.first != ret3.first || ret1.second != ret3.second ) {
|
||||
throw std::runtime_error (
|
||||
std::string ( "results mismatch between boyer-moore and knuth-morris-pratt search" ));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -75,10 +83,10 @@ namespace {
|
||||
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 << " bm: " << std::distance ( hBeg, ret1.first ) << "\n";
|
||||
std::cout << " bm(r): " << std::distance ( hBeg, ret1r.first ) << "\n";
|
||||
std::cout << " bmh: " << std::distance ( hBeg, ret2.first ) << "\n";
|
||||
std::cout << " kpm: " << std::distance ( hBeg, ret3.first )<< "\n";
|
||||
std::cout << std::flush;
|
||||
throw ;
|
||||
}
|
||||
@ -91,32 +99,35 @@ namespace {
|
||||
template<typename Container>
|
||||
void check_one_pointer ( const Container &haystack, const std::string &needle, int expected ) {
|
||||
typedef const typename Container::value_type *ptr_type;
|
||||
typedef typename std::pair<ptr_type, ptr_type> ret_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 );
|
||||
ret_type ret1 = ba::boyer_moore_search (hBeg, hEnd, nBeg, nEnd);
|
||||
ret_type ret2 = ba::boyer_moore_horspool_search (hBeg, hEnd, nBeg, nEnd);
|
||||
ret_type ret3 = ba::knuth_morris_pratt_search (hBeg, hEnd, nBeg, nEnd);
|
||||
const int dist = ret1.first == hEnd ? -1 : std::distance ( hBeg, ret1.first );
|
||||
|
||||
std::cout << "(Pointers) Pattern is " << needle.length () << ", haysstack is " << haystack.length () << " chars long; " << std::endl;
|
||||
try {
|
||||
if ( it0 != it1 ) {
|
||||
if ( it0 != ret1.first ) {
|
||||
throw std::runtime_error (
|
||||
std::string ( "results mismatch between std::search and boyer-moore search" ));
|
||||
}
|
||||
|
||||
if ( it1 != it2 ) {
|
||||
if ( ret1.first != ret2.first || ret1.second != ret2.second ) {
|
||||
throw std::runtime_error (
|
||||
std::string ( "results mismatch between boyer-moore and boyer-moore-horspool search" ));
|
||||
}
|
||||
|
||||
if ( it1 != it3 )
|
||||
if ( ret1.first != ret3.first || ret1.second != ret3.second ) {
|
||||
throw std::runtime_error (
|
||||
std::string ( "results mismatch between boyer-moore and knuth-morris-pratt search" ));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -124,9 +135,9 @@ namespace {
|
||||
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 << " bm: " << std::distance ( hBeg, ret1.first ) << "\n";
|
||||
std::cout << " bmh: " << std::distance ( hBeg, ret2.first ) << "\n";
|
||||
std::cout << " kpm: " << std::distance ( hBeg, ret3.first )<< "\n";
|
||||
std::cout << std::flush;
|
||||
throw ;
|
||||
}
|
||||
@ -138,6 +149,7 @@ namespace {
|
||||
template<typename Container>
|
||||
void check_one_object ( const Container &haystack, const std::string &needle, int expected ) {
|
||||
typedef typename Container::const_iterator iter_type;
|
||||
typedef typename std::pair<iter_type, iter_type> ret_type;
|
||||
typedef std::string::const_iterator pattern_type;
|
||||
|
||||
iter_type hBeg = haystack.begin ();
|
||||
@ -150,58 +162,59 @@ namespace {
|
||||
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 );
|
||||
iter_type it0 = std::search (hBeg, hEnd, nBeg, nEnd);
|
||||
ret_type ret1 = bm (hBeg, hEnd);
|
||||
ret_type ret1r = bm (haystack);
|
||||
ret_type retr1 = bm_r (hBeg, hEnd);
|
||||
ret_type retr1r = bm_r (haystack);
|
||||
ret_type ret2 = bmh (hBeg, hEnd);
|
||||
ret_type ret3 = kmp (hBeg, hEnd);
|
||||
const int dist = ret1.first == hEnd ? -1 : std::distance ( hBeg, ret1.first );
|
||||
|
||||
std::cout << "(Objects) Pattern is " << needle.length () << ", haysstack is " << haystack.length () << " chars long; " << std::endl;
|
||||
try {
|
||||
if ( it0 != it1 ) {
|
||||
if ( it0 != ret1.first ) {
|
||||
throw std::runtime_error (
|
||||
std::string ( "results mismatch between std::search and boyer-moore search" ));
|
||||
}
|
||||
|
||||
if ( it1 != it1r ) {
|
||||
if ( ret1.first != ret1r.first || ret1.second != ret1r.second ) {
|
||||
throw std::runtime_error (
|
||||
std::string ( "results mismatch between iterator and range boyer_moore search(1)" ));
|
||||
}
|
||||
|
||||
if ( it1 != rt1 ) {
|
||||
if ( ret1.first != retr1.first || ret1.second != retr1.second ) {
|
||||
throw std::runtime_error (
|
||||
std::string ( "results mismatch between iterator and range boyer_moore search(2)" ));
|
||||
}
|
||||
|
||||
if ( rt1 != rt1r ) {
|
||||
if ( ret1.first != retr1r.first || ret1.second != retr1r.second ) {
|
||||
throw std::runtime_error (
|
||||
std::string ( "results mismatch between iterator and range boyer_moore search(3)" ));
|
||||
}
|
||||
|
||||
if ( it1 != it2 ) {
|
||||
if ( ret1.first != ret2.first || ret1.second != ret2.second ) {
|
||||
throw std::runtime_error (
|
||||
std::string ( "results mismatch between boyer-moore and boyer-moore-horspool search" ));
|
||||
}
|
||||
|
||||
if ( it1 != it3 )
|
||||
if ( ret1.first != ret3.first || ret1.second != ret3.second ) {
|
||||
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 << "Expected: " << expected << "\n";
|
||||
std::cout << " std: " << std::distance ( hBeg, it0 ) << "\n";
|
||||
std::cout << " bm: " << std::distance ( hBeg, ret1.first ) << "\n";
|
||||
std::cout << " bm(r1): " << std::distance ( hBeg, ret1r.first ) << "\n";
|
||||
std::cout << " bm(r2): " << std::distance ( hBeg, retr1.first ) << "\n";
|
||||
std::cout << " bm(r3): " << std::distance ( hBeg, retr1r.first ) << "\n";
|
||||
std::cout << " bmh: " << std::distance ( hBeg, ret2.first ) << "\n";
|
||||
std::cout << " kpm: " << std::distance ( hBeg, ret3.first )<< "\n";
|
||||
std::cout << std::flush;
|
||||
throw ;
|
||||
}
|
||||
|
@ -33,8 +33,8 @@ typedef std::vector<char> vec;
|
||||
needle.begin (), needle.end ()); \
|
||||
if ( res != exp ) { \
|
||||
std::cout << "On run # " << i << " expected " \
|
||||
<< exp - haystack.begin () << " got " \
|
||||
<< res - haystack.begin () << std::endl; \
|
||||
<< exp.first - haystack.begin () << " got " \
|
||||
<< res.first - haystack.begin () << std::endl; \
|
||||
throw std::runtime_error \
|
||||
( "Unexpected result from " #call ); \
|
||||
} \
|
||||
@ -51,8 +51,8 @@ typedef std::vector<char> vec;
|
||||
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; \
|
||||
<< exp.first - haystack.begin () << " got " \
|
||||
<< res.first - haystack.begin () << std::endl; \
|
||||
throw std::runtime_error \
|
||||
( "Unexpected result from " #obj " object" ); \
|
||||
} \
|
||||
@ -90,27 +90,33 @@ namespace {
|
||||
std::clock_t sTime;
|
||||
unsigned long stdDiff;
|
||||
|
||||
vec::const_iterator res;
|
||||
vec::const_iterator exp; // the expected result
|
||||
std::pair<vec::const_iterator, vec::const_iterator> res;
|
||||
std::pair<vec::const_iterator, vec::const_iterator> exp; // the expected result
|
||||
vec::const_iterator exp_start;
|
||||
|
||||
if ( expected >= 0 )
|
||||
exp = haystack.begin () + expected;
|
||||
exp_start = haystack.begin () + expected;
|
||||
else if ( expected == -1 )
|
||||
exp = haystack.end (); // we didn't find it!
|
||||
exp_start = haystack.end (); // we didn't find it!
|
||||
else if ( expected == -2 )
|
||||
exp = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
|
||||
exp_start = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
|
||||
else
|
||||
throw std::logic_error ( "Expected must be -2, -1, or >= 0" );
|
||||
|
||||
if ( expected == -1 )
|
||||
exp = std::make_pair(haystack.end(), haystack.end());
|
||||
else
|
||||
exp = std::make_pair(exp_start, exp_start + needle.size());
|
||||
|
||||
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;
|
||||
vec::const_iterator s_res = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
|
||||
if ( s_res != exp.first ) {
|
||||
std::cout << "On run # " << i << " expected " << exp.first - haystack.begin () << " got " << s_res - haystack.begin () << std::endl;
|
||||
throw std::runtime_error ( "Unexpected result from std::search" );
|
||||
}
|
||||
}
|
||||
|
@ -34,8 +34,8 @@ typedef std::vector<std::string> vec;
|
||||
needle.begin (), needle.end ()); \
|
||||
if ( res != exp ) { \
|
||||
std::cout << "On run # " << i << " expected " \
|
||||
<< exp - haystack.begin () << " got " \
|
||||
<< res - haystack.begin () << std::endl; \
|
||||
<< exp.first - haystack.begin () << " got " \
|
||||
<< res.first - haystack.begin () << std::endl; \
|
||||
throw std::runtime_error \
|
||||
( "Unexpected result from " #call ); \
|
||||
} \
|
||||
@ -52,8 +52,8 @@ typedef std::vector<std::string> vec;
|
||||
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; \
|
||||
<< exp.first - haystack.begin () << " got " \
|
||||
<< res.first - haystack.begin () << std::endl; \
|
||||
throw std::runtime_error \
|
||||
( "Unexpected result from " #obj " object" ); \
|
||||
} \
|
||||
@ -90,27 +90,33 @@ namespace {
|
||||
std::clock_t sTime;
|
||||
unsigned long stdDiff;
|
||||
|
||||
vec::const_iterator res;
|
||||
vec::const_iterator exp; // the expected result
|
||||
std::pair<vec::const_iterator, vec::const_iterator> res;
|
||||
std::pair<vec::const_iterator, vec::const_iterator> exp; // the expected result
|
||||
vec::const_iterator exp_start;
|
||||
|
||||
if ( expected >= 0 )
|
||||
exp = haystack.begin () + expected;
|
||||
exp_start = haystack.begin () + expected;
|
||||
else if ( expected == -1 )
|
||||
exp = haystack.end (); // we didn't find it1
|
||||
exp_start = haystack.end (); // we didn't find it1
|
||||
else if ( expected == -2 )
|
||||
exp = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
|
||||
exp_start = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
|
||||
else
|
||||
throw std::logic_error ( "Expected must be -2, -1, or >= 0" );
|
||||
|
||||
if ( expected == -1 )
|
||||
exp = std::make_pair(haystack.end(), haystack.end());
|
||||
else
|
||||
exp = std::make_pair(exp_start, exp_start + needle.size());
|
||||
|
||||
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;
|
||||
vec::const_iterator s_res = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
|
||||
if ( s_res != exp.first ) {
|
||||
std::cout << "On run # " << i << " expected " << exp.first - haystack.begin () << " got " << s_res - haystack.begin () << std::endl;
|
||||
throw std::runtime_error ( "Unexpected result from std::search" );
|
||||
}
|
||||
}
|
||||
|
@ -30,8 +30,8 @@ typedef std::vector<std::string> vec;
|
||||
res = boost::algorithm::call ( haystack, needle ); \
|
||||
if ( res != exp ) { \
|
||||
std::cout << "Expected " \
|
||||
<< exp - haystack.begin () << " got " \
|
||||
<< res - haystack.begin () << std::endl; \
|
||||
<< exp.first - haystack.begin () << " got " \
|
||||
<< res.first - haystack.begin () << std::endl; \
|
||||
throw std::runtime_error \
|
||||
( "Unexpected result from " #call ); \
|
||||
} \
|
||||
@ -43,8 +43,8 @@ typedef std::vector<std::string> vec;
|
||||
res = s_o ( haystack ); \
|
||||
if ( res != exp ) { \
|
||||
std::cout << "Expected " \
|
||||
<< exp - haystack.begin () << " got " \
|
||||
<< res - haystack.begin () << std::endl; \
|
||||
<< exp.first - haystack.begin () << " got " \
|
||||
<< res.first - haystack.begin () << std::endl; \
|
||||
throw std::runtime_error \
|
||||
( "Unexpected result from " #obj " object" ); \
|
||||
} \
|
||||
@ -64,25 +64,31 @@ namespace {
|
||||
|
||||
void check_one ( const vec &haystack, const vec &needle, int expected ) {
|
||||
|
||||
vec::const_iterator res;
|
||||
vec::const_iterator exp; // the expected result
|
||||
std::pair<vec::const_iterator, vec::const_iterator> res;
|
||||
std::pair<vec::const_iterator, vec::const_iterator> exp; // the expected result
|
||||
vec::const_iterator exp_start;
|
||||
|
||||
if ( expected >= 0 )
|
||||
exp = haystack.begin () + expected;
|
||||
exp_start = haystack.begin () + expected;
|
||||
else if ( expected == -1 )
|
||||
exp = haystack.end (); // we didn't find it1
|
||||
exp_start = haystack.end (); // we didn't find it1
|
||||
else if ( expected == -2 )
|
||||
exp = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
|
||||
exp_start = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
|
||||
else
|
||||
throw std::logic_error ( "Expected must be -2, -1, or >= 0" );
|
||||
|
||||
if ( expected == -1 )
|
||||
exp = std::make_pair(haystack.end(), haystack.end());
|
||||
else
|
||||
exp = std::make_pair(exp_start, exp_start + needle.size());
|
||||
|
||||
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
|
||||
res = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
|
||||
if ( res != exp ) {
|
||||
std::cout << "Expected " << exp - haystack.begin () << " got " << res - haystack.begin () << std::endl;
|
||||
vec::const_iterator s_res = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
|
||||
if ( s_res != exp.first ) {
|
||||
std::cout << "Expected " << exp.first - haystack.begin () << " got " << s_res - haystack.begin () << std::endl;
|
||||
throw std::runtime_error ( "Unexpected result from std::search" );
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,20 @@
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#include <random>
|
||||
|
||||
std::default_random_engine gen;
|
||||
template<typename RandomIt>
|
||||
void do_shuffle(RandomIt first, RandomIt last)
|
||||
{ std::shuffle(first, last, gen); }
|
||||
#else
|
||||
template<typename RandomIt>
|
||||
void do_shuffle(RandomIt first, RandomIt last)
|
||||
{ std::random_shuffle(first, last); }
|
||||
#endif
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
|
||||
template <typename Iter>
|
||||
@ -53,14 +67,14 @@ BOOST_AUTO_TEST_CASE( test_main )
|
||||
BOOST_CHECK_EQUAL(v[5], 5);
|
||||
|
||||
// Mix them up and try again - single element
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::sort_subrange(b, v.end(), b + 7, b + 8);
|
||||
check_sequence (b, v.end(), b + 7, b + 8);
|
||||
|
||||
BOOST_CHECK_EQUAL(v[7], 7);
|
||||
|
||||
// Mix them up and try again - at the end
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::sort_subrange(b, v.end(), b + 7, v.end());
|
||||
check_sequence (b, v.end(), b + 7, v.end());
|
||||
|
||||
@ -69,7 +83,7 @@ BOOST_AUTO_TEST_CASE( test_main )
|
||||
BOOST_CHECK_EQUAL(v[9], 9);
|
||||
|
||||
// Mix them up and try again - at the beginning
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::sort_subrange(b, v.end(), b, b + 2);
|
||||
check_sequence (b, v.end(), b, b + 2);
|
||||
|
||||
@ -77,12 +91,12 @@ BOOST_AUTO_TEST_CASE( test_main )
|
||||
BOOST_CHECK_EQUAL(v[1], 1);
|
||||
|
||||
// Mix them up and try again - empty subrange
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::sort_subrange(b, v.end(), b, b);
|
||||
check_sequence (b, v.end(), b, b);
|
||||
|
||||
// Mix them up and try again - entire subrange
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::sort_subrange(b, v.end(), b, v.end());
|
||||
check_sequence (b, v.end(), b, v.end());
|
||||
}
|
||||
@ -101,14 +115,14 @@ BOOST_AUTO_TEST_CASE( test_main )
|
||||
BOOST_CHECK_EQUAL(v[5], 4);
|
||||
|
||||
// Mix them up and try again - single element
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::sort_subrange(b, v.end(), b + 7, b + 8, std::greater<int>());
|
||||
check_sequence (b, v.end(), b + 7, b + 8, std::greater<int>());
|
||||
|
||||
BOOST_CHECK_EQUAL(v[7], 2);
|
||||
|
||||
// Mix them up and try again - at the end
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::sort_subrange(b, v.end(), b + 7, v.end(), std::greater<int>());
|
||||
check_sequence (b, v.end(), b + 7, v.end(), std::greater<int>());
|
||||
|
||||
@ -117,7 +131,7 @@ BOOST_AUTO_TEST_CASE( test_main )
|
||||
BOOST_CHECK_EQUAL(v[9], 0);
|
||||
|
||||
// Mix them up and try again - at the beginning
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::sort_subrange(b, v.end(), b, b + 2, std::greater<int>());
|
||||
check_sequence (b, v.end(), b, b + 2, std::greater<int>());
|
||||
|
||||
@ -125,12 +139,12 @@ BOOST_AUTO_TEST_CASE( test_main )
|
||||
BOOST_CHECK_EQUAL(v[1], 8);
|
||||
|
||||
// Mix them up and try again - empty subrange
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::sort_subrange(b, v.end(), b, b, std::greater<int>());
|
||||
check_sequence (b, v.end(), b, b, std::greater<int>());
|
||||
|
||||
// Mix them up and try again - entire subrange
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
do_shuffle(v.begin(), v.end());
|
||||
ba::sort_subrange(b, v.end(), b, v.end(), std::greater<int>());
|
||||
check_sequence (b, v.end(), b, v.end(), std::greater<int>());
|
||||
}
|
||||
|
Reference in New Issue
Block a user