forked from boostorg/algorithm
Compare commits
97 Commits
boost-1.52
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
4b0fe81140 | |||
bca416c177 | |||
823e059a0e | |||
e3263d43e4 | |||
1af25699b7 | |||
49668cf66a | |||
a92ae91b23 | |||
028d9aedcd | |||
dfaea65083 | |||
eb8291e0aa | |||
f023127c99 | |||
43c01ff2bc | |||
8693e875a5 | |||
8bfaa6dad3 | |||
6fbc7401d5 | |||
d518994247 | |||
ba98f32d1b | |||
ba417e875a | |||
8549207f05 | |||
040fb0650b | |||
e92d471817 | |||
34c49f856c | |||
5473509fad | |||
caea7bd125 | |||
81b04cde96 | |||
276073ca64 | |||
a7f5bdd781 | |||
0c0a866f07 | |||
9d25072f2f | |||
823b199df3 | |||
fecd440527 | |||
3325d3a3f8 | |||
ebf104c127 | |||
3b76763807 | |||
62df1eb048 | |||
f5dd47883f | |||
9d68c4280c | |||
1e8b3ee752 | |||
42147c8385 | |||
672775545d | |||
46ed1bf987 | |||
6289ed7f98 | |||
8e97668b1f | |||
e7c23d2f13 | |||
a1e7512012 | |||
31b5842441 | |||
4515bc182e | |||
7e2e6856cc | |||
235c81be61 | |||
1eb3d83534 | |||
8f2b8d4888 | |||
6c0f953c01 | |||
e439792494 | |||
236b142308 | |||
9bad789175 | |||
d84f81d841 | |||
ce98e8b87e | |||
e8a2596637 | |||
7b2754b937 | |||
784402e5c0 | |||
1188575e7b | |||
bff2a1e112 | |||
6d5e7b5a04 | |||
760af1798b | |||
1f5542b44c | |||
baf3dd99e2 | |||
7299b29bf8 | |||
539c170b9d | |||
c81ee948b7 | |||
ba5e4c30c6 | |||
cd26ed816c | |||
4e15767bed | |||
9fa2f90db4 | |||
35f317aeac | |||
d0a03fdb4e | |||
346f032be2 | |||
a389d768c4 | |||
90fca39906 | |||
5b24f31486 | |||
b25d6511b3 | |||
1541a554f5 | |||
7a97b3390e | |||
6e5a7497ae | |||
f0b8b60379 | |||
66019abb2f | |||
8758222006 | |||
4eef56761a | |||
b94a3fbfba | |||
614cc2ebab | |||
869660ed14 | |||
777f30780e | |||
26aa37733b | |||
f1e60579c2 | |||
389dd3c863 | |||
f23f61ae9b | |||
608112b112 | |||
b21b54dc4e |
@ -16,6 +16,8 @@ using quickbook ;
|
||||
using doxygen ;
|
||||
using boostbook ;
|
||||
|
||||
local BOOST_ROOT = [ os.environ BOOST_ROOT ] ;
|
||||
|
||||
doxygen autodoc
|
||||
:
|
||||
[ glob ../../../boost/algorithm/*.hpp ../../../boost/algorithm/searching/*.hpp ]
|
||||
@ -27,12 +29,14 @@ doxygen autodoc
|
||||
|
||||
xml algorithm : algorithm.qbk ;
|
||||
|
||||
# path-constant boost-images : $(BOOST_ROOT)/doc/src/images ;
|
||||
|
||||
boostbook standalone
|
||||
:
|
||||
algorithm
|
||||
:
|
||||
<dependency>autodoc
|
||||
<xsl:param>boost.root=../../../..
|
||||
<xsl:param>boost.root=$(BOOST_ROOT)
|
||||
<xsl:param>"boost.doxygen.reftitle=Boost.Algorithms C++ Reference"
|
||||
<xsl:param>chapter.autolabel=0
|
||||
<xsl:param>chunk.section.depth=8
|
||||
|
@ -24,8 +24,6 @@ However, the Boyer-Moore algorithm cannot be used with comparison predicates lik
|
||||
|
||||
Nomenclature: I refer to the sequence being searched for as the "pattern", and the sequence being searched in as the "corpus".
|
||||
|
||||
[heading Interface]
|
||||
|
||||
For flexibility, the Boyer-Moore algorithm has has two interfaces; an object-based interface and a procedural one. The object-based interface builds the tables in the constructor, and uses operator () to perform the search. The procedural interface builds the table and does the search all in one step. If you are going to be searching for the same pattern in multiple corpora, then you should use the object interface, and only build the tables once.
|
||||
|
||||
Here is the object interface:
|
||||
@ -80,7 +78,7 @@ Both the object-oriented and procedural versions of the Boyer-Moore algorithm ta
|
||||
|
||||
The Boyer-Moore object takes a traits template parameter which enables the caller to customize how one of the precomputed tables is stored. This table, called the skip table, contains (logically) one entry for every possible value that the pattern can contain. When searching 8-bit character data, this table contains 256 elements. The traits class defines the table to be used.
|
||||
|
||||
The default traits class uses a `boost::array` for small 'alphabets' and a `tr1::unordered_map` for larger ones. The array-based skip table gives excellent performance, but could be prohibitively large when the 'alphabet' of elements to be searched grows. The unordered_map based version only grows as the number of unique elements in the pattern, but makes many more heap allocations, and gives slower lookup performance.
|
||||
The default traits class uses a `boost::array` for small 'alphabets' and a `tr1::unordered_map` for larger ones. The array-based skip table gives excellent performance, but could be prohibitively large when the "alphabet" of elements to be searched grows. The unordered_map based version only grows as the number of unique elements in the pattern, but makes many more heap allocations, and gives slower lookup performance.
|
||||
|
||||
To use a different skip table, you should define your own skip table object and your own traits class, and use them to instantiate the Boyer-Moore object. The interface to these objects is described TBD.
|
||||
|
||||
|
@ -16,72 +16,6 @@ http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
The header file 'boyer_moore_horspool.hpp' contains an an implementation of the Boyer-Moore-Horspool algorithm for searching sequences of values.
|
||||
|
||||
The Boyer-Moore-Horspool search algorithm was published by Nigel Horspool in 1980. It is a refinement of the Boyer-Moore algorithm that trades space for time. It uses less space for internal tables than Boyer-Moore, and has poorer worst-case performance.
|
||||
|
||||
The Boyer-Moore-Horspool algorithm cannot be used with comparison predicates like `std::search`.
|
||||
|
||||
[heading Interface]
|
||||
|
||||
Nomenclature: I refer to the sequence being searched for as the "pattern", and the sequence being searched in as the "corpus".
|
||||
|
||||
For flexibility, the Boyer-Moore-Horspool algorithm has has two interfaces; an object-based interface and a procedural one. The object-based interface builds the tables in the constructor, and uses operator () to perform the search. The procedural interface builds the table and does the search all in one step. If you are going to be searching for the same pattern in multiple corpora, then you should use the object interface, and only build the tables once.
|
||||
|
||||
Here is the object interface:
|
||||
``
|
||||
template <typename patIter>
|
||||
class boyer_moore_horspool {
|
||||
public:
|
||||
boyer_moore_horspool ( patIter first, patIter last );
|
||||
~boyer_moore_horspool ();
|
||||
|
||||
template <typename corpusIter>
|
||||
corpusIter operator () ( corpusIter corpus_first, corpusIter corpus_last );
|
||||
};
|
||||
``
|
||||
|
||||
and here is the corresponding procedural interface:
|
||||
|
||||
``
|
||||
template <typename patIter, typename corpusIter>
|
||||
corpusIter boyer_moore_horspool_search (
|
||||
corpusIter corpus_first, corpusIter corpus_last,
|
||||
patIter pat_first, patIter pat_last );
|
||||
``
|
||||
|
||||
Each of the functions is passed two pairs of iterators. The first two define the corpus and the second two define the pattern. Note that the two pairs need not be of the same type, but they do need to "point" at the same type. In other words, `patIter::value_type` and `curpusIter::value_type` need to be the same type.
|
||||
|
||||
The return value of the function is an iterator pointing to the start of the pattern in the corpus. If the pattern is not found, it returns the end of the corpus (`corpus_last`).
|
||||
|
||||
[heading Performance]
|
||||
|
||||
The execution time of the Boyer-Moore-Horspool algorithm is linear in the size of the string being searched; it can have a significantly lower constant factor than many other search algorithms: it doesn't need to check every character of the string to be searched, but rather skips over some of them. Generally the algorithm gets faster as the pattern being searched for becomes longer. Its efficiency derives from the fact that with each unsuccessful attempt to find a match between the search string and the text it is searching, it uses the information gained from that attempt to rule out as many positions of the text as possible where the string cannot match.
|
||||
|
||||
[heading Memory Use]
|
||||
|
||||
The algorithm an internal table that has one entry for each member of the "alphabet" in the pattern. For (8-bit) character types, this table contains 256 entries.
|
||||
|
||||
[heading Complexity]
|
||||
|
||||
The worst-case performance is ['O(m x n)], where ['m] is the length of the pattern and ['n] is the length of the corpus. The average time is ['O(n)]. The best case performance is sub-linear, and is, in fact, identical to Boyer-Moore, but the initialization is quicker and the internal loop is simpler than Boyer-Moore.
|
||||
|
||||
[heading Exception Safety]
|
||||
|
||||
Both the object-oriented and procedural versions of the Boyer-Moore-Horspool algorithm take their parameters by value and do not use any information other than what is passed in. Therefore, both interfaces provide the strong exception guarantee.
|
||||
|
||||
[heading Notes]
|
||||
|
||||
* When using the object-based interface, the pattern must remain unchanged for during the searches; i.e, from the time the object is constructed until the final call to operator () returns.
|
||||
|
||||
* The Boyer-Moore-Horspool algorithm requires random-access iterators for both the pattern and the corpus.
|
||||
|
||||
[heading Customization points]
|
||||
|
||||
The Boyer-Moore-Horspool object takes a traits template parameter which enables the caller to customize how the precomputed table is stored. This table, called the skip table, contains (logically) one entry for every possible value that the pattern can contain. When searching 8-bit character data, this table contains 256 elements. The traits class defines the table to be used.
|
||||
|
||||
The default traits class uses a `boost::array` for small 'alphabets' and a `tr1::unordered_map` for larger ones. The array-based skip table gives excellent performance, but could be prohibitively large when the 'alphabet' of elements to be searched grows. The unordered_map based version only grows as the number of unique elements in the pattern, but makes many more heap allocations, and gives slower lookup performance.
|
||||
|
||||
To use a different skip table, you should define your own skip table object and your own traits class, and use them to instantiate the Boyer-Moore-Horspool object. The interface to these objects is described TBD.
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
|
@ -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 )
|
||||
|
@ -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 {
|
||||
|
0
include/boost/algorithm/clamp.hpp
Normal file → Executable file
0
include/boost/algorithm/clamp.hpp
Normal file → Executable file
@ -12,7 +12,6 @@
|
||||
#ifndef BOOST_ALGORITHM_ALL_OF_HPP
|
||||
#define BOOST_ALGORITHM_ALL_OF_HPP
|
||||
|
||||
#include <algorithm> // for std::all_of, if available
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
#ifndef BOOST_ALGORITHM_ANY_OF_HPP
|
||||
#define BOOST_ALGORITHM_ANY_OF_HPP
|
||||
|
||||
#include <algorithm> // for std::any_of, if available
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
#ifndef BOOST_ALGORITHM_COPY_IF_HPP
|
||||
#define BOOST_ALGORITHM_COPY_IF_HPP
|
||||
|
||||
#include <algorithm> // for std::copy_if, if available
|
||||
#include <algorithm> // for std::copy_if, if available
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
@ -39,7 +39,7 @@ OutputIterator copy_if ( InputIterator first, InputIterator last, OutputIterator
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if (p(*first))
|
||||
*result++ = *first;
|
||||
*result++ = first;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
@ -75,7 +75,7 @@ OutputIterator copy_while ( InputIterator first, InputIterator last,
|
||||
OutputIterator result, Predicate p )
|
||||
{
|
||||
for ( ; first != last && p(*first); ++first )
|
||||
*result++ = *first;
|
||||
*result++ = first;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ template<typename InputIterator, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
|
||||
{
|
||||
for ( ; first != last && !p(*first); ++first )
|
||||
*result++ = *first;
|
||||
*result++ = first;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -71,4 +71,4 @@ OutputIterator iota_n ( OutputIterator out, T value, std::size_t n )
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_IOTA_HPP
|
||||
#endif // BOOST_ALGORITHM_IOTA_HPP
|
@ -12,7 +12,7 @@
|
||||
#ifndef BOOST_ALGORITHM_IS_PARTITIONED_HPP
|
||||
#define BOOST_ALGORITHM_IS_PARTITIONED_HPP
|
||||
|
||||
#include <algorithm> // for std::is_partitioned, if available
|
||||
#include <algorithm> // for std::is_partitioned, if available
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
@ -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 )
|
||||
@ -35,14 +35,14 @@ using std::is_partitioned; // Section 25.3.13
|
||||
template <typename InputIterator, typename UnaryPredicate>
|
||||
bool is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p )
|
||||
{
|
||||
// Run through the part that satisfy the predicate
|
||||
// Run through the part that satisfy the predicate
|
||||
for ( ; first != last; ++first )
|
||||
if ( !p (*first))
|
||||
break;
|
||||
// Now the part that does not satisfy the predicate
|
||||
break;
|
||||
// Now the part that does not satisfy the predicate
|
||||
for ( ; first != last; ++first )
|
||||
if ( p (*first))
|
||||
return false;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@ -62,4 +62,4 @@ bool is_partitioned ( const Range &r, UnaryPredicate p )
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_IS_PARTITIONED_HPP
|
||||
#endif // BOOST_ALGORITHM_IS_PARTITIONED_HPP
|
@ -46,7 +46,7 @@ namespace detail {
|
||||
|
||||
|
||||
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 first2, BinaryPredicate p )
|
||||
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
/// \brief Tests to see if a the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
@ -88,7 +88,7 @@ bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
}
|
||||
|
||||
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 first2 )
|
||||
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
/// \brief Tests to see if a the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
@ -108,7 +108,7 @@ bool is_permutation ( ForwardIterator1 first, ForwardIterator1 last, ForwardIter
|
||||
#endif
|
||||
|
||||
/// \fn is_permutation ( const Range &r, ForwardIterator first2 )
|
||||
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
/// \brief Tests to see if a the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param first2 The start of the second sequence
|
||||
@ -119,7 +119,7 @@ bool is_permutation ( const Range &r, ForwardIterator first2 )
|
||||
}
|
||||
|
||||
/// \fn is_permutation ( const Range &r, ForwardIterator first2, BinaryPredicate pred )
|
||||
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
/// \brief Tests to see if a the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param first2 The start of the second sequence
|
||||
@ -136,4 +136,4 @@ is_permutation ( const Range &r, ForwardIterator first2, BinaryPredicate pred )
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
||||
#endif // BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
@ -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>());
|
||||
}
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ using std::is_sorted; // Section 25.4.1.5
|
||||
#endif
|
||||
|
||||
///
|
||||
/// -- Range based versions of the C++11 functions
|
||||
/// -- Range based versions of the C++11 functions
|
||||
///
|
||||
|
||||
/// \fn is_sorted_until ( const R &range, Pred p )
|
||||
@ -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').
|
||||
@ -153,7 +157,7 @@ using std::is_sorted; // Section 25.4.1.5
|
||||
|
||||
|
||||
///
|
||||
/// -- Range based versions of the C++11 functions
|
||||
/// -- Range based versions of the C++11 functions
|
||||
///
|
||||
|
||||
/// \fn is_increasing ( ForwardIterator first, ForwardIterator last )
|
||||
@ -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 )
|
||||
|
@ -12,7 +12,6 @@
|
||||
#ifndef BOOST_ALGORITHM_NONE_OF_HPP
|
||||
#define BOOST_ALGORITHM_NONE_OF_HPP
|
||||
|
||||
#include <algorithm> // for std::none_of, if available
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
#ifndef BOOST_ALGORITHM_PARTITION_COPY_HPP
|
||||
#define BOOST_ALGORITHM_PARTITION_COPY_HPP
|
||||
|
||||
#include <algorithm> // for std::partition_copy, if available
|
||||
#include <utility> // for make_pair
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
|
@ -12,7 +12,7 @@
|
||||
#ifndef BOOST_ALGORITHM_PARTITION_POINT_HPP
|
||||
#define BOOST_ALGORITHM_PARTITION_POINT_HPP
|
||||
|
||||
#include <algorithm> // for std::partition_point, if available
|
||||
#include <algorithm> // for std::partition_point, if available
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
@ -20,12 +20,12 @@
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of partition_point if it is available
|
||||
// Use the C++11 versions of iota if it is available
|
||||
using std::partition_point; // Section 25.3.13
|
||||
#else
|
||||
/// \fn partition_point ( ForwardIterator first, ForwardIterator last, Predicate p )
|
||||
/// \brief Given a partitioned range, returns the partition point, i.e, the first element
|
||||
/// that does not satisfy p
|
||||
/// that does not satisfy p
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
@ -69,4 +69,4 @@ typename boost::range_iterator<Range> partition_point ( Range &r, Predicate p )
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_PARTITION_POINT_HPP
|
||||
#endif // BOOST_ALGORITHM_PARTITION_POINT_HPP
|
@ -45,16 +45,20 @@ namespace boost { namespace algorithm {
|
||||
|
||||
\struct non_hex_input
|
||||
\brief Thrown when a non-hex value (0-9, A-F) encountered when decoding.
|
||||
Contains the offending character
|
||||
Contains the offending character
|
||||
|
||||
\struct not_enough_input
|
||||
\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
|
||||
@ -69,18 +73,14 @@ namespace detail {
|
||||
return std::copy ( res, res + num_hex_digits, out );
|
||||
}
|
||||
|
||||
// this needs to be in an un-named namespace because it is not a template
|
||||
// and might get included in several compilation units. This could cause
|
||||
// multiple definition errors at link time.
|
||||
namespace {
|
||||
unsigned hex_char_to_int ( char c ) {
|
||||
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));
|
||||
return 0; // keep dumb compilers happy
|
||||
BOOST_THROW_EXCEPTION (non_hex_input (c));
|
||||
return 0; // keep dumb compilers happy
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// My own iterator_traits class.
|
||||
// It is here so that I can "reach inside" some kinds of output iterators
|
||||
@ -109,30 +109,38 @@ namespace detail {
|
||||
// The first one is the output type, the second one is the character type of
|
||||
// the underlying stream, the third is the character traits.
|
||||
// We only care about the first one.
|
||||
template<typename T, typename charType, typename traits>
|
||||
struct hex_iterator_traits< std::ostream_iterator<T, charType, traits> > {
|
||||
typedef T value_type;
|
||||
};
|
||||
template<typename T, typename charType, typename traits>
|
||||
struct hex_iterator_traits< std::ostream_iterator<T, charType, traits> > {
|
||||
typedef T value_type;
|
||||
};
|
||||
|
||||
// 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>
|
||||
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'; }
|
||||
|
||||
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));
|
||||
}
|
||||
@ -201,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;
|
||||
}
|
||||
|
||||
@ -215,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;
|
||||
}
|
||||
|
||||
|
4
include/boost/algorithm/searching/boyer_moore.hpp
Normal file → Executable file
4
include/boost/algorithm/searching/boyer_moore.hpp
Normal file → Executable 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));
|
||||
}
|
||||
|
62
include/boost/algorithm/searching/boyer_moore_horspool.hpp
Normal file → Executable file
62
include/boost/algorithm/searching/boyer_moore_horspool.hpp
Normal file → Executable file
@ -14,11 +14,6 @@
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/algorithm/searching/detail/bm_traits.hpp>
|
||||
@ -89,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;
|
||||
@ -129,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.
|
||||
@ -143,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));
|
||||
}
|
||||
|
||||
}}
|
||||
|
0
include/boost/algorithm/searching/detail/bm_traits.hpp
Normal file → Executable file
0
include/boost/algorithm/searching/detail/bm_traits.hpp
Normal file → Executable file
0
include/boost/algorithm/searching/detail/debugging.hpp
Normal file → Executable file
0
include/boost/algorithm/searching/detail/debugging.hpp
Normal file → Executable file
64
include/boost/algorithm/searching/knuth_morris_pratt.hpp
Normal file → Executable file
64
include/boost/algorithm/searching/knuth_morris_pratt.hpp
Normal file → Executable file
@ -15,11 +15,6 @@
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/algorithm/searching/detail/debugging.hpp>
|
||||
@ -37,7 +32,7 @@ namespace boost { namespace algorithm {
|
||||
* Random-access iterators
|
||||
* The two iterator types (I1 and I2) must "point to" the same underlying type.
|
||||
|
||||
http://en.wikipedia.org/wiki/Knuth-Morris-Pratt_algorithm
|
||||
http://en.wikipedia.org/wiki/Knuth–Morris–Pratt_algorithm
|
||||
http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/kmpen.htm
|
||||
*/
|
||||
|
||||
@ -84,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;
|
||||
@ -189,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.
|
||||
@ -203,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));
|
||||
}
|
||||
}}
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
13
index.html
13
index.html
@ -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> <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>
|
@ -130,17 +130,17 @@
|
||||
string str1("command.com");
|
||||
cout
|
||||
<< str1
|
||||
<< (is_executable(str1)? "is": "is not")
|
||||
<< (is_executable("command.com")? "is": "is not")
|
||||
<< "an executable"
|
||||
<< endl; // prints "command.com is an executable"
|
||||
|
||||
//..
|
||||
char text1[]="hello";
|
||||
char text1[]="hello world!";
|
||||
cout
|
||||
<< text1
|
||||
<< (all( text1, is_lower() )? " is": " is not")
|
||||
<< (all( text1, is_lower() )? "is": "is not")
|
||||
<< " written in the lower case"
|
||||
<< endl; // prints "hello is written in the lower case"
|
||||
<< endl; // prints "hello world! is written in the lower case"
|
||||
</programlisting>
|
||||
<para>
|
||||
The predicates determine whether if a substring is contained in the input string
|
||||
@ -149,11 +149,6 @@
|
||||
simply contains the substring or if both strings are equal. See the reference for
|
||||
<headername>boost/algorithm/string/predicate.hpp</headername> for more details.
|
||||
</para>
|
||||
<para>
|
||||
Note that if we had used "hello world" as the input to the test, it would have
|
||||
output "hello world is not written in the lower case" because the space in the
|
||||
input string is not a lower case letter.
|
||||
</para>
|
||||
<para>
|
||||
In addition the algorithm <functionname>all()</functionname> checks
|
||||
all elements of a container to satisfy a condition specified by a predicate.
|
||||
|
3
test/Jamfile.v2
Normal file → Executable file
3
test/Jamfile.v2
Normal file → Executable 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 : : : : ]
|
||||
@ -32,7 +31,6 @@ import testing ;
|
||||
|
||||
[ run ordered_test.cpp : : : : ordered_test ]
|
||||
[ run find_if_not_test1.cpp : : : : find_if_not_test1 ]
|
||||
[ run copy_if_test1.cpp : : : : copy_if_test1 ]
|
||||
[ run copy_n_test1.cpp : : : : copy_n_test1 ]
|
||||
[ run iota_test1.cpp : : : : iota_test1 ]
|
||||
|
||||
@ -45,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 ]
|
||||
;
|
||||
}
|
||||
|
0
test/clamp_test.cpp
Normal file → Executable file
0
test/clamp_test.cpp
Normal file → Executable file
@ -1,87 +0,0 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2012.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/cxx11/copy_if.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#include <boost/algorithm/cxx11/all_of.hpp>
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
// namespace ba = boost;
|
||||
|
||||
bool is_true ( int v ) { return true; }
|
||||
bool is_false ( int v ) { return false; }
|
||||
bool is_even ( int v ) { return v % 2 == 0; }
|
||||
bool is_odd ( int v ) { return v % 2 == 1; }
|
||||
|
||||
template <typename Container>
|
||||
void test_sequence ( Container const &c ) {
|
||||
|
||||
typedef typename Container::value_type value_type;
|
||||
std::vector<value_type> v;
|
||||
|
||||
// None of the elements
|
||||
v.clear ();
|
||||
ba::copy_if ( c.begin (), c.end (), back_inserter ( v ), is_false);
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
|
||||
v.clear ();
|
||||
ba::copy_if ( c, back_inserter ( v ), is_false);
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
|
||||
// All the elements
|
||||
v.clear ();
|
||||
ba::copy_if ( c.begin (), c.end (), back_inserter ( v ), is_true);
|
||||
BOOST_CHECK ( v.size () == c.size ());
|
||||
BOOST_CHECK ( std::equal ( c.begin (), c.end (), v.begin ()));
|
||||
|
||||
v.clear ();
|
||||
ba::copy_if ( c, back_inserter ( v ), is_true);
|
||||
BOOST_CHECK ( v.size () == c.size ());
|
||||
BOOST_CHECK ( v.size () == c.size ());
|
||||
BOOST_CHECK ( std::equal ( c.begin (), c.end (), v.begin ()));
|
||||
|
||||
// Some of the elements
|
||||
v.clear ();
|
||||
ba::copy_if ( c.begin (), c.end (), back_inserter ( v ), is_even );
|
||||
BOOST_CHECK ( v.size () == std::count_if ( c.begin (), c.end (), is_even ));
|
||||
BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
|
||||
|
||||
v.clear ();
|
||||
ba::copy_if ( c, back_inserter ( v ), is_even );
|
||||
BOOST_CHECK ( v.size () == std::count_if ( c.begin (), c.end (), is_even ));
|
||||
BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
|
||||
}
|
||||
|
||||
|
||||
void test_sequence1 () {
|
||||
std::vector<int> v;
|
||||
for ( int i = 5; i < 15; ++i )
|
||||
v.push_back ( i );
|
||||
test_sequence ( v );
|
||||
|
||||
std::list<int> l;
|
||||
for ( int i = 25; i > 15; --i )
|
||||
l.push_back ( i );
|
||||
test_sequence ( l );
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
{
|
||||
test_sequence1 ();
|
||||
return 0;
|
||||
}
|
@ -22,60 +22,60 @@ namespace ba = boost::algorithm;
|
||||
template <typename Container>
|
||||
void test_sequence ( Container const &c ) {
|
||||
|
||||
typedef typename Container::value_type value_type;
|
||||
std::vector<value_type> v;
|
||||
|
||||
// Copy zero elements
|
||||
v.clear ();
|
||||
ba::copy_n ( c.begin (), 0, back_inserter ( v ));
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
ba::copy_n ( c.begin (), 0U, back_inserter ( v ));
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
typedef typename Container::value_type value_type;
|
||||
std::vector<value_type> v;
|
||||
|
||||
// Copy zero elements
|
||||
v.clear ();
|
||||
ba::copy_n ( c.begin (), 0, back_inserter ( v ));
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
ba::copy_n ( c.begin (), 0U, back_inserter ( v ));
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
|
||||
if ( c.size () > 0 ) {
|
||||
// Just one element
|
||||
v.clear ();
|
||||
ba::copy_n ( c.begin (), 1, back_inserter ( v ));
|
||||
BOOST_CHECK ( v.size () == 1 );
|
||||
BOOST_CHECK ( v[0] == *c.begin ());
|
||||
|
||||
v.clear ();
|
||||
ba::copy_n ( c.begin (), 1U, back_inserter ( v ));
|
||||
BOOST_CHECK ( v.size () == 1 );
|
||||
BOOST_CHECK ( v[0] == *c.begin ());
|
||||
if ( c.size () > 0 ) {
|
||||
// Just one element
|
||||
v.clear ();
|
||||
ba::copy_n ( c.begin (), 1, back_inserter ( v ));
|
||||
BOOST_CHECK ( v.size () == 1 );
|
||||
BOOST_CHECK ( v[0] == *c.begin ());
|
||||
|
||||
v.clear ();
|
||||
ba::copy_n ( c.begin (), 1U, back_inserter ( v ));
|
||||
BOOST_CHECK ( v.size () == 1 );
|
||||
BOOST_CHECK ( v[0] == *c.begin ());
|
||||
|
||||
// Half the elements
|
||||
v.clear ();
|
||||
ba::copy_n ( c.begin (), c.size () / 2, back_inserter ( v ));
|
||||
BOOST_CHECK ( v.size () == c.size () / 2);
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
// Half the elements
|
||||
v.clear ();
|
||||
ba::copy_n ( c.begin (), c.size () / 2, back_inserter ( v ));
|
||||
BOOST_CHECK ( v.size () == c.size () / 2);
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
|
||||
// Half the elements + 1
|
||||
v.clear ();
|
||||
ba::copy_n ( c.begin (), c.size () / 2 + 1, back_inserter ( v ));
|
||||
BOOST_CHECK ( v.size () == c.size () / 2 + 1 );
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
|
||||
// All the elements
|
||||
v.clear ();
|
||||
ba::copy_n ( c.begin (), c.size (), back_inserter ( v ));
|
||||
BOOST_CHECK ( v.size () == c.size ());
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
}
|
||||
}
|
||||
// Half the elements + 1
|
||||
v.clear ();
|
||||
ba::copy_n ( c.begin (), c.size () / 2 + 1, back_inserter ( v ));
|
||||
BOOST_CHECK ( v.size () == c.size () / 2 + 1 );
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
|
||||
// All the elements
|
||||
v.clear ();
|
||||
ba::copy_n ( c.begin (), c.size (), back_inserter ( v ));
|
||||
BOOST_CHECK ( v.size () == c.size ());
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void test_sequence1 () {
|
||||
std::vector<int> v;
|
||||
for ( int i = 5; i < 15; ++i )
|
||||
v.push_back ( i );
|
||||
test_sequence ( v );
|
||||
|
||||
std::list<int> l;
|
||||
for ( int i = 25; i > 15; --i )
|
||||
l.push_back ( i );
|
||||
test_sequence ( l );
|
||||
}
|
||||
std::vector<int> v;
|
||||
for ( int i = 5; i < 15; ++i )
|
||||
v.push_back ( i );
|
||||
test_sequence ( v );
|
||||
|
||||
std::list<int> l;
|
||||
for ( int i = 25; i > 15; --i )
|
||||
l.push_back ( i );
|
||||
test_sequence ( l );
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
|
0
test/empty_search_test.cpp
Normal file → Executable file
0
test/empty_search_test.cpp
Normal file → Executable file
@ -22,18 +22,18 @@ namespace ba = boost::algorithm;
|
||||
|
||||
template <typename Container>
|
||||
typename Container::iterator offset_to_iter ( Container &v, int offset ) {
|
||||
typename Container::iterator retval;
|
||||
|
||||
if ( offset >= 0 ) {
|
||||
retval = v.begin ();
|
||||
std::advance ( retval, offset );
|
||||
}
|
||||
else {
|
||||
retval = v.end ();
|
||||
std::advance ( retval, offset + 1 );
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
typename Container::iterator retval;
|
||||
|
||||
if ( offset >= 0 ) {
|
||||
retval = v.begin ();
|
||||
std::advance ( retval, offset );
|
||||
}
|
||||
else {
|
||||
retval = v.end ();
|
||||
std::advance ( retval, offset + 1 );
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
template <typename Container, typename Predicate>
|
||||
void test_sequence ( Container &v, Predicate comp, int expected ) {
|
||||
@ -71,7 +71,7 @@ void test_sequence1 () {
|
||||
test_sequence ( v, less_than<int>(10), 5 );
|
||||
test_sequence ( v, less_than<int>(99), -1 ); // all elements satisfy
|
||||
|
||||
// With bidirectional iterators.
|
||||
// With bidirectional iterators.
|
||||
std::list<int> l;
|
||||
for ( int i = 5; i < 15; ++i )
|
||||
l.push_back ( i );
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
// should not compile: vector is not an integral type
|
||||
// should not compile: vector is not an integral type
|
||||
int test_main( int , char* [] )
|
||||
{
|
||||
std::vector<float> v;
|
||||
|
@ -21,12 +21,12 @@ Try ostream_iterators
|
||||
|
||||
template <typename char_type>
|
||||
void test_to_hex ( const char_type ** tests ) {
|
||||
typedef std::basic_string<char_type> String;
|
||||
typedef std::basic_ostringstream<char_type> Stream;
|
||||
typedef std::ostream_iterator<char_type, char_type> Iter;
|
||||
typedef std::basic_string<char_type> String;
|
||||
typedef std::basic_ostringstream<char_type> Stream;
|
||||
typedef std::ostream_iterator<char_type, char_type> Iter;
|
||||
|
||||
for ( const char_type **p = tests; *p; p++ ) {
|
||||
String arg, argh;
|
||||
String arg, argh;
|
||||
Stream one, two, three;
|
||||
arg.assign ( *p );
|
||||
boost::algorithm::hex ( *p, Iter ( one ));
|
||||
@ -49,12 +49,12 @@ void test_to_hex ( const char_type ** tests ) {
|
||||
|
||||
template <typename char_type>
|
||||
void test_from_hex_success ( const char_type ** tests ) {
|
||||
typedef std::basic_string<char_type> String;
|
||||
typedef std::basic_ostringstream<char_type> Stream;
|
||||
typedef std::ostream_iterator<char_type, char_type> Iter;
|
||||
typedef std::basic_string<char_type> String;
|
||||
typedef std::basic_ostringstream<char_type> Stream;
|
||||
typedef std::ostream_iterator<char_type, char_type> Iter;
|
||||
|
||||
for ( const char_type **p = tests; *p; p++ ) {
|
||||
String arg, argh;
|
||||
String arg, argh;
|
||||
Stream one, two, three;
|
||||
arg.assign ( *p );
|
||||
boost::algorithm::unhex ( *p, Iter ( one ));
|
||||
|
@ -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;
|
||||
}
|
@ -16,60 +16,60 @@
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
// Test to make sure a sequence is "correctly formed"; i.e, ascending by one
|
||||
// Test to make sure a sequence is "correctly formed"; i.e, ascending by one
|
||||
template <typename Iterator, typename T>
|
||||
bool test_iota_results ( Iterator first, Iterator last, T initial_value ) {
|
||||
if ( first == last ) return true;
|
||||
if ( initial_value != *first ) return false;
|
||||
Iterator prev = first;
|
||||
while ( ++first != last ) {
|
||||
if (( *first - *prev ) != 1 )
|
||||
return false;
|
||||
prev = first;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if ( first == last ) return true;
|
||||
if ( initial_value != *first ) return false;
|
||||
Iterator prev = first;
|
||||
while ( ++first != last ) {
|
||||
if (( *first - *prev ) != 1 )
|
||||
return false;
|
||||
prev = first;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Range, typename T>
|
||||
bool test_iota_results ( const Range &r, T initial_value ) {
|
||||
return test_iota_results (boost::begin (r), boost::end (r), initial_value );
|
||||
return test_iota_results (boost::begin (r), boost::end (r), initial_value );
|
||||
}
|
||||
|
||||
|
||||
void test_ints () {
|
||||
std::vector<int> v;
|
||||
std::list<int> l;
|
||||
std::vector<int> v;
|
||||
std::list<int> l;
|
||||
|
||||
v.clear (); v.reserve ( 10 );
|
||||
boost::algorithm::iota ( v.begin (), v.end (), 23 );
|
||||
BOOST_CHECK ( test_iota_results ( v.begin (), v.end (), 23 ));
|
||||
|
||||
v.clear (); v.reserve ( 19 );
|
||||
boost::algorithm::iota ( v, 18 );
|
||||
BOOST_CHECK ( test_iota_results ( v, 18 ));
|
||||
|
||||
v.clear ();
|
||||
boost::algorithm::iota_n ( std::back_inserter(v), 99, 20 );
|
||||
BOOST_CHECK ( test_iota_results ( v, 99 ));
|
||||
|
||||
v.clear (); v.reserve ( 10 );
|
||||
boost::algorithm::iota ( v.begin (), v.end (), 23 );
|
||||
BOOST_CHECK ( test_iota_results ( v.begin (), v.end (), 23 ));
|
||||
|
||||
v.clear (); v.reserve ( 19 );
|
||||
boost::algorithm::iota ( v, 18 );
|
||||
BOOST_CHECK ( test_iota_results ( v, 18 ));
|
||||
|
||||
v.clear ();
|
||||
boost::algorithm::iota_n ( std::back_inserter(v), 99, 20 );
|
||||
BOOST_CHECK ( test_iota_results ( v, 99 ));
|
||||
|
||||
/*
|
||||
l.clear (); l.reserve ( 5 );
|
||||
boost::algorithm::iota ( l.begin (), l.end (), 123 );
|
||||
BOOST_CHECK ( test_iota_results ( l.begin (), l.end (), 123 ));
|
||||
|
||||
l.clear (); l.reserve ( 9 );
|
||||
boost::algorithm::iota ( l.begin (), l.end (), 87 );
|
||||
BOOST_CHECK ( test_iota_results ( l.begin (), l.end (), 87 ));
|
||||
l.clear (); l.reserve ( 5 );
|
||||
boost::algorithm::iota ( l.begin (), l.end (), 123 );
|
||||
BOOST_CHECK ( test_iota_results ( l.begin (), l.end (), 123 ));
|
||||
|
||||
l.clear (); l.reserve ( 9 );
|
||||
boost::algorithm::iota ( l.begin (), l.end (), 87 );
|
||||
BOOST_CHECK ( test_iota_results ( l.begin (), l.end (), 87 ));
|
||||
*/
|
||||
|
||||
l.clear ();
|
||||
boost::algorithm::iota_n ( std::back_inserter(l), 99, 20 );
|
||||
BOOST_CHECK ( test_iota_results ( l, 99 ));
|
||||
|
||||
l.clear ();
|
||||
boost::algorithm::iota_n ( std::front_inserter(l), 123, 20 );
|
||||
BOOST_CHECK ( test_iota_results ( l.rbegin (), l.rend (), 123 ));
|
||||
}
|
||||
l.clear ();
|
||||
boost::algorithm::iota_n ( std::back_inserter(l), 99, 20 );
|
||||
BOOST_CHECK ( test_iota_results ( l, 99 ));
|
||||
|
||||
l.clear ();
|
||||
boost::algorithm::iota_n ( std::front_inserter(l), 123, 20 );
|
||||
BOOST_CHECK ( test_iota_results ( l.rbegin (), l.rend (), 123 ));
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
|
@ -40,19 +40,19 @@ void test_sequence1 () {
|
||||
v.clear ();
|
||||
for ( int i = 5; i < 15; ++i )
|
||||
v.push_back ( i );
|
||||
BOOST_CHECK ( ba::is_partitioned ( v, less_than<int>(3))); // no elements
|
||||
BOOST_CHECK ( ba::is_partitioned ( v, less_than<int>(6))); // only the first element
|
||||
BOOST_CHECK ( ba::is_partitioned ( v, less_than<int>(10))); // in the middle somewhere
|
||||
BOOST_CHECK ( ba::is_partitioned ( v, less_than<int>(99))); // all elements satisfy
|
||||
BOOST_CHECK ( ba::is_partitioned ( v, less_than<int>(3))); // no elements
|
||||
BOOST_CHECK ( ba::is_partitioned ( v, less_than<int>(6))); // only the first element
|
||||
BOOST_CHECK ( ba::is_partitioned ( v, less_than<int>(10))); // in the middle somewhere
|
||||
BOOST_CHECK ( ba::is_partitioned ( v, less_than<int>(99))); // all elements satisfy
|
||||
|
||||
// With bidirectional iterators.
|
||||
// With bidirectional iterators.
|
||||
std::list<int> l;
|
||||
for ( int i = 5; i < 15; ++i )
|
||||
l.push_back ( i );
|
||||
BOOST_CHECK ( ba::is_partitioned ( l.begin (), l.end (), less_than<int>(3))); // no elements
|
||||
BOOST_CHECK ( ba::is_partitioned ( l.begin (), l.end (), less_than<int>(6))); // only the first element
|
||||
BOOST_CHECK ( ba::is_partitioned ( l.begin (), l.end (), less_than<int>(10))); // in the middle somewhere
|
||||
BOOST_CHECK ( ba::is_partitioned ( l.begin (), l.end (), less_than<int>(99))); // all elements satisfy
|
||||
BOOST_CHECK ( ba::is_partitioned ( l.begin (), l.end (), less_than<int>(3))); // no elements
|
||||
BOOST_CHECK ( ba::is_partitioned ( l.begin (), l.end (), less_than<int>(6))); // only the first element
|
||||
BOOST_CHECK ( ba::is_partitioned ( l.begin (), l.end (), less_than<int>(10))); // in the middle somewhere
|
||||
BOOST_CHECK ( ba::is_partitioned ( l.begin (), l.end (), less_than<int>(99))); // all elements satisfy
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,28 +36,28 @@ test_ordered(void)
|
||||
int nonConstantArray[] = { 1, 2, 2, 2, 5 };
|
||||
const int inOrderUntilTheEnd [] = { 0, 1, 2, 3, 4, 5, 6, 7, 6 };
|
||||
|
||||
// Begin/end checks
|
||||
BOOST_CHECK ( ba::is_sorted (b_e(strictlyIncreasingValues)));
|
||||
BOOST_CHECK ( !ba::is_sorted (b_e(randomValues)));
|
||||
BOOST_CHECK ( ba::is_sorted (b_e(strictlyIncreasingValues), std::less<int>()));
|
||||
BOOST_CHECK ( !ba::is_sorted (b_e(strictlyIncreasingValues), std::greater<int>()));
|
||||
// Begin/end checks
|
||||
BOOST_CHECK ( ba::is_sorted (b_e(strictlyIncreasingValues)));
|
||||
BOOST_CHECK ( !ba::is_sorted (b_e(randomValues)));
|
||||
BOOST_CHECK ( ba::is_sorted (b_e(strictlyIncreasingValues), std::less<int>()));
|
||||
BOOST_CHECK ( !ba::is_sorted (b_e(strictlyIncreasingValues), std::greater<int>()));
|
||||
|
||||
// Range checks
|
||||
BOOST_CHECK ( ba::is_sorted (a_range(strictlyIncreasingValues)));
|
||||
BOOST_CHECK ( !ba::is_sorted (a_range(randomValues)));
|
||||
BOOST_CHECK ( ba::is_sorted (a_range(strictlyIncreasingValues), std::less<int>()));
|
||||
BOOST_CHECK ( !ba::is_sorted (a_range(strictlyIncreasingValues), std::greater<int>()));
|
||||
// Range checks
|
||||
BOOST_CHECK ( ba::is_sorted (a_range(strictlyIncreasingValues)));
|
||||
BOOST_CHECK ( !ba::is_sorted (a_range(randomValues)));
|
||||
BOOST_CHECK ( ba::is_sorted (a_range(strictlyIncreasingValues), std::less<int>()));
|
||||
BOOST_CHECK ( !ba::is_sorted (a_range(strictlyIncreasingValues), std::greater<int>()));
|
||||
|
||||
BOOST_CHECK ( ba::is_sorted_until ( b_e(strictlyIncreasingValues)) == a_end(strictlyIncreasingValues));
|
||||
BOOST_CHECK ( ba::is_sorted_until ( b_e(strictlyIncreasingValues), std::less<int>()) == a_end(strictlyIncreasingValues));
|
||||
BOOST_CHECK ( ba::is_sorted_until ( a_range(strictlyIncreasingValues)) == boost::end(strictlyIncreasingValues));
|
||||
BOOST_CHECK ( ba::is_sorted_until ( a_range(strictlyIncreasingValues), std::less<int>()) == boost::end(strictlyIncreasingValues));
|
||||
|
||||
// Check for const and non-const arrays
|
||||
BOOST_CHECK ( ba::is_sorted_until ( b_e(constantValues), std::less<int>()) == a_end(constantValues));
|
||||
BOOST_CHECK ( ba::is_sorted_until ( a_range(constantValues), std::less<int>()) == boost::end(constantValues));
|
||||
BOOST_CHECK ( ba::is_sorted_until ( b_e(nonConstantArray), std::less<int>()) == a_end(nonConstantArray));
|
||||
BOOST_CHECK ( ba::is_sorted_until ( a_range(nonConstantArray), std::less<int>()) == boost::end(nonConstantArray));
|
||||
// Check for const and non-const arrays
|
||||
BOOST_CHECK ( ba::is_sorted_until ( b_e(constantValues), std::less<int>()) != a_end(constantValues));
|
||||
BOOST_CHECK ( ba::is_sorted_until ( a_range(constantValues), std::less<int>()) != boost::end(constantValues));
|
||||
BOOST_CHECK ( ba::is_sorted_until ( b_e(nonConstantArray), std::less<int>()) != a_end(nonConstantArray));
|
||||
BOOST_CHECK ( ba::is_sorted_until ( a_range(nonConstantArray), std::less<int>()) != boost::end(nonConstantArray));
|
||||
|
||||
BOOST_CHECK ( ba::is_sorted_until ( b_e(randomValues), std::less<int>()) == &randomValues[2] );
|
||||
BOOST_CHECK ( ba::is_sorted_until ( b_e(randomValues)) == &randomValues[2] );
|
||||
@ -149,6 +149,6 @@ test_increasing_decreasing(void)
|
||||
int test_main( int, char * [] )
|
||||
{
|
||||
test_ordered ();
|
||||
test_increasing_decreasing ();
|
||||
test_increasing_decreasing ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -22,18 +22,18 @@ namespace ba = boost::algorithm;
|
||||
|
||||
template <typename Container>
|
||||
typename Container::iterator offset_to_iter ( Container &v, int offset ) {
|
||||
typename Container::iterator retval;
|
||||
|
||||
if ( offset >= 0 ) {
|
||||
retval = v.begin ();
|
||||
std::advance ( retval, offset );
|
||||
}
|
||||
else {
|
||||
retval = v.end ();
|
||||
std::advance ( retval, offset + 1 );
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
typename Container::iterator retval;
|
||||
|
||||
if ( offset >= 0 ) {
|
||||
retval = v.begin ();
|
||||
std::advance ( retval, offset );
|
||||
}
|
||||
else {
|
||||
retval = v.end ();
|
||||
std::advance ( retval, offset + 1 );
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
template <typename Container, typename Predicate>
|
||||
void test_sequence ( Container &v, Predicate comp, int expected ) {
|
||||
@ -79,7 +79,7 @@ void test_sequence1 () {
|
||||
test_sequence ( v, less_than<int>(10), 5 );
|
||||
test_sequence ( v, less_than<int>(99), -1 ); // all elements satisfy
|
||||
|
||||
// With bidirectional iterators.
|
||||
// With bidirectional iterators.
|
||||
std::list<int> l;
|
||||
for ( int i = 5; i < 15; ++i )
|
||||
l.push_back ( i );
|
||||
|
0
test/search_test1.cpp
Normal file → Executable file
0
test/search_test1.cpp
Normal file → Executable file
0
test/search_test2.cpp
Normal file → Executable file
0
test/search_test2.cpp
Normal file → Executable file
0
test/search_test3.cpp
Normal file → Executable file
0
test/search_test3.cpp
Normal file → Executable 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;
|
||||
}
|
Reference in New Issue
Block a user