Compare commits

..

1 Commits

Author SHA1 Message Date
95838c7be5 Release 1.50.0
[SVN r79156]
2012-06-28 12:37:29 +00:00
14 changed files with 63 additions and 416 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) 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 ( "32", out ) --> "3332"
hex ( "abcdef", wout ) --> "006100620063006400650066" hex ( "abcde", wout ) --> "006100620063006400650066"
hex ( "32", wout ) --> "00330032" hex ( "32", wout ) --> "00330032"
unhex ( "616263646566", out ) --> "abcdef" unhex ( "616263646566", out ) --> "abcde"
unhex ( "3332", out ) --> "32" unhex ( "3332", out ) --> "32"
unhex ( "616263646566", wout ) --> "\6162\6364\6566" ( i.e, a 3 character string ) unhex ( "616263646566", wout ) --> "\6162\6364\6566" ( i.e, a 3 character string )
unhex ( "3332", wout ) --> "\3233" ( U+3332, SQUARE HUARADDO ) 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] [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. 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.
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`.
`` ``
namespace boost { namespace algorithm { namespace boost { namespace algorithm {

View File

@ -20,7 +20,7 @@
namespace boost { namespace algorithm { namespace boost { namespace algorithm {
#if __cplusplus >= 201103L #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 using std::is_partitioned; // Section 25.3.13
#else #else
/// \fn is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p ) /// \fn is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p )

View File

@ -27,7 +27,7 @@
namespace boost { namespace algorithm { namespace boost { namespace algorithm {
#if __cplusplus >= 201103L #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_until; // Section 25.4.1.5
using std::is_sorted; // Section 25.4.1.5 using std::is_sorted; // Section 25.4.1.5
#else #else
@ -46,7 +46,7 @@ using std::is_sorted; // Section 25.4.1.5
ForwardIterator next = first; ForwardIterator next = first;
while ( ++next != last ) while ( ++next != last )
{ {
if ( p ( *next, *first )) if ( !p ( *first, *next ))
return next; return next;
first = next; first = next;
} }
@ -63,7 +63,7 @@ using std::is_sorted; // Section 25.4.1.5
ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last ) ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last )
{ {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; 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 )); 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 ) /// \fn is_sorted ( const R &range, Pred p )
/// \return whether or not the entire range R is sorted /// \return whether or not the entire range R is sorted
/// (according to the comparison predicate 'p'). /// (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 ) bool is_increasing ( ForwardIterator first, ForwardIterator last )
{ {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; 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 ) bool is_decreasing ( ForwardIterator first, ForwardIterator last )
{ {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; 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 ) /// \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 ) bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last )
{ {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; 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 ) /// \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 ) bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last )
{ {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; 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 ) /// \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 \brief Thrown when the input sequence unexpectedly ends
*/ */
struct hex_decode_error : virtual boost::exception, virtual std::exception {}; struct hex_decode_error: virtual boost::exception, virtual std::exception {};
struct not_enough_input : virtual hex_decode_error {}; struct not_enough_input : public hex_decode_error {};
struct non_hex_input : virtual hex_decode_error {}; struct non_hex_input : public hex_decode_error {
typedef boost::error_info<struct bad_char_,char> bad_char; 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 { namespace detail {
/// \cond DOXYGEN_HIDE /// \cond DOXYGEN_HIDE
@ -73,7 +77,7 @@ namespace detail {
if ( c >= '0' && c <= '9' ) return c - '0'; 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;
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 return 0; // keep dumb compilers happy
} }
@ -110,25 +114,33 @@ namespace detail {
typedef T value_type; typedef T value_type;
}; };
template <typename Iterator> // Output Iterators have a value type of 'void'. Kinda sucks.
bool iter_end ( Iterator current, Iterator last ) { return current == last; } // 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.
template <typename T> // If you don't, pass in an iterator with a real value_type.
bool ptr_end ( const T* ptr, const T* /*end*/ ) { return *ptr == '\0'; } 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? // What can we assume here about the inputs?
// is std::iterator_traits<InputIterator>::value_type always 'char' ? // is std::iterator_traits<InputIterator>::value_type always 'char' ?
// Could it be wchar_t, say? Does it matter? // Could it be wchar_t, say? Does it matter?
// We are assuming ASCII for the values - but what about the storage? // We are assuming ASCII for the values - but what about the storage?
template <typename InputIterator, typename OutputIterator, typename EndPred> template <typename InputIterator, typename OutputIterator>
typename boost::enable_if<boost::is_integral<typename hex_iterator_traits<OutputIterator>::value_type>, OutputIterator>::type typename boost::enable_if<boost::is_integral<typename iterator_value_type<OutputIterator>::value_type>, OutputIterator>::type
decode_one ( InputIterator &first, InputIterator last, OutputIterator out, EndPred pred ) { decode_one ( InputIterator &first, InputIterator last, OutputIterator out ) {
typedef typename hex_iterator_traits<OutputIterator>::value_type T; typedef typename iterator_value_type<OutputIterator>::value_type T;
T res (0); T res (0);
// Need to make sure that we get can read that many chars here. // 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 ) { 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 ()); BOOST_THROW_EXCEPTION (not_enough_input ());
res = ( 16 * res ) + hex_char_to_int (static_cast<char> (*first)); 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> template <typename InputIterator, typename OutputIterator>
OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator out ) { OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator out ) {
while ( first != last ) while ( first != last )
out = detail::decode_one ( first, last, out, detail::iter_end<InputIterator> ); out = detail::decode_one ( first, last, out );
return 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 /// \note Based on the MySQL function of the same name
template <typename T, typename OutputIterator> template <typename T, typename OutputIterator>
OutputIterator unhex ( const T *ptr, OutputIterator out ) { 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 // 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' // malformed input exception. It would be nicer to throw a 'Not enough input'
// exception - but how much extra work would that require? // 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 ) 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; return out;
} }

View File

@ -223,7 +223,7 @@ Requirements:
corpusIter boyer_moore_search ( corpusIter boyer_moore_search (
corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern ) 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)); boyer_moore<pattern_iterator> bm ( boost::begin(pattern), boost::end (pattern));
return bm ( corpus_first, corpus_last ); return bm ( corpus_first, corpus_last );
} }
@ -242,7 +242,7 @@ Requirements:
typename boost::range_iterator<CorpusRange>::type typename boost::range_iterator<CorpusRange>::type
boyer_moore_search ( CorpusRange &corpus, const PatternRange &pattern ) 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)); boyer_moore<pattern_iterator> bm ( boost::begin(pattern), boost::end (pattern));
return bm (boost::begin (corpus), boost::end (corpus)); 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 ); 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: private:
/// \cond DOXYGEN_HIDE /// \cond DOXYGEN_HIDE
patIter pat_first, pat_last; patIter pat_first, pat_last;
@ -124,9 +119,6 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html
// \endcond // \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, /// \fn boyer_moore_horspool_search ( corpusIter corpus_first, corpusIter corpus_last,
/// patIter pat_first, patIter pat_last ) /// patIter pat_first, patIter pat_last )
/// \brief Searches the corpus for the pattern. /// \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> template <typename patIter, typename corpusIter>
corpusIter boyer_moore_horspool_search ( corpusIter boyer_moore_horspool_search (
corpusIter corpus_first, corpusIter corpus_last, corpusIter corpus_first, corpusIter corpus_last,
patIter pat_first, patIter pat_last ) patIter pat_first, patIter pat_last ) {
{
boyer_moore_horspool<patIter> bmh ( pat_first, pat_last ); boyer_moore_horspool<patIter> bmh ( pat_first, pat_last );
return bmh ( corpus_first, corpus_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 ); 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: private:
/// \cond DOXYGEN_HIDE /// \cond DOXYGEN_HIDE
patIter pat_first, pat_last; 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, /// \fn knuth_morris_pratt_search ( corpusIter corpus_first, corpusIter corpus_last,
/// patIter pat_first, patIter pat_last ) /// patIter pat_first, patIter pat_last )
/// \brief Searches the corpus for the pattern. /// \brief Searches the corpus for the pattern.
@ -198,55 +190,10 @@ namespace boost { namespace algorithm {
/// ///
template <typename patIter, typename corpusIter> template <typename patIter, typename corpusIter>
corpusIter knuth_morris_pratt_search ( corpusIter knuth_morris_pratt_search (
corpusIter corpus_first, corpusIter corpus_last, corpusIter corpus_first, corpusIter corpus_last,
patIter pat_first, patIter pat_last ) patIter pat_first, patIter pat_last ) {
{
knuth_morris_pratt<patIter> kmp ( pat_first, pat_last ); knuth_morris_pratt<patIter> kmp ( pat_first, pat_last );
return kmp ( corpus_first, corpus_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). a match).
\param Input A container which will be searched. \param Input A container which will be searched.
\param Finder A Finder object used for searching \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. \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 Each match is used as a separator of segments. These segments are then
returned in the result. 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 Both outer and inner container must have constructor taking a pair
of iterators as an argument. of iterators as an argument.
Typical type of the result is Typical type of the result is
@ -131,7 +131,7 @@ namespace boost {
a match). a match).
\param Input A container which will be searched. \param Input A container which will be searched.
\param Finder A finder object used for searching \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. \note Prior content of the result will be overwritten.
*/ */

View File

@ -130,7 +130,7 @@
string str1("command.com"); string str1("command.com");
cout cout
&lt;&lt; str1 &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; "an executable"
&lt;&lt; endl; // prints "command.com is 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_test1.cpp : : : : search_test1 ]
[ run search_test2.cpp : : : : search_test2 ] [ run search_test2.cpp : : : : search_test2 ]
[ run search_test3.cpp : : : : search_test3 ] [ run search_test3.cpp : : : : search_test3 ]
[ run search_test4.cpp : : : : search_test4 ]
[ compile-fail search_fail1.cpp : : : : ] [ compile-fail search_fail1.cpp : : : : ]
[ compile-fail search_fail2.cpp : : : : ] [ compile-fail search_fail2.cpp : : : : ]
[ compile-fail search_fail3.cpp : : : : ] [ compile-fail search_fail3.cpp : : : : ]
@ -44,7 +43,6 @@ import testing ;
[ run hex_test1.cpp : : : : hex_test1 ] [ run hex_test1.cpp : : : : hex_test1 ]
[ run hex_test2.cpp : : : : hex_test2 ] [ run hex_test2.cpp : : : : hex_test2 ]
[ run hex_test3.cpp : : : : hex_test3 ] [ run hex_test3.cpp : : : : hex_test3 ]
[ run hex_test4.cpp : : : : hex_test4 ]
[ compile-fail hex_fail1.cpp ] [ 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)); BOOST_CHECK ( ba::is_sorted_until ( a_range(strictlyIncreasingValues), std::less<int>()) == boost::end(strictlyIncreasingValues));
// Check for const and non-const arrays // 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 ( 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 ( 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 ( 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 ( 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), std::less<int>()) == &randomValues[2] );
BOOST_CHECK ( ba::is_sorted_until ( b_e(randomValues)) == &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;
}