From 205f5ff4bbb00ece289892089a6c94c975e97ca2 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Mon, 15 Feb 2016 22:23:58 -0800 Subject: [PATCH] Update searchers to return a pair of iterators --- .../boost/algorithm/searching/boyer_moore.hpp | 32 +++--- .../searching/boyer_moore_horspool.hpp | 33 +++--- .../searching/knuth_morris_pratt.hpp | 33 +++--- test/empty_search_test.cpp | 18 +-- test/search_test1.cpp | 103 ++++++++++-------- test/search_test2.cpp | 30 +++-- test/search_test3.cpp | 30 +++-- test/search_test4.cpp | 30 +++-- 8 files changed, 176 insertions(+), 133 deletions(-) diff --git a/include/boost/algorithm/searching/boyer_moore.hpp b/include/boost/algorithm/searching/boyer_moore.hpp index c5fe9fa..65a809d 100644 --- a/include/boost/algorithm/searching/boyer_moore.hpp +++ b/include/boost/algorithm/searching/boyer_moore.hpp @@ -75,25 +75,27 @@ Requirements: /// \param corpus_last One past the end of the data to search /// template - corpusIter operator () ( corpusIter corpus_first, corpusIter corpus_last ) const { + std::pair + operator () ( corpusIter corpus_first, corpusIter corpus_last ) const { BOOST_STATIC_ASSERT (( boost::is_same< typename std::iterator_traits::value_type, typename std::iterator_traits::value_type>::value )); - if ( corpus_first == corpus_last ) return corpus_last; // if nothing to search, we didn't find it! - if ( pat_first == pat_last ) return corpus_first; // empty pattern matches at start + if ( corpus_first == corpus_last ) return std::make_pair(corpus_last, corpus_last); // if nothing to search, we didn't find it! + if ( pat_first == pat_last ) return std::make_pair(corpus_first, corpus_first); // empty pattern matches at start const difference_type k_corpus_length = std::distance ( corpus_first, corpus_last ); // If the pattern is larger than the corpus, we can't find it! if ( k_corpus_length < k_pattern_length ) - return corpus_last; + return std::make_pair(corpus_last, corpus_last); // Do the search - return this->do_search ( corpus_first, corpus_last ); + return this->do_search ( corpus_first, corpus_last ); } template - typename boost::range_iterator::type operator () ( Range &r ) const { + std::pair::type, typename boost::range_iterator::type> + operator () ( Range &r ) const { return (*this) (boost::begin(r), boost::end(r)); } @@ -112,7 +114,8 @@ Requirements: /// \param p A predicate used for the search comparisons. /// template - corpusIter do_search ( corpusIter corpus_first, corpusIter corpus_last ) const { + std::pair + do_search ( corpusIter corpus_first, corpusIter corpus_last ) const { /* ---- Do the matching ---- */ corpusIter curPos = corpus_first; const corpusIter lastPos = corpus_last - k_pattern_length; @@ -126,7 +129,7 @@ Requirements: j--; // We matched - we're done! if ( j == 0 ) - return curPos; + return std::make_pair(curPos, curPos + k_pattern_length); } // Since we didn't match, figure out how far to skip forward @@ -138,7 +141,7 @@ Requirements: curPos += suffix_ [ j ]; } - return corpus_last; // We didn't find anything + return std::make_pair(corpus_last, corpus_last); // We didn't find anything } @@ -211,7 +214,7 @@ Requirements: /// \param pat_last One past the end of the data to search for /// template - corpusIter boyer_moore_search ( + std::pair boyer_moore_search ( corpusIter corpus_first, corpusIter corpus_last, patIter pat_first, patIter pat_last ) { @@ -220,7 +223,7 @@ Requirements: } template - corpusIter boyer_moore_search ( + std::pair boyer_moore_search ( corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern ) { typedef typename boost::range_iterator::type pattern_iterator; @@ -229,8 +232,9 @@ Requirements: } template - typename boost::lazy_disable_if_c< - boost::is_same::value, typename boost::range_iterator > + typename boost::disable_if_c< + boost::is_same::value, + std::pair::type, typename boost::range_iterator::type> > ::type boyer_moore_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last ) { @@ -239,7 +243,7 @@ Requirements: } template - typename boost::range_iterator::type + std::pair::type, typename boost::range_iterator::type> boyer_moore_search ( CorpusRange &corpus, const PatternRange &pattern ) { typedef typename boost::range_iterator::type pattern_iterator; diff --git a/include/boost/algorithm/searching/boyer_moore_horspool.hpp b/include/boost/algorithm/searching/boyer_moore_horspool.hpp index 758ded2..aacb5cb 100644 --- a/include/boost/algorithm/searching/boyer_moore_horspool.hpp +++ b/include/boost/algorithm/searching/boyer_moore_horspool.hpp @@ -64,33 +64,34 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html ~boyer_moore_horspool () {} - /// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p ) + /// \fn operator ( corpusIter corpus_first, corpusIter corpus_last) /// \brief Searches the corpus for the pattern that was passed into the constructor /// /// \param corpus_first The start of the data to search (Random Access Iterator) /// \param corpus_last One past the end of the data to search - /// \param p A predicate used for the search comparisons. /// template - corpusIter operator () ( corpusIter corpus_first, corpusIter corpus_last ) const { + std::pair + operator () ( corpusIter corpus_first, corpusIter corpus_last ) const { BOOST_STATIC_ASSERT (( boost::is_same< typename std::iterator_traits::value_type, typename std::iterator_traits::value_type>::value )); - if ( corpus_first == corpus_last ) return corpus_last; // if nothing to search, we didn't find it! - if ( pat_first == pat_last ) return corpus_first; // empty pattern matches at start + if ( corpus_first == corpus_last ) return std::make_pair(corpus_last, corpus_last); // if nothing to search, we didn't find it! + if ( pat_first == pat_last ) return std::make_pair(corpus_first, corpus_first); // empty pattern matches at start const difference_type k_corpus_length = std::distance ( corpus_first, corpus_last ); // If the pattern is larger than the corpus, we can't find it! if ( k_corpus_length < k_pattern_length ) - return corpus_last; + return std::make_pair(corpus_last, corpus_last); // Do the search return this->do_search ( corpus_first, corpus_last ); } template - typename boost::range_iterator::type operator () ( Range &r ) const { + std::pair::type, typename boost::range_iterator::type> + operator () ( Range &r ) const { return (*this) (boost::begin(r), boost::end(r)); } @@ -108,7 +109,8 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html /// \param k_corpus_length The length of the corpus to search /// template - corpusIter do_search ( corpusIter corpus_first, corpusIter corpus_last ) const { + std::pair + do_search ( corpusIter corpus_first, corpusIter corpus_last ) const { corpusIter curPos = corpus_first; const corpusIter lastPos = corpus_last - k_pattern_length; while ( curPos <= lastPos ) { @@ -117,14 +119,14 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html while ( pat_first [j] == curPos [j] ) { // We matched - we're done! if ( j == 0 ) - return curPos; + return std::make_pair(curPos, curPos + k_pattern_length); j--; } curPos += skip_ [ curPos [ k_pattern_length - 1 ]]; } - return corpus_last; + return std::make_pair(corpus_last, corpus_last); } // \endcond }; @@ -142,7 +144,7 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html /// \param pat_last One past the end of the data to search for /// template - corpusIter boyer_moore_horspool_search ( + std::pair boyer_moore_horspool_search ( corpusIter corpus_first, corpusIter corpus_last, patIter pat_first, patIter pat_last ) { @@ -151,7 +153,7 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html } template - corpusIter boyer_moore_horspool_search ( + std::pair boyer_moore_horspool_search ( corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern ) { typedef typename boost::range_iterator::type pattern_iterator; @@ -160,8 +162,9 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html } template - typename boost::lazy_disable_if_c< - boost::is_same::value, typename boost::range_iterator > + typename boost::disable_if_c< + boost::is_same::value, + std::pair::type, typename boost::range_iterator::type> > ::type boyer_moore_horspool_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last ) { @@ -170,7 +173,7 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html } template - typename boost::range_iterator::type + std::pair::type, typename boost::range_iterator::type> boyer_moore_horspool_search ( CorpusRange &corpus, const PatternRange &pattern ) { typedef typename boost::range_iterator::type pattern_iterator; diff --git a/include/boost/algorithm/searching/knuth_morris_pratt.hpp b/include/boost/algorithm/searching/knuth_morris_pratt.hpp index aaeeb51..c890c9c 100644 --- a/include/boost/algorithm/searching/knuth_morris_pratt.hpp +++ b/include/boost/algorithm/searching/knuth_morris_pratt.hpp @@ -69,23 +69,26 @@ namespace boost { namespace algorithm { /// \param p A predicate used for the search comparisons. /// template - corpusIter operator () ( corpusIter corpus_first, corpusIter corpus_last ) const { + std::pair + operator () ( corpusIter corpus_first, corpusIter corpus_last ) const { BOOST_STATIC_ASSERT (( boost::is_same< typename std::iterator_traits::value_type, typename std::iterator_traits::value_type>::value )); - if ( corpus_first == corpus_last ) return corpus_last; // if nothing to search, we didn't find it! - if ( pat_first == pat_last ) return corpus_first; // empty pattern matches at start + + if ( corpus_first == corpus_last ) return std::make_pair(corpus_last, corpus_last); // if nothing to search, we didn't find it! + if ( pat_first == pat_last ) return std::make_pair(corpus_first, corpus_first); // empty pattern matches at start const difference_type k_corpus_length = std::distance ( corpus_first, corpus_last ); // If the pattern is larger than the corpus, we can't find it! if ( k_corpus_length < k_pattern_length ) - return corpus_last; + return std::make_pair(corpus_last, corpus_last); - return do_search ( corpus_first, corpus_last, k_corpus_length ); + return do_search ( corpus_first, corpus_last, k_corpus_length ); } template - typename boost::range_iterator::type operator () ( Range &r ) const { + std::pair::type, typename boost::range_iterator::type> + operator () ( Range &r ) const { return (*this) (boost::begin(r), boost::end(r)); } @@ -103,7 +106,8 @@ namespace boost { namespace algorithm { /// \param p A predicate used for the search comparisons. /// template - corpusIter do_search ( corpusIter corpus_first, corpusIter corpus_last, + std::pair + do_search ( corpusIter corpus_first, corpusIter corpus_last, difference_type k_corpus_length ) const { difference_type match_start = 0; // position in the corpus that we're matching @@ -135,7 +139,7 @@ namespace boost { namespace algorithm { while ( match_start <= last_match ) { while ( pat_first [ idx ] == corpus_first [ match_start + idx ] ) { if ( ++idx == k_pattern_length ) - return corpus_first + match_start; + return std::make_pair(corpus_first + match_start, corpus_first + match_start + k_pattern_length); } // Figure out where to start searching again // assert ( idx - skip_ [ idx ] > 0 ); // we're always moving forward @@ -146,7 +150,7 @@ namespace boost { namespace algorithm { #endif // We didn't find anything - return corpus_last; + return std::make_pair(corpus_last, corpus_last); } @@ -202,7 +206,7 @@ namespace boost { namespace algorithm { /// \param pat_last One past the end of the data to search for /// template - corpusIter knuth_morris_pratt_search ( + std::pair knuth_morris_pratt_search ( corpusIter corpus_first, corpusIter corpus_last, patIter pat_first, patIter pat_last ) { @@ -211,7 +215,7 @@ namespace boost { namespace algorithm { } template - corpusIter knuth_morris_pratt_search ( + std::pair knuth_morris_pratt_search ( corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern ) { typedef typename boost::range_iterator::type pattern_iterator; @@ -220,8 +224,9 @@ namespace boost { namespace algorithm { } template - typename boost::lazy_disable_if_c< - boost::is_same::value, typename boost::range_iterator > + typename boost::disable_if_c< + boost::is_same::value, + std::pair::type, typename boost::range_iterator::type> > ::type knuth_morris_pratt_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last ) { @@ -230,7 +235,7 @@ namespace boost { namespace algorithm { } template - typename boost::range_iterator::type + std::pair::type, typename boost::range_iterator::type> knuth_morris_pratt_search ( CorpusRange &corpus, const PatternRange &pattern ) { typedef typename boost::range_iterator::type pattern_iterator; diff --git a/test/empty_search_test.cpp b/test/empty_search_test.cpp index 22317f1..cb37678 100644 --- a/test/empty_search_test.cpp +++ b/test/empty_search_test.cpp @@ -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()) ); } diff --git a/test/search_test1.cpp b/test/search_test1.cpp index 7c49a3a..3fe3b91 100644 --- a/test/search_test1.cpp +++ b/test/search_test1.cpp @@ -34,6 +34,7 @@ namespace { template void check_one_iter ( const Container &haystack, const std::string &needle, int expected ) { typedef typename Container::const_iterator iter_type; + typedef typename std::pair 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 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 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 void check_one_object ( const Container &haystack, const std::string &needle, int expected ) { typedef typename Container::const_iterator iter_type; + typedef typename std::pair ret_type; typedef std::string::const_iterator pattern_type; iter_type hBeg = haystack.begin (); @@ -150,58 +162,59 @@ namespace { ba::boyer_moore_horspool bmh ( nBeg, nEnd ); ba::knuth_morris_pratt 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 ; } diff --git a/test/search_test2.cpp b/test/search_test2.cpp index 4d772ca..eba105e 100644 --- a/test/search_test2.cpp +++ b/test/search_test2.cpp @@ -33,8 +33,8 @@ typedef std::vector 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 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 res; + std::pair 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" ); } } diff --git a/test/search_test3.cpp b/test/search_test3.cpp index 96226cd..e4c7661 100644 --- a/test/search_test3.cpp +++ b/test/search_test3.cpp @@ -34,8 +34,8 @@ typedef std::vector 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 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 res; + std::pair 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" ); } } diff --git a/test/search_test4.cpp b/test/search_test4.cpp index 2b83267..997e359 100644 --- a/test/search_test4.cpp +++ b/test/search_test4.cpp @@ -30,8 +30,8 @@ typedef std::vector 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 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 res; + std::pair 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" ); }