Compare commits

..

1 Commits

Author SHA1 Message Date
70e0ff8da7 Release 1.50.0 beta 1
[SVN r78831]
2012-06-06 15:23:40 +00:00
15 changed files with 63 additions and 429 deletions

View File

@ -66,12 +66,12 @@ If you want to catch all the decoding errors, you can catch exceptions of type `
Assuming that `out` is an iterator that accepts `char` values, and `wout` accepts `wchar_t` values (and that sizeof ( wchar_t ) == 2)
``
hex ( "abcdef", out ) --> "616263646566"
hex ( "abcde", out ) --> "616263646566"
hex ( "32", out ) --> "3332"
hex ( "abcdef", wout ) --> "006100620063006400650066"
hex ( "abcde", wout ) --> "006100620063006400650066"
hex ( "32", wout ) --> "00330032"
unhex ( "616263646566", out ) --> "abcdef"
unhex ( "616263646566", out ) --> "abcde"
unhex ( "3332", out ) --> "32"
unhex ( "616263646566", wout ) --> "\6162\6364\6566" ( i.e, a 3 character string )
unhex ( "3332", wout ) --> "\3233" ( U+3332, SQUARE HUARADDO )

View File

@ -38,9 +38,7 @@ Iterator requirements: The `is_sorted` functions will work on all kinds of itera
[heading is_sorted_until]
If `distance(first, last) < 2`, then `is_sorted ( first, last )` returns `last`. Otherwise, it returns the last iterator i in [first,last] for which the range [first,i) is sorted.
In short, it returns the element in the sequence that is "out of order". If the entire sequence is sorted (according to the predicate), then it will return `last`.
The function `is_sorted_until(sequence, predicate)` compares each sequential pair of elements in the sequence, checking if they satisfy the predicate. it returns the first element of the sequence that does not satisfy the predicate with its' predecessor. In short, it returns the element in the sequence that is "out of order". If all adjacent pairs satisfy the predicate, then it will return one past the last element of the sequence.
``
namespace boost { namespace algorithm {

View File

@ -20,7 +20,7 @@
namespace boost { namespace algorithm {
#if __cplusplus >= 201103L
// Use the C++11 versions of is_partitioned if it is available
// Use the C++11 versions of iota if it is available
using std::is_partitioned; // Section 25.3.13
#else
/// \fn is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p )

View File

@ -27,7 +27,7 @@
namespace boost { namespace algorithm {
#if __cplusplus >= 201103L
// Use the C++11 versions of is_sorted/is_sorted_until if they are available
// Use the C++11 versions of iota if it is available
using std::is_sorted_until; // Section 25.4.1.5
using std::is_sorted; // Section 25.4.1.5
#else
@ -46,7 +46,7 @@ using std::is_sorted; // Section 25.4.1.5
ForwardIterator next = first;
while ( ++next != last )
{
if ( p ( *next, *first ))
if ( !p ( *first, *next ))
return next;
first = next;
}
@ -63,7 +63,7 @@ using std::is_sorted; // Section 25.4.1.5
ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last )
{
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted_until ( first, last, std::less<value_type>());
return boost::algorithm::is_sorted_until ( first, last, std::less_equal<value_type>());
}
@ -125,6 +125,10 @@ using std::is_sorted; // Section 25.4.1.5
return boost::algorithm::is_sorted_until ( boost::begin ( range ), boost::end ( range ));
}
namespace detail {
typedef struct { typedef bool type; } bool_;
};
/// \fn is_sorted ( const R &range, Pred p )
/// \return whether or not the entire range R is sorted
/// (according to the comparison predicate 'p').
@ -169,7 +173,7 @@ using std::is_sorted; // Section 25.4.1.5
bool is_increasing ( ForwardIterator first, ForwardIterator last )
{
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::less<value_type>());
return boost::algorithm::is_sorted (first, last, std::less_equal<value_type>());
}
@ -202,7 +206,7 @@ using std::is_sorted; // Section 25.4.1.5
bool is_decreasing ( ForwardIterator first, ForwardIterator last )
{
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::greater<value_type>());
return boost::algorithm::is_sorted (first, last, std::greater_equal<value_type>());
}
/// \fn is_decreasing ( const R &range )
@ -234,7 +238,7 @@ using std::is_sorted; // Section 25.4.1.5
bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last )
{
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::less_equal<value_type>());
return boost::algorithm::is_sorted (first, last, std::less<value_type>());
}
/// \fn is_strictly_increasing ( const R &range )
@ -265,7 +269,7 @@ using std::is_sorted; // Section 25.4.1.5
bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last )
{
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::greater_equal<value_type>());
return boost::algorithm::is_sorted (first, last, std::greater<value_type>());
}
/// \fn is_strictly_decreasing ( const R &range )

View File

@ -51,10 +51,14 @@ namespace boost { namespace algorithm {
\brief Thrown when the input sequence unexpectedly ends
*/
struct hex_decode_error : virtual boost::exception, virtual std::exception {};
struct not_enough_input : virtual hex_decode_error {};
struct non_hex_input : virtual hex_decode_error {};
typedef boost::error_info<struct bad_char_,char> bad_char;
struct hex_decode_error: virtual boost::exception, virtual std::exception {};
struct not_enough_input : public hex_decode_error {};
struct non_hex_input : public hex_decode_error {
non_hex_input ( char ch ) : bad_char ( ch ) {}
char bad_char;
private:
non_hex_input (); // don't allow creation w/o a char
};
namespace detail {
/// \cond DOXYGEN_HIDE
@ -73,7 +77,7 @@ namespace detail {
if ( c >= '0' && c <= '9' ) return c - '0';
if ( c >= 'A' && c <= 'F' ) return c - 'A' + 10;
if ( c >= 'a' && c <= 'f' ) return c - 'a' + 10;
BOOST_THROW_EXCEPTION (non_hex_input() << bad_char (c));
BOOST_THROW_EXCEPTION (non_hex_input (c));
return 0; // keep dumb compilers happy
}
@ -110,25 +114,33 @@ namespace detail {
typedef T value_type;
};
template <typename Iterator>
bool iter_end ( Iterator current, Iterator last ) { return current == last; }
template <typename T>
bool ptr_end ( const T* ptr, const T* /*end*/ ) { return *ptr == '\0'; }
// Output Iterators have a value type of 'void'. Kinda sucks.
// We special case some output iterators, but we can't enumerate them all.
// If we can't figure it out, we assume that you want to output chars.
// If you don't, pass in an iterator with a real value_type.
template <typename T> struct value_type_or_char { typedef T value_type; };
template <> struct value_type_or_char<void> { typedef char value_type; };
// All in one step
template <typename Iterator>
struct iterator_value_type {
// typedef typename value_type_or_char<typename hex_iterator_traits<Iterator>::value_type>::value_type value_type;
typedef typename hex_iterator_traits<Iterator>::value_type value_type;
};
// What can we assume here about the inputs?
// is std::iterator_traits<InputIterator>::value_type always 'char' ?
// Could it be wchar_t, say? Does it matter?
// We are assuming ASCII for the values - but what about the storage?
template <typename InputIterator, typename OutputIterator, typename EndPred>
typename boost::enable_if<boost::is_integral<typename hex_iterator_traits<OutputIterator>::value_type>, OutputIterator>::type
decode_one ( InputIterator &first, InputIterator last, OutputIterator out, EndPred pred ) {
typedef typename hex_iterator_traits<OutputIterator>::value_type T;
template <typename InputIterator, typename OutputIterator>
typename boost::enable_if<boost::is_integral<typename iterator_value_type<OutputIterator>::value_type>, OutputIterator>::type
decode_one ( InputIterator &first, InputIterator last, OutputIterator out ) {
typedef typename iterator_value_type<OutputIterator>::value_type T;
T res (0);
// Need to make sure that we get can read that many chars here.
for ( std::size_t i = 0; i < 2 * sizeof ( T ); ++i, ++first ) {
if ( pred ( first, last ))
if ( first == last )
BOOST_THROW_EXCEPTION (not_enough_input ());
res = ( 16 * res ) + hex_char_to_int (static_cast<char> (*first));
}
@ -197,7 +209,7 @@ hex ( const Range &r, OutputIterator out ) {
template <typename InputIterator, typename OutputIterator>
OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator out ) {
while ( first != last )
out = detail::decode_one ( first, last, out, detail::iter_end<InputIterator> );
out = detail::decode_one ( first, last, out );
return out;
}
@ -211,12 +223,14 @@ OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator o
/// \note Based on the MySQL function of the same name
template <typename T, typename OutputIterator>
OutputIterator unhex ( const T *ptr, OutputIterator out ) {
typedef typename detail::hex_iterator_traits<OutputIterator>::value_type OutputType;
typedef typename detail::iterator_value_type<OutputIterator>::value_type OutputType;
// If we run into the terminator while decoding, we will throw a
// malformed input exception. It would be nicer to throw a 'Not enough input'
// exception - but how much extra work would that require?
// I just make up an "end iterator" which we will never get to -
// two Ts per byte of the output type.
while ( *ptr )
out = detail::decode_one ( ptr, (const T *) NULL, out, detail::ptr_end<T> );
out = detail::decode_one ( ptr, ptr + 2 * sizeof(OutputType), out );
return out;
}

View File

@ -223,7 +223,7 @@ Requirements:
corpusIter boyer_moore_search (
corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
typedef typename boost::range_iterator<PatternRange> pattern_iterator;
boyer_moore<pattern_iterator> bm ( boost::begin(pattern), boost::end (pattern));
return bm ( corpus_first, corpus_last );
}
@ -242,7 +242,7 @@ Requirements:
typename boost::range_iterator<CorpusRange>::type
boyer_moore_search ( CorpusRange &corpus, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
typedef typename boost::range_iterator<PatternRange> pattern_iterator;
boyer_moore<pattern_iterator> bm ( boost::begin(pattern), boost::end (pattern));
return bm (boost::begin (corpus), boost::end (corpus));
}

View File

@ -84,11 +84,6 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html
return this->do_search ( corpus_first, corpus_last );
}
template <typename Range>
typename boost::range_iterator<Range>::type operator () ( Range &r ) const {
return (*this) (boost::begin(r), boost::end(r));
}
private:
/// \cond DOXYGEN_HIDE
patIter pat_first, pat_last;
@ -124,9 +119,6 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html
// \endcond
};
/* Two ranges as inputs gives us four possibilities; with 2,3,3,4 parameters
Use a bit of TMP to disambiguate the 3-argument templates */
/// \fn boyer_moore_horspool_search ( corpusIter corpus_first, corpusIter corpus_last,
/// patIter pat_first, patIter pat_last )
/// \brief Searches the corpus for the pattern.
@ -138,55 +130,10 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html
///
template <typename patIter, typename corpusIter>
corpusIter boyer_moore_horspool_search (
corpusIter corpus_first, corpusIter corpus_last,
patIter pat_first, patIter pat_last )
{
corpusIter corpus_first, corpusIter corpus_last,
patIter pat_first, patIter pat_last ) {
boyer_moore_horspool<patIter> bmh ( pat_first, pat_last );
return bmh ( corpus_first, corpus_last );
}
template <typename PatternRange, typename corpusIter>
corpusIter boyer_moore_horspool_search (
corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
boyer_moore_horspool<pattern_iterator> bmh ( boost::begin(pattern), boost::end (pattern));
return bmh ( corpus_first, corpus_last );
}
template <typename patIter, typename CorpusRange>
typename boost::lazy_disable_if_c<
boost::is_same<CorpusRange, patIter>::value, typename boost::range_iterator<CorpusRange> >
::type
boyer_moore_horspool_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last )
{
boyer_moore_horspool<patIter> bmh ( pat_first, pat_last );
return bm (boost::begin (corpus), boost::end (corpus));
}
template <typename PatternRange, typename CorpusRange>
typename boost::range_iterator<CorpusRange>::type
boyer_moore_horspool_search ( CorpusRange &corpus, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
boyer_moore_horspool<pattern_iterator> bmh ( boost::begin(pattern), boost::end (pattern));
return bmh (boost::begin (corpus), boost::end (corpus));
}
// Creator functions -- take a pattern range, return an object
template <typename Range>
boost::algorithm::boyer_moore_horspool<typename boost::range_iterator<const Range>::type>
make_boyer_moore_horspool ( const Range &r ) {
return boost::algorithm::boyer_moore_horspool
<typename boost::range_iterator<const Range>::type> (boost::begin(r), boost::end(r));
}
template <typename Range>
boost::algorithm::boyer_moore_horspool<typename boost::range_iterator<Range>::type>
make_boyer_moore_horspool ( Range &r ) {
return boost::algorithm::boyer_moore_horspool
<typename boost::range_iterator<Range>::type> (boost::begin(r), boost::end(r));
}
}}

View File

@ -79,11 +79,6 @@ namespace boost { namespace algorithm {
return do_search ( corpus_first, corpus_last, k_corpus_length );
}
template <typename Range>
typename boost::range_iterator<Range>::type operator () ( Range &r ) const {
return (*this) (boost::begin(r), boost::end(r));
}
private:
/// \cond DOXYGEN_HIDE
patIter pat_first, pat_last;
@ -184,9 +179,6 @@ namespace boost { namespace algorithm {
};
/* Two ranges as inputs gives us four possibilities; with 2,3,3,4 parameters
Use a bit of TMP to disambiguate the 3-argument templates */
/// \fn knuth_morris_pratt_search ( corpusIter corpus_first, corpusIter corpus_last,
/// patIter pat_first, patIter pat_last )
/// \brief Searches the corpus for the pattern.
@ -198,55 +190,10 @@ namespace boost { namespace algorithm {
///
template <typename patIter, typename corpusIter>
corpusIter knuth_morris_pratt_search (
corpusIter corpus_first, corpusIter corpus_last,
patIter pat_first, patIter pat_last )
{
corpusIter corpus_first, corpusIter corpus_last,
patIter pat_first, patIter pat_last ) {
knuth_morris_pratt<patIter> kmp ( pat_first, pat_last );
return kmp ( corpus_first, corpus_last );
}
template <typename PatternRange, typename corpusIter>
corpusIter knuth_morris_pratt_search (
corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
knuth_morris_pratt<pattern_iterator> kmp ( boost::begin(pattern), boost::end (pattern));
return kmp ( corpus_first, corpus_last );
}
template <typename patIter, typename CorpusRange>
typename boost::lazy_disable_if_c<
boost::is_same<CorpusRange, patIter>::value, typename boost::range_iterator<CorpusRange> >
::type
knuth_morris_pratt_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last )
{
knuth_morris_pratt<patIter> kmp ( pat_first, pat_last );
return kmp (boost::begin (corpus), boost::end (corpus));
}
template <typename PatternRange, typename CorpusRange>
typename boost::range_iterator<CorpusRange>::type
knuth_morris_pratt_search ( CorpusRange &corpus, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
knuth_morris_pratt<pattern_iterator> kmp ( boost::begin(pattern), boost::end (pattern));
return kmp (boost::begin (corpus), boost::end (corpus));
}
// Creator functions -- take a pattern range, return an object
template <typename Range>
boost::algorithm::knuth_morris_pratt<typename boost::range_iterator<const Range>::type>
make_knuth_morris_pratt ( const Range &r ) {
return boost::algorithm::knuth_morris_pratt
<typename boost::range_iterator<const Range>::type> (boost::begin(r), boost::end(r));
}
template <typename Range>
boost::algorithm::knuth_morris_pratt<typename boost::range_iterator<Range>::type>
make_knuth_morris_pratt ( Range &r ) {
return boost::algorithm::knuth_morris_pratt
<typename boost::range_iterator<Range>::type> (boost::begin(r), boost::end(r));
}
}}

View File

@ -60,7 +60,7 @@ namespace boost {
a match).
\param Input A container which will be searched.
\param Finder A Finder object used for searching
\return A reference to the result
\return A reference the result
\note Prior content of the result will be overwritten.
*/
@ -122,7 +122,7 @@ namespace boost {
Each match is used as a separator of segments. These segments are then
returned in the result.
\param Result A 'container container' to contain the result of search.
\param Result A 'container container' to container the result of search.
Both outer and inner container must have constructor taking a pair
of iterators as an argument.
Typical type of the result is
@ -131,7 +131,7 @@ namespace boost {
a match).
\param Input A container which will be searched.
\param Finder A finder object used for searching
\return A reference to the result
\return A reference the result
\note Prior content of the result will be overwritten.
*/

View File

@ -1,13 +0,0 @@
<html>
<head>
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
</head>
<body>
Automatic redirection failed, please go to
<a href="doc/html/index.html">doc/html/index.html</a> &nbsp;<hr>
<p>© Copyright Marshall Clow, 2012</p>
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>

View File

@ -130,7 +130,7 @@
string str1("command.com");
cout
&lt;&lt; str1
&lt;&lt; (is_executable(str1)? "is": "is not")
&lt;&lt; (is_executable("command.com")? "is": "is not")
&lt;&lt; "an executable"
&lt;&lt; endl; // prints "command.com is an executable"

View File

@ -16,7 +16,6 @@ import testing ;
[ run search_test1.cpp : : : : search_test1 ]
[ run search_test2.cpp : : : : search_test2 ]
[ run search_test3.cpp : : : : search_test3 ]
[ run search_test4.cpp : : : : search_test4 ]
[ compile-fail search_fail1.cpp : : : : ]
[ compile-fail search_fail2.cpp : : : : ]
[ compile-fail search_fail3.cpp : : : : ]
@ -44,7 +43,6 @@ import testing ;
[ run hex_test1.cpp : : : : hex_test1 ]
[ run hex_test2.cpp : : : : hex_test2 ]
[ run hex_test3.cpp : : : : hex_test3 ]
[ run hex_test4.cpp : : : : hex_test4 ]
[ compile-fail hex_fail1.cpp ]
;
}

View File

@ -1,145 +0,0 @@
/*
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>
namespace ba = boost::algorithm;
void test_short_input1 () {
std::string s;
try { ba::unhex ( std::string ( "A" ), std::back_inserter(s)); }
catch ( const std::exception &ex ) { return; }
BOOST_TEST_MESSAGE ( "Failed to catch std::exception in test_short_input1" );
BOOST_CHECK ( false );
}
void test_short_input2 () {
std::string s;
try { ba::unhex ( std::string ( "A" ), std::back_inserter(s)); }
catch ( const ba::hex_decode_error &ex ) { return; }
BOOST_TEST_MESSAGE ( "Failed to catch ba::hex_decode_error in test_short_input2" );
BOOST_CHECK ( false );
}
void test_short_input3 () {
std::string s;
try { ba::unhex ( std::string ( "A" ), std::back_inserter(s)); }
catch ( const ba::not_enough_input &ex ) { return; }
BOOST_TEST_MESSAGE ( "Failed to catch ba::not_enough_input in test_short_input3" );
BOOST_CHECK ( false );
}
// Make sure that the right thing is thrown
void test_short_input4 () {
std::string s;
try { ba::unhex ( std::string ( "A" ), std::back_inserter(s)); }
catch ( const ba::non_hex_input &ex ) { BOOST_CHECK ( false ); }
catch ( const ba::not_enough_input &ex ) { return; }
catch ( ... ) { BOOST_CHECK ( false ); }
BOOST_CHECK ( false );
}
// Make sure that the right thing is thrown
void test_short_input5 () {
std::string s;
try { ba::unhex ( "A", std::back_inserter(s)); }
catch ( const ba::non_hex_input &ex ) { BOOST_CHECK ( false ); }
catch ( const ba::not_enough_input &ex ) { return; }
catch ( ... ) { BOOST_CHECK ( false ); }
BOOST_CHECK ( false );
}
void test_short_input () {
// BOOST_TEST_MESSAGE ( "Short input tests for boost::algorithm::unhex" );
test_short_input1 ();
test_short_input2 ();
test_short_input3 ();
test_short_input4 ();
test_short_input5 ();
}
void test_nonhex_input1 () {
std::string s;
try { ba::unhex ( "01234FG1234", std::back_inserter(s)); }
catch ( const std::exception &ex ) {
BOOST_CHECK ( 'G' == *boost::get_error_info<ba::bad_char>(ex));
return;
}
catch ( ... ) {}
BOOST_TEST_MESSAGE ( "Failed to catch std::exception in test_nonhex_input1" );
BOOST_CHECK ( false );
}
void test_nonhex_input2 () {
std::string s;
try { ba::unhex ( "012Z4FA1234", std::back_inserter(s)); }
catch ( const ba::hex_decode_error &ex ) {
BOOST_CHECK ( 'Z' == *boost::get_error_info<ba::bad_char>(ex));
return;
}
catch ( ... ) {}
BOOST_TEST_MESSAGE ( "Failed to catch ba::hex_decode_error in test_nonhex_input2" );
BOOST_CHECK ( false );
}
void test_nonhex_input3 () {
std::string s;
try { ba::unhex ( "01234FA12Q4", std::back_inserter(s)); }
catch ( const ba::non_hex_input &ex ) {
BOOST_CHECK ( 'Q' == *boost::get_error_info<ba::bad_char>(ex));
return;
}
catch ( ... ) {}
BOOST_TEST_MESSAGE ( "Failed to catch ba::non_hex_input in test_nonhex_input3" );
BOOST_CHECK ( false );
}
// Make sure that the right thing is thrown
void test_nonhex_input4 () {
std::string s;
try { ba::unhex ( "P1234FA1234", std::back_inserter(s)); }
catch ( const ba::not_enough_input &ex ) { BOOST_CHECK ( false ); }
catch ( const ba::non_hex_input &ex ) { return; }
catch ( ... ) { BOOST_CHECK ( false ); }
BOOST_CHECK ( false );
}
void test_nonhex_input () {
// BOOST_TEST_MESSAGE ( "Non hex input tests for for boost::algorithm::unhex" );
test_nonhex_input1 ();
test_nonhex_input2 ();
test_nonhex_input3 ();
test_nonhex_input4 ();
}
int test_main( int , char* [] )
{
test_short_input ();
test_nonhex_input ();
return 0;
}

View File

@ -54,10 +54,10 @@ test_ordered(void)
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(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] );

View File

@ -1,116 +0,0 @@
/*
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
Testing the range-based interfaces
*/
#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) { \
res = boost::algorithm::call ( haystack, needle ); \
if ( res != exp ) { \
std::cout << "Expected " \
<< exp - haystack.begin () << " got " \
<< res - haystack.begin () << std::endl; \
throw std::runtime_error \
( "Unexpected result from " #call ); \
} \
}
#define runObject(obj, refDiff) { \
boost::algorithm::obj <vec::const_iterator> s_o = \
boost::algorithm::make_##obj ( needle ); \
res = s_o ( haystack ); \
if ( res != exp ) { \
std::cout << "Expected " \
<< exp - haystack.begin () << " got " \
<< res - haystack.begin () << std::endl; \
throw std::runtime_error \
( "Unexpected result from " #obj " object" ); \
} \
}
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 check_one ( const vec &haystack, const vec &needle, int expected ) {
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
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;
throw std::runtime_error ( "Unexpected result from std::search" );
}
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;
}