mirror of
https://github.com/boostorg/algorithm.git
synced 2025-06-25 12:01:39 +02:00
Compare commits
153 Commits
boost-1.53
...
boost-1.54
Author | SHA1 | Date | |
---|---|---|---|
088d942db3 | |||
1a70166889 | |||
a4b907197e | |||
b8c95b412c | |||
1529f909a6 | |||
63da6f5713 | |||
2381d0bdac | |||
40b5941652 | |||
00dfda98b2 | |||
52eef989da | |||
ef16153353 | |||
8132864884 | |||
5f45246c6c | |||
a451b260a3 | |||
578c37b7fa | |||
21e88adcda | |||
6d22c99f2e | |||
efd5d23bb9 | |||
f65d36aca7 | |||
4ca6b10441 | |||
771375973f | |||
d6d75c9a31 | |||
54d2649b8c | |||
922afd98c4 | |||
20c9bad06d | |||
06d0a61a01 | |||
5bb66c562b | |||
9e130e7b4e | |||
b7d4f04a8b | |||
cc55b8d6ae | |||
d739f7ff0c | |||
223e6e1826 | |||
0d750ae554 | |||
6afae475fe | |||
a7190c0044 | |||
fdb9522a1b | |||
4cd7e10628 | |||
8b5c0d9114 | |||
234656765a | |||
87f97645da | |||
ed9b65dc39 | |||
d0a05da4c1 | |||
4a4ae462fb | |||
5084a5d228 | |||
5492b15518 | |||
9b412cdf6f | |||
cabff10be7 | |||
1fd1894ed7 | |||
26edcb7b51 | |||
9e7e5087b8 | |||
a0ee93ff89 | |||
681c5827d3 | |||
93b0b886fd | |||
dcda91716a | |||
a42d6ebcd7 | |||
ea13506795 | |||
8d82e7538d | |||
fae48250b4 | |||
1aa1944636 | |||
35496195f2 | |||
163b8d0052 | |||
f0ad49c07f | |||
bca416c177 | |||
823e059a0e | |||
e3263d43e4 | |||
1af25699b7 | |||
49668cf66a | |||
a92ae91b23 | |||
028d9aedcd | |||
dfaea65083 | |||
eb8291e0aa | |||
f023127c99 | |||
43c01ff2bc | |||
8bfaa6dad3 | |||
6fbc7401d5 | |||
d518994247 | |||
ba417e875a | |||
e92d471817 | |||
34c49f856c | |||
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 |
@ -58,6 +58,7 @@ Thanks to all the people who have reviewed this library and made suggestions for
|
||||
|
||||
[section:Misc Other Algorithms]
|
||||
[include clamp-hpp.qbk]
|
||||
[include gather.qbk]
|
||||
[include hex.qbk]
|
||||
[endsect]
|
||||
|
||||
|
79
doc/gather.qbk
Normal file
79
doc/gather.qbk
Normal file
@ -0,0 +1,79 @@
|
||||
[/ File gather.qbk]
|
||||
|
||||
[section:gather gather]
|
||||
|
||||
[/license
|
||||
Copyright (c) 2013 Marshall Clow
|
||||
|
||||
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)
|
||||
]
|
||||
|
||||
The header file 'boost/algorithm/gather.hpp' contains two variants of a single algorithm, `gather`.
|
||||
|
||||
`gather()` takes a collection of elements defined by a pair of iterators and moves the ones satisfying a predicate to them to a position (called the pivot) within the sequence. The algorithm is stable. The result is a pair of iterators that contains the items that satisfy the predicate.
|
||||
|
||||
[heading Interface]
|
||||
|
||||
The function `gather` returns a `std::pair` of iterators that denote the elements that satisfy the predicate.
|
||||
|
||||
There are two versions; one takes two iterators, and the other takes a range.
|
||||
|
||||
``
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
template <typename BidirectionalIterator, typename Pred>
|
||||
std::pair<BidirectionalIterator,BidirectionalIterator>
|
||||
gather ( BidirectionalIterator first, BidirectionalIterator last, BidirectionalIterator pivot, Pred pred );
|
||||
|
||||
template <typename BidirectionalRange, typename Pred>
|
||||
std::pair<typename boost::range_iterator<const BidirectionalRange>::type, typename boost::range_iterator<const BidirectionalRange>::type>
|
||||
gather ( const BidirectionalRange &range, typename boost::range_iterator<const BidirectionalRange>::type pivot, Pred pred );
|
||||
|
||||
}}
|
||||
``
|
||||
|
||||
[heading Examples]
|
||||
|
||||
Given an sequence containing:
|
||||
``
|
||||
0 1 2 3 4 5 6 7 8 9
|
||||
``
|
||||
|
||||
a call to gather ( arr, arr + 10, arr + 4, IsEven ) will result in:
|
||||
|
||||
``
|
||||
1 3 0 2 4 6 8 5 7 9
|
||||
|---|-----|
|
||||
first | second
|
||||
pivot
|
||||
``
|
||||
where `first` and `second` are the fields of the pair that is returned by the call.
|
||||
|
||||
|
||||
[heading Iterator Requirements]
|
||||
|
||||
`gather` work on bidirectional iterators or better. This requirement comes from the usage of `stable_partition`, which requires bidirectional iterators. Some standard libraries (libstdc++ and libc++, for example) have implementations of `stable_partition` that work with forward iterators. If that is the case, then `gather` will work with forward iterators as well.
|
||||
|
||||
[heading Storage Requirements]
|
||||
|
||||
`gather` uses `stable_partition`, which will attempt to allocate temporary memory, but will work in-situ if there is none available.
|
||||
|
||||
[heading Complexity]
|
||||
|
||||
If there is sufficient memory available, the run time is linear: `O(N)`
|
||||
|
||||
If there is not any memory available, then the run time is `O(N log N)`.
|
||||
|
||||
[heading Exception Safety]
|
||||
|
||||
[heading Notes]
|
||||
|
||||
[endsect]
|
||||
|
||||
[/ File gather.qbk
|
||||
Copyright 2013 Marshall Clow
|
||||
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).
|
||||
]
|
||||
|
@ -63,7 +63,7 @@ OutputIterator copy_if ( const Range &r, OutputIterator result, Predicate p )
|
||||
/// \fn copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
|
||||
/// \brief Copies all the elements at the start of the input range that
|
||||
/// satisfy the predicate to the output range.
|
||||
/// \return The updated output iterator
|
||||
/// \return The updated input and output iterators
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
@ -71,25 +71,26 @@ OutputIterator copy_if ( const Range &r, OutputIterator result, Predicate p )
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename InputIterator, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_while ( InputIterator first, InputIterator last,
|
||||
OutputIterator result, Predicate p )
|
||||
std::pair<InputIterator, OutputIterator>
|
||||
copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
|
||||
{
|
||||
for ( ; first != last && p(*first); ++first )
|
||||
*result++ = *first;
|
||||
return result;
|
||||
return std::make_pair(first, result);
|
||||
}
|
||||
|
||||
/// \fn copy_while ( const Range &r, OutputIterator result, Predicate p )
|
||||
/// \brief Copies all the elements at the start of the input range that
|
||||
/// satisfy the predicate to the output range.
|
||||
/// \return The updated output iterator
|
||||
/// \return The updated input and output iterators
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param result An output iterator to write the results into
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_while ( const Range &r, OutputIterator result, Predicate p )
|
||||
std::pair<typename boost::range_iterator<const Range>::type, OutputIterator>
|
||||
copy_while ( const Range &r, OutputIterator result, Predicate p )
|
||||
{
|
||||
return boost::algorithm::copy_while (boost::begin (r), boost::end(r), result, p);
|
||||
}
|
||||
@ -106,11 +107,12 @@ OutputIterator copy_while ( const Range &r, OutputIterator result, Predicate p )
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename InputIterator, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
|
||||
std::pair<InputIterator, OutputIterator>
|
||||
copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
|
||||
{
|
||||
for ( ; first != last && !p(*first); ++first )
|
||||
*result++ = *first;
|
||||
return result;
|
||||
return std::make_pair(first, result);
|
||||
}
|
||||
|
||||
/// \fn copy_until ( const Range &r, OutputIterator result, Predicate p )
|
||||
@ -123,7 +125,8 @@ OutputIterator copy_until ( InputIterator first, InputIterator last, OutputItera
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_until ( const Range &r, OutputIterator result, Predicate p )
|
||||
std::pair<typename boost::range_iterator<const Range>::type, OutputIterator>
|
||||
copy_until ( const Range &r, OutputIterator result, Predicate p )
|
||||
{
|
||||
return boost::algorithm::copy_until (boost::begin (r), boost::end(r), result, p);
|
||||
}
|
||||
|
@ -25,10 +25,6 @@
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of is_permutation if it is available
|
||||
using std::is_permutation; // Section 25.2.12
|
||||
#else
|
||||
/// \cond DOXYGEN_HIDE
|
||||
namespace detail {
|
||||
template <typename Predicate, typename Iterator>
|
||||
@ -38,18 +34,82 @@ namespace detail {
|
||||
template <typename T1>
|
||||
bool operator () ( const T1 &t1 ) const { return p_ ( *it_, t1 ); }
|
||||
private:
|
||||
Predicate &p_;
|
||||
Predicate p_;
|
||||
Iterator it_;
|
||||
};
|
||||
|
||||
// Preconditions:
|
||||
// 1. The sequences are the same length
|
||||
// 2. Any common elements on the front have been removed (not necessary for correctness, just for performance)
|
||||
template< class ForwardIterator1, class ForwardIterator2, class BinaryPredicate >
|
||||
bool is_permutation_inner ( ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2,
|
||||
BinaryPredicate p ) {
|
||||
// for each unique value in the sequence [first1,last1), count how many times
|
||||
// it occurs, and make sure it occurs the same number of times in [first2, last2)
|
||||
for ( ForwardIterator1 iter = first1; iter != last1; ++iter ) {
|
||||
value_predicate<BinaryPredicate, ForwardIterator1> pred ( p, iter );
|
||||
|
||||
/* For each value we haven't seen yet... */
|
||||
if ( std::find_if ( first1, iter, pred ) == iter ) {
|
||||
std::size_t dest_count = std::count_if ( first2, last2, pred );
|
||||
if ( dest_count == 0 || dest_count != (std::size_t) std::count_if ( iter, last1, pred ))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template< class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
|
||||
bool is_permutation_tag ( ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2,
|
||||
BinaryPredicate p,
|
||||
std::forward_iterator_tag, std::forward_iterator_tag ) {
|
||||
|
||||
// Skip the common prefix (if any)
|
||||
while ( first1 != last1 && first2 != last2 && p ( *first1, *first2 )) {
|
||||
++first1;
|
||||
++first2;
|
||||
}
|
||||
if ( first1 != last1 && first2 != last2 )
|
||||
return boost::algorithm::detail::is_permutation_inner ( first1, last1, first2, last2,
|
||||
std::equal_to<typename std::iterator_traits<ForwardIterator1>::value_type> ());
|
||||
return first1 == last1 && first2 == last2;
|
||||
}
|
||||
|
||||
template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate>
|
||||
bool is_permutation_tag ( RandomAccessIterator1 first1, RandomAccessIterator1 last1,
|
||||
RandomAccessIterator2 first2, RandomAccessIterator2 last2,
|
||||
BinaryPredicate p,
|
||||
std::random_access_iterator_tag, std::random_access_iterator_tag ) {
|
||||
// Cheap check
|
||||
if ( std::distance ( first1, last1 ) != std::distance ( first2, last2 ))
|
||||
return false;
|
||||
// Skip the common prefix (if any)
|
||||
while ( first1 != last1 && first2 != last2 && p ( *first1, *first2 )) {
|
||||
++first1;
|
||||
++first2;
|
||||
}
|
||||
|
||||
if ( first1 != last1 && first2 != last2 )
|
||||
return is_permutation_inner (first1, last1, first2, last2, p);
|
||||
return first1 == last1 && first2 == last2;
|
||||
}
|
||||
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of is_permutation if it is available
|
||||
using std::is_permutation; // Section 25.2.12
|
||||
#else
|
||||
|
||||
/// \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
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param first1 The start of the input sequence
|
||||
/// \param last1 One past the end of the input sequence
|
||||
/// \param first2 The start of the second sequence
|
||||
/// \param p The predicate to compare elements with
|
||||
///
|
||||
@ -69,19 +129,7 @@ bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
// Create last2
|
||||
ForwardIterator2 last2 = first2;
|
||||
std::advance ( last2, std::distance (first1, last1));
|
||||
|
||||
// for each unique value in the sequence [first1,last1), count how many times
|
||||
// it occurs, and make sure it occurs the same number of times in [first2, last2)
|
||||
for ( ForwardIterator1 iter = first1; iter != last1; ++iter ) {
|
||||
detail::value_predicate<BinaryPredicate, ForwardIterator1> pred ( p, iter );
|
||||
|
||||
/* For each value we haven't seen yet... */
|
||||
if ( std::find_if ( first1, iter, pred ) == iter ) {
|
||||
std::size_t dest_count = std::count_if ( first2, last2, pred );
|
||||
if ( dest_count == 0 || dest_count != (std::size_t) std::count_if ( iter, last1, pred ))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return boost::algorithm::detail::is_permutation_inner ( first1, last1, first2, last2, p );
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -90,23 +138,84 @@ 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
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param first1 The start of the input sequence
|
||||
/// \param last2 One past the end of the input sequence
|
||||
/// \param first2 The start of the second sequence
|
||||
/// \note This function is part of the C++2011 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template< class ForwardIterator1, class ForwardIterator2 >
|
||||
bool is_permutation ( ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 first2 )
|
||||
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2 )
|
||||
{
|
||||
// How should I deal with the idea that ForwardIterator1::value_type
|
||||
// and ForwardIterator2::value_type could be different? Define my own comparison predicate?
|
||||
return boost::algorithm::is_permutation ( first, last, first2,
|
||||
std::equal_to<typename std::iterator_traits<ForwardIterator1>::value_type> ());
|
||||
// Skip the common prefix (if any)
|
||||
std::pair<ForwardIterator1, ForwardIterator2> eq = std::mismatch (first1, last1, first2 );
|
||||
first1 = eq.first;
|
||||
first2 = eq.second;
|
||||
if ( first1 != last1 ) {
|
||||
// Create last2
|
||||
ForwardIterator2 last2 = first2;
|
||||
std::advance ( last2, std::distance (first1, last1));
|
||||
return boost::algorithm::detail::is_permutation_inner ( first1, last1, first2, last2,
|
||||
std::equal_to<typename std::iterator_traits<ForwardIterator1>::value_type> ());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last,
|
||||
/// ForwardIterator2 first2, ForwardIterator2 last2 )
|
||||
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param first1 The start of the input sequence
|
||||
/// \param last2 One past the end of the input sequence
|
||||
/// \param first2 The start of the second sequence
|
||||
/// \param last1 One past the end of the second sequence
|
||||
/// \note This function is part of the C++2011 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template< class ForwardIterator1, class ForwardIterator2 >
|
||||
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2 )
|
||||
{
|
||||
// How should I deal with the idea that ForwardIterator1::value_type
|
||||
// and ForwardIterator2::value_type could be different? Define my own comparison predicate?
|
||||
return boost::algorithm::detail::is_permutation_tag (
|
||||
first1, last1, first2, last2,
|
||||
std::equal_to<typename std::iterator_traits<ForwardIterator1>::value_type> (),
|
||||
typename std::iterator_traits<ForwardIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<ForwardIterator2>::iterator_category ());
|
||||
}
|
||||
|
||||
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last,
|
||||
/// ForwardIterator2 first2, ForwardIterator2 last2,
|
||||
/// BinaryPredicate p )
|
||||
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param first1 The start of the input sequence
|
||||
/// \param last1 One past the end of the input sequence
|
||||
/// \param first2 The start of the second sequence
|
||||
/// \param last2 One past the end of the second sequence
|
||||
/// \param pred The predicate to compare elements with
|
||||
///
|
||||
/// \note This function is part of the C++2011 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template< class ForwardIterator1, class ForwardIterator2, class BinaryPredicate >
|
||||
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2,
|
||||
BinaryPredicate pred )
|
||||
{
|
||||
return boost::algorithm::detail::is_permutation_tag (
|
||||
first1, last1, first2, last2, pred,
|
||||
typename std::iterator_traits<ForwardIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<ForwardIterator2>::iterator_category ());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// \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
|
||||
///
|
||||
|
97
include/boost/algorithm/cxx14/equal.hpp
Normal file
97
include/boost/algorithm/cxx14/equal.hpp
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2008-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)
|
||||
*/
|
||||
|
||||
/// \file equal.hpp
|
||||
/// \brief Test ranges to if they are equal
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_EQUAL_HPP
|
||||
#define BOOST_ALGORITHM_EQUAL_HPP
|
||||
|
||||
#include <algorithm> // for std::equal
|
||||
#include <functional> // for std::equal_to
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T1, class T2>
|
||||
struct eq : public std::binary_function<T1, T2, bool> {
|
||||
bool operator () ( const T1& v1, const T2& v2 ) const { return v1 == v2 ;}
|
||||
};
|
||||
|
||||
template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate>
|
||||
bool equal ( RandomAccessIterator1 first1, RandomAccessIterator1 last1,
|
||||
RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred,
|
||||
std::random_access_iterator_tag, std::random_access_iterator_tag )
|
||||
{
|
||||
// Random-access iterators let is check the sizes in constant time
|
||||
if ( std::distance ( first1, last1 ) != std::distance ( first2, last2 ))
|
||||
return false;
|
||||
// If we know that the sequences are the same size, the original version is fine
|
||||
return std::equal ( first1, last1, first2, pred );
|
||||
}
|
||||
|
||||
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
|
||||
bool equal ( InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred,
|
||||
std::input_iterator_tag, std::input_iterator_tag )
|
||||
{
|
||||
for (; first1 != last1 && first2 != last2; ++first1, ++first2 )
|
||||
if ( !pred(*first1, *first2 ))
|
||||
return false;
|
||||
|
||||
return first1 == last1 && first2 == last2;
|
||||
}
|
||||
}
|
||||
|
||||
/// \fn equal ( InputIterator1 first1, InputIterator1 last1,
|
||||
/// InputIterator2 first2, InputIterator2 last2,
|
||||
/// BinaryPredicate pred )
|
||||
/// \return true if all elements in the two ranges are equal
|
||||
///
|
||||
/// \param first1 The start of the first range.
|
||||
/// \param last1 One past the end of the first range.
|
||||
/// \param first2 The start of the second range.
|
||||
/// \param last2 One past the end of the second range.
|
||||
/// \param pred A predicate for comparing the elements of the ranges
|
||||
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
|
||||
bool equal ( InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred )
|
||||
{
|
||||
return boost::algorithm::detail::equal (
|
||||
first1, last1, first2, last2, pred,
|
||||
typename std::iterator_traits<InputIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<InputIterator2>::iterator_category ());
|
||||
}
|
||||
|
||||
/// \fn equal ( InputIterator1 first1, InputIterator1 last1,
|
||||
/// InputIterator2 first2, InputIterator2 last2 )
|
||||
/// \return true if all elements in the two ranges are equal
|
||||
///
|
||||
/// \param first1 The start of the first range.
|
||||
/// \param last1 One past the end of the first range.
|
||||
/// \param first2 The start of the second range.
|
||||
/// \param last2 One past the end of the second range.
|
||||
template <class InputIterator1, class InputIterator2>
|
||||
bool equal ( InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, InputIterator2 last2 )
|
||||
{
|
||||
return boost::algorithm::detail::equal (
|
||||
first1, last1, first2, last2,
|
||||
boost::algorithm::detail::eq<
|
||||
typename std::iterator_traits<InputIterator1>::value_type,
|
||||
typename std::iterator_traits<InputIterator2>::value_type> (),
|
||||
typename std::iterator_traits<InputIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<InputIterator2>::iterator_category ());
|
||||
}
|
||||
|
||||
// There are already range-based versions of these.
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_EQUAL_HPP
|
130
include/boost/algorithm/cxx14/is_permutation.hpp
Normal file
130
include/boost/algorithm/cxx14/is_permutation.hpp
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2013
|
||||
|
||||
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)
|
||||
*/
|
||||
|
||||
/// \file equal.hpp
|
||||
/// \brief Determines if one
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
||||
#define BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional> // for std::equal_to
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_perm_eq : public std::binary_function<T1, T2, bool> {
|
||||
bool operator () ( const T1& v1, const T2& v2 ) const { return v1 == v2 ;}
|
||||
};
|
||||
|
||||
|
||||
template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate>
|
||||
bool is_permutation ( RandomAccessIterator1 first1, RandomAccessIterator1 last1,
|
||||
RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred,
|
||||
std::random_access_iterator_tag, std::random_access_iterator_tag )
|
||||
{
|
||||
// Random-access iterators let is check the sizes in constant time
|
||||
if ( std::distance ( first1, last1 ) != std::distance ( first2, last2 ))
|
||||
return false;
|
||||
// If we know that the sequences are the same size, the original version is fine
|
||||
return std::is_permutation ( first1, last1, first2, pred );
|
||||
}
|
||||
|
||||
|
||||
template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
|
||||
bool is_permutation (
|
||||
ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2,
|
||||
BinaryPredicate pred,
|
||||
std::forward_iterator_tag, std::forward_iterator_tag )
|
||||
{
|
||||
|
||||
// Look for common prefix
|
||||
for (; first1 != last1 && first2 != last2; ++first1, ++first2)
|
||||
if (!pred(*first1, *first2))
|
||||
goto not_done;
|
||||
// We've reached the end of one of the sequences without a mismatch.
|
||||
return first1 == last1 && first2 == last2;
|
||||
not_done:
|
||||
|
||||
// Check and make sure that we have the same # of elements left
|
||||
typedef typename std::iterator_traits<ForwardIterator1>::difference_type diff1_t;
|
||||
diff1_t len1 = _VSTD::distance(first1, last1);
|
||||
typedef typename std::iterator_traits<ForwardIterator2>::difference_type diff2_t;
|
||||
diff2_t len2 = _VSTD::distance(first2, last2);
|
||||
if (len1 != len2)
|
||||
return false;
|
||||
|
||||
// For each element in [f1, l1) see if there are the
|
||||
// same number of equal elements in [f2, l2)
|
||||
for ( ForwardIterator1 i = first1; i != last1; ++i )
|
||||
{
|
||||
// Have we already counted this value?
|
||||
ForwardIterator1 j;
|
||||
for ( j = first1; j != i; ++j )
|
||||
if (pred(*j, *i))
|
||||
break;
|
||||
if ( j == i ) // didn't find it...
|
||||
{
|
||||
// Count number of *i in [f2, l2)
|
||||
diff1_t c2 = 0;
|
||||
for ( ForwardIterator2 iter2 = first2; iter2 != last2; ++iter2 )
|
||||
if (pred(*i, *iter2))
|
||||
++c2;
|
||||
if (c2 == 0)
|
||||
return false;
|
||||
|
||||
// Count number of *i in [i, l1)
|
||||
diff1_t c1 = 0;
|
||||
for (_ForwardIterator1 iter1 = i; iter1 != last1; ++iter1 )
|
||||
if (pred(*i, *iter1))
|
||||
++c1;
|
||||
if (c1 != c2)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
|
||||
bool is_permutation (
|
||||
ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2,
|
||||
BinaryPredicate pred )
|
||||
{
|
||||
return boost::algorithm::detail::is_permutation (
|
||||
first1, last1, first2, last2, pred,
|
||||
typename std::iterator_traits<ForwardIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<ForwardIterator2>::iterator_category ());
|
||||
}
|
||||
|
||||
template<class ForwardIterator1, class ForwardIterator2>
|
||||
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2 )
|
||||
{
|
||||
typedef typename iterator_traits<_ForwardIterator1>::value_type value1_t;
|
||||
typedef typename iterator_traits<_ForwardIterator2>::value_type value2_t;
|
||||
return boost::algorithm::detail::is_permutation (
|
||||
first1, last1, first2, last2,
|
||||
boost::algorithm::detail::is_perm_eq<
|
||||
typename std::iterator_traits<InputIterator1>::value_type,
|
||||
typename std::iterator_traits<InputIterator2>::value_type> (),
|
||||
typename std::iterator_traits<ForwardIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<ForwardIterator2>::iterator_category ());
|
||||
}
|
||||
|
||||
// There are already range-based versions of these.
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
66
include/boost/algorithm/cxx14/mismatch.hpp
Normal file
66
include/boost/algorithm/cxx14/mismatch.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2008-2012.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE10.txt or copy at http://www.boost.org/LICENSE10.txt)
|
||||
*/
|
||||
|
||||
/// \file mismatch.hpp
|
||||
/// \brief Find the first mismatched element in a sequence
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_MISMATCH_HPP
|
||||
#define BOOST_ALGORITHM_MISMATCH_HPP
|
||||
|
||||
#include <algorithm> // for std::mismatch
|
||||
#include <utility> // for std::pair
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
|
||||
|
||||
/// \fn mismatch ( InputIterator1 first1, InputIterator1 last1,
|
||||
/// InputIterator2 first2, InputIterator2 last2,
|
||||
/// BinaryPredicate pred )
|
||||
/// \return a pair of iterators pointing to the first elements in the sequence that do not match
|
||||
///
|
||||
/// \param first1 The start of the first range.
|
||||
/// \param last1 One past the end of the first range.
|
||||
/// \param first2 The start of the second range.
|
||||
/// \param last2 One past the end of the second range.
|
||||
/// \param pred A predicate for comparing the elements of the ranges
|
||||
std::pair<InputIterator1, InputIterator2> mismatch (
|
||||
InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, InputIterator2 last2,
|
||||
BinaryPredicate pred )
|
||||
{
|
||||
for (; first1 != last1 && first2 != last2; ++first1, ++first2)
|
||||
if ( !pred ( *first1, *first2 ))
|
||||
break;
|
||||
return std::pair<InputIterator1, InputIterator2>(first1, first2);
|
||||
}
|
||||
|
||||
/// \fn mismatch ( InputIterator1 first1, InputIterator1 last1,
|
||||
/// InputIterator2 first2, InputIterator2 last2 )
|
||||
/// \return a pair of iterators pointing to the first elements in the sequence that do not match
|
||||
///
|
||||
/// \param first1 The start of the first range.
|
||||
/// \param last1 One past the end of the first range.
|
||||
/// \param first2 The start of the second range.
|
||||
/// \param last2 One past the end of the second range.
|
||||
template <class InputIterator1, class InputIterator2>
|
||||
std::pair<InputIterator1, InputIterator2> mismatch (
|
||||
InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, InputIterator2 last2 )
|
||||
{
|
||||
for (; first1 != last1 && first2 != last2; ++first1, ++first2)
|
||||
if ( *first1 != *first2 )
|
||||
break;
|
||||
return std::pair<InputIterator1, InputIterator2>(first1, first2);
|
||||
}
|
||||
|
||||
// There are already range-based versions of these.
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_MISMATCH_HPP
|
123
include/boost/algorithm/gather.hpp
Normal file
123
include/boost/algorithm/gather.hpp
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
Copyright 2008 Adobe Systems Incorporated
|
||||
|
||||
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)
|
||||
|
||||
Revision history:
|
||||
January 2008 mtc Version for Adobe Source Library
|
||||
January 2013 mtc Version for Boost.Algorithm
|
||||
|
||||
*/
|
||||
|
||||
/**************************************************************************************************/
|
||||
|
||||
/*!
|
||||
\author Marshall Clow
|
||||
\date January 2008
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ALGORITHM_GATHER_HPP
|
||||
#define BOOST_ALGORITHM_GATHER_HPP
|
||||
|
||||
#include <algorithm> // for std::stable_partition
|
||||
#include <functional>
|
||||
|
||||
#include <boost/bind.hpp> // for boost::bind
|
||||
#include <boost/range/begin.hpp> // for boost::begin(range)
|
||||
#include <boost/range/end.hpp> // for boost::end(range)
|
||||
|
||||
|
||||
/**************************************************************************************************/
|
||||
/*!
|
||||
\defgroup gather gather
|
||||
\ingroup mutating_algorithm
|
||||
|
||||
\c gather() takes a collection of elements defined by a pair of iterators and moves
|
||||
the ones satisfying a predicate to them to a position (called the pivot) within
|
||||
the sequence. The algorithm is stable. The result is a pair of iterators that
|
||||
contains the items that satisfy the predicate.
|
||||
|
||||
Given an sequence containing:
|
||||
<pre>
|
||||
0 1 2 3 4 5 6 7 8 9
|
||||
</pre>
|
||||
|
||||
a call to gather ( arr, arr + 10, arr + 4, IsEven ()) will result in:
|
||||
|
||||
<pre>
|
||||
1 3 0 2 4 6 8 5 7 9
|
||||
|---|-----|
|
||||
first | second
|
||||
pivot
|
||||
</pre>
|
||||
|
||||
|
||||
The problem is broken down into two basic steps, namely, moving the items before the pivot
|
||||
and then moving the items from the pivot to the end. These "moves" are done with calls to
|
||||
stable_partition.
|
||||
|
||||
\par Storage Requirements:
|
||||
|
||||
The algorithm uses stable_partition, which will attempt to allocate temporary memory,
|
||||
but will work in-situ if there is none available.
|
||||
|
||||
\par Time Complexity:
|
||||
|
||||
If there is sufficient memory available, the run time is linear in <code>N</code>.
|
||||
If there is not any memory available, then the run time is <code>O(N log N)</code>.
|
||||
*/
|
||||
|
||||
/**************************************************************************************************/
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/**************************************************************************************************/
|
||||
|
||||
/*!
|
||||
\ingroup gather
|
||||
\brief iterator-based gather implementation
|
||||
*/
|
||||
|
||||
template <
|
||||
typename BidirectionalIterator, // Iter models BidirectionalIterator
|
||||
typename Pred> // Pred models UnaryPredicate
|
||||
std::pair<BidirectionalIterator, BidirectionalIterator> gather
|
||||
( BidirectionalIterator first, BidirectionalIterator last, BidirectionalIterator pivot, Pred pred )
|
||||
{
|
||||
// The first call partitions everything up to (but not including) the pivot element,
|
||||
// while the second call partitions the rest of the sequence.
|
||||
return std::make_pair (
|
||||
std::stable_partition ( first, pivot, !boost::bind<bool> ( pred, _1 )),
|
||||
std::stable_partition ( pivot, last, boost::bind<bool> ( pred, _1 )));
|
||||
}
|
||||
|
||||
/**************************************************************************************************/
|
||||
|
||||
/*!
|
||||
\ingroup gather
|
||||
\brief range-based gather implementation
|
||||
*/
|
||||
|
||||
template <
|
||||
typename BidirectionalRange, //
|
||||
typename Pred> // Pred models UnaryPredicate
|
||||
std::pair<
|
||||
typename boost::range_iterator<const BidirectionalRange>::type,
|
||||
typename boost::range_iterator<const BidirectionalRange>::type>
|
||||
gather (
|
||||
const BidirectionalRange &range,
|
||||
typename boost::range_iterator<const BidirectionalRange>::type pivot,
|
||||
Pred pred )
|
||||
{
|
||||
return boost::algorithm::gather ( boost::begin ( range ), boost::end ( range ), pivot, pred );
|
||||
}
|
||||
|
||||
/**************************************************************************************************/
|
||||
|
||||
}} // namespace
|
||||
|
||||
/**************************************************************************************************/
|
||||
|
||||
#endif
|
||||
|
@ -10,12 +10,6 @@
|
||||
/*
|
||||
General problem - turn a sequence of integral types into a sequence of hexadecimal characters.
|
||||
- and back.
|
||||
|
||||
TO DO:
|
||||
1. these should really only work on integral types. (see the >> and << operations)
|
||||
-- this is done, I think.
|
||||
2. The 'value_type_or_char' struct is really a hack.
|
||||
-- but it's a better hack now that it works with back_insert_iterators
|
||||
*/
|
||||
|
||||
/// \file hex.hpp
|
||||
@ -42,11 +36,11 @@ namespace boost { namespace algorithm {
|
||||
/*!
|
||||
\struct hex_decode_error
|
||||
\brief Base exception class for all hex decoding errors
|
||||
|
||||
*/ /*!
|
||||
\struct non_hex_input
|
||||
\brief Thrown when a non-hex value (0-9, A-F) encountered when decoding.
|
||||
Contains the offending character
|
||||
|
||||
*/ /*!
|
||||
\struct not_enough_input
|
||||
\brief Thrown when the input sequence unexpectedly ends
|
||||
|
||||
@ -69,18 +63,16 @@ 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
|
||||
template <typename T>
|
||||
unsigned char hex_char_to_int ( T val ) {
|
||||
char c = static_cast<char> ( val );
|
||||
unsigned retval = 0;
|
||||
if ( c >= '0' && c <= '9' ) retval = c - '0';
|
||||
else if ( c >= 'A' && c <= 'F' ) retval = c - 'A' + 10;
|
||||
else if ( c >= 'a' && c <= 'f' ) retval = c - 'a' + 10;
|
||||
else BOOST_THROW_EXCEPTION (non_hex_input() << bad_char (c));
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
// My own iterator_traits class.
|
||||
// It is here so that I can "reach inside" some kinds of output iterators
|
||||
@ -134,7 +126,7 @@ namespace detail {
|
||||
for ( std::size_t i = 0; i < 2 * sizeof ( T ); ++i, ++first ) {
|
||||
if ( pred ( first, last ))
|
||||
BOOST_THROW_EXCEPTION (not_enough_input ());
|
||||
res = ( 16 * res ) + hex_char_to_int (static_cast<char> (*first));
|
||||
res = ( 16 * res ) + hex_char_to_int (*first);
|
||||
}
|
||||
|
||||
*out = res;
|
||||
|
@ -134,8 +134,10 @@ namespace boost {
|
||||
{
|
||||
if(m_Match.begin() == m_Match.end())
|
||||
m_Match=this->do_find(m_Match.end(),m_End);
|
||||
else
|
||||
m_Match=this->do_find(m_Match.begin()+1,m_End);
|
||||
else {
|
||||
input_iterator_type last = m_Match.begin();
|
||||
m_Match=this->do_find(++last,m_End);
|
||||
}
|
||||
}
|
||||
|
||||
// comparison
|
||||
|
@ -9,11 +9,16 @@
|
||||
|
||||
import testing ;
|
||||
|
||||
alias unit_test_framework
|
||||
: # sources
|
||||
/boost//unit_test_framework
|
||||
;
|
||||
|
||||
{
|
||||
test-suite algorithm/minmax:
|
||||
: [ run minmax_element_test.cpp
|
||||
: [ run minmax_element_test.cpp unit_test_framework
|
||||
: : : : minmax_element ]
|
||||
[ run minmax_test.cpp
|
||||
[ run minmax_test.cpp unit_test_framework
|
||||
: : : : minmax ]
|
||||
;
|
||||
}
|
||||
|
@ -15,9 +15,11 @@
|
||||
|
||||
#include <boost/config.hpp> /* prevents some nasty warns in MSVC */
|
||||
#include <boost/algorithm/minmax_element.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
class custom {
|
||||
int m_x;
|
||||
friend bool operator<(custom const& x, custom const& y);
|
||||
@ -225,17 +227,14 @@ void test(int n BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Value))
|
||||
test_range(first, last, n);
|
||||
}
|
||||
|
||||
int test_main( int argc, char* argv[] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
#ifndef BOOST_NO_STDC_NAMESPACE
|
||||
using std::atoi;
|
||||
#endif
|
||||
|
||||
int n = 100;
|
||||
if (argc > 1) n = atoi(argv[1]);
|
||||
|
||||
test<int>(n);
|
||||
test<custom>(n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -8,7 +8,9 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/minmax.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
class custom {
|
||||
int m_x;
|
||||
@ -76,10 +78,8 @@ void test(BOOST_EXPLICIT_TEMPLATE_TYPE(Value))
|
||||
BOOST_CHECK_EQUAL( counter, 1);
|
||||
}
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test<int>(); // ("builtin");
|
||||
test<custom>(); // ("custom ");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,58 +9,63 @@
|
||||
|
||||
import testing ;
|
||||
|
||||
alias unit_test_framework
|
||||
: # sources
|
||||
/boost//unit_test_framework
|
||||
;
|
||||
|
||||
test-suite algorithm/string
|
||||
: [ run
|
||||
trim_test.cpp
|
||||
trim_test.cpp unit_test_framework
|
||||
: :
|
||||
:
|
||||
: trim
|
||||
]
|
||||
[ run
|
||||
conv_test.cpp
|
||||
conv_test.cpp unit_test_framework
|
||||
: :
|
||||
:
|
||||
: conv
|
||||
]
|
||||
[ run
|
||||
predicate_test.cpp
|
||||
predicate_test.cpp unit_test_framework
|
||||
: :
|
||||
:
|
||||
: predicate
|
||||
]
|
||||
[ run
|
||||
find_test.cpp
|
||||
find_test.cpp unit_test_framework
|
||||
: :
|
||||
:
|
||||
: find
|
||||
]
|
||||
[ run
|
||||
split_test.cpp
|
||||
split_test.cpp unit_test_framework
|
||||
: :
|
||||
:
|
||||
: split
|
||||
]
|
||||
[ run
|
||||
join_test.cpp
|
||||
join_test.cpp unit_test_framework
|
||||
: :
|
||||
:
|
||||
: join
|
||||
]
|
||||
[ run
|
||||
replace_test.cpp
|
||||
replace_test.cpp unit_test_framework
|
||||
: :
|
||||
:
|
||||
: replace
|
||||
]
|
||||
[ run
|
||||
regex_test.cpp
|
||||
regex_test.cpp unit_test_framework
|
||||
../../../regex/build//boost_regex
|
||||
: :
|
||||
:
|
||||
: regex
|
||||
]
|
||||
[ run
|
||||
find_format_test.cpp
|
||||
find_format_test.cpp unit_test_framework
|
||||
: :
|
||||
:
|
||||
: find_format
|
||||
|
@ -10,7 +10,8 @@
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
// Include unit test framework
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
@ -87,9 +88,7 @@ void conv_test()
|
||||
}
|
||||
|
||||
// test main
|
||||
int test_main( int, char*[] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
conv_test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,7 +12,8 @@
|
||||
#include <boost/algorithm/string/formatter.hpp>
|
||||
|
||||
// Include unit test framework
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
@ -154,10 +155,8 @@ void find_format_all_test()
|
||||
BOOST_CHECK_EQUAL(output, source);
|
||||
}
|
||||
|
||||
int test_main( int, char*[] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
find_format_test();
|
||||
find_format_all_test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,7 +12,8 @@
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
|
||||
// Include unit test framework
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -45,7 +46,7 @@ void find_test()
|
||||
|
||||
|
||||
// find_first
|
||||
BOOST_CHECKPOINT( "find_first" );
|
||||
BOOST_TEST_CHECKPOINT( "find_first" );
|
||||
|
||||
nc_result=find_first( str1, string("abc") );
|
||||
BOOST_CHECK(
|
||||
@ -66,7 +67,7 @@ void find_test()
|
||||
BOOST_CHECK(( (ch_result.begin() - pch1 ) == 3) && ( (ch_result.end() - pch1 ) == 6 ) );
|
||||
|
||||
// find_last
|
||||
BOOST_CHECKPOINT( "find_last" );
|
||||
BOOST_TEST_CHECKPOINT( "find_last" );
|
||||
|
||||
nc_result=find_last( str1, string("abc") );
|
||||
BOOST_CHECK(
|
||||
@ -87,7 +88,7 @@ void find_test()
|
||||
BOOST_CHECK(( (ch_result.begin() - pch1 ) == 15) && ( (ch_result.end() - pch1 ) == 18 ) );
|
||||
|
||||
// find_nth
|
||||
BOOST_CHECKPOINT( "find_nth" );
|
||||
BOOST_TEST_CHECKPOINT( "find_nth" );
|
||||
|
||||
nc_result=find_nth( str1, string("abc"), 1 );
|
||||
BOOST_CHECK(
|
||||
@ -125,7 +126,7 @@ void find_test()
|
||||
BOOST_CHECK(( (ch_result.begin() - pch1 ) == 9) && ( (ch_result.end() - pch1 ) == 12 ) );
|
||||
|
||||
// find_head
|
||||
BOOST_CHECKPOINT( "find_head" );
|
||||
BOOST_TEST_CHECKPOINT( "find_head" );
|
||||
|
||||
nc_result=find_head( str1, 6 );
|
||||
BOOST_CHECK(
|
||||
@ -146,7 +147,7 @@ void find_test()
|
||||
BOOST_CHECK( ( (ch_result.begin() - pch1 ) == 0 ) && ( (ch_result.end() - pch1 ) == 6 ) );
|
||||
|
||||
// find_tail
|
||||
BOOST_CHECKPOINT( "find_tail" );
|
||||
BOOST_TEST_CHECKPOINT( "find_tail" );
|
||||
|
||||
nc_result=find_tail( str1, 6 );
|
||||
BOOST_CHECK(
|
||||
@ -168,7 +169,7 @@ void find_test()
|
||||
BOOST_CHECK( ( (ch_result.begin() - pch1 ) == 15 ) && ( (ch_result.end() - pch1 ) == 21 ) );
|
||||
|
||||
// find_token
|
||||
BOOST_CHECKPOINT( "find_token" );
|
||||
BOOST_TEST_CHECKPOINT( "find_token" );
|
||||
|
||||
nc_result=find_token( str1, is_any_of("abc"), token_compress_on );
|
||||
BOOST_CHECK(
|
||||
@ -194,7 +195,7 @@ void find_test()
|
||||
BOOST_CHECK( ( (ch_result.begin() - pch1 ) == 3 ) && ( (ch_result.end() - pch1 ) == 4 ) );
|
||||
|
||||
// generic find
|
||||
BOOST_CHECKPOINT( "generic find" );
|
||||
BOOST_TEST_CHECKPOINT( "generic find" );
|
||||
|
||||
nc_result=find(str1, first_finder(string("abc")));
|
||||
BOOST_CHECK(
|
||||
@ -207,7 +208,7 @@ void find_test()
|
||||
( (cv_result.end()-str1.begin()) == 6) );
|
||||
|
||||
// multi-type comparison test
|
||||
BOOST_CHECKPOINT( "multi-type" );
|
||||
BOOST_TEST_CHECKPOINT( "multi-type" );
|
||||
|
||||
nc_vresult=find_first( vec1, string("abc") );
|
||||
BOOST_CHECK(
|
||||
@ -220,7 +221,7 @@ void find_test()
|
||||
( (cv_result.end()-str1.begin()) == 6) );
|
||||
|
||||
// overflow test
|
||||
BOOST_CHECKPOINT( "overflow" );
|
||||
BOOST_TEST_CHECKPOINT( "overflow" );
|
||||
|
||||
nc_result=find_first( str2, string("abcd") );
|
||||
BOOST_CHECK( nc_result.begin()==nc_result.end() );
|
||||
@ -233,7 +234,7 @@ void find_test()
|
||||
BOOST_CHECK( string( cv_result.begin(), cv_result.end() )== string("abc") );
|
||||
|
||||
// Empty string test
|
||||
BOOST_CHECKPOINT( "empty" );
|
||||
BOOST_TEST_CHECKPOINT( "empty" );
|
||||
|
||||
nc_result=find_first( str3, string("abcd") );
|
||||
BOOST_CHECK( nc_result.begin()==nc_result.end() );
|
||||
@ -251,7 +252,7 @@ void find_test()
|
||||
BOOST_CHECK( osstr.str()=="abc" );
|
||||
|
||||
// Empty string test
|
||||
BOOST_CHECKPOINT( "overlapping" );
|
||||
BOOST_TEST_CHECKPOINT( "overlapping" );
|
||||
|
||||
std::string overlap_target("aaaa");
|
||||
std::vector<boost::iterator_range<std::string::iterator> > overlap_results;
|
||||
@ -266,9 +267,7 @@ void find_test()
|
||||
}
|
||||
|
||||
// test main
|
||||
int test_main( int, char*[] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
find_test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -13,7 +13,8 @@
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
// Include unit test framework
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -70,10 +71,8 @@ void join_test()
|
||||
BOOST_CHECK( equals(join_if(tokens3, "-", is_not_empty), "") );
|
||||
}
|
||||
|
||||
// test main
|
||||
int test_main( int, char*[] )
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
join_test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,7 +11,8 @@
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
|
||||
// Include unit test framework
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -152,11 +153,8 @@ void classification_test()
|
||||
|
||||
#undef TEST_CLASS
|
||||
|
||||
// test main
|
||||
int test_main( int, char*[] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
predicate_test();
|
||||
classification_test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -15,7 +15,8 @@
|
||||
|
||||
|
||||
// Include unit test framework
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -149,11 +150,9 @@ static void replace_test()
|
||||
BOOST_CHECK( str1==string("123AxXxCa23ca456c321") );
|
||||
}
|
||||
|
||||
int test_main( int, char*[] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
find_test();
|
||||
join_test();
|
||||
replace_test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -16,7 +16,8 @@
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
|
||||
// Include unit test framework
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -56,14 +57,14 @@ void sequence_traits_test()
|
||||
#define C_ ,
|
||||
#define TEST_ALGO( Algo, Input, Params, Output ) \
|
||||
{\
|
||||
BOOST_CHECKPOINT( #Algo " - Copy" );\
|
||||
BOOST_TEST_CHECKPOINT( #Algo " - Copy" );\
|
||||
\
|
||||
string str1(Input);\
|
||||
\
|
||||
/* Copy test */ \
|
||||
BOOST_CHECK( Algo##_copy( str1, Params )==Output );\
|
||||
\
|
||||
BOOST_CHECKPOINT( #Algo " - Iterator" );\
|
||||
BOOST_TEST_CHECKPOINT( #Algo " - Iterator" );\
|
||||
/* Iterator test */\
|
||||
string strout;\
|
||||
Algo##_copy( back_inserter(strout), str1, Params );\
|
||||
@ -73,15 +74,15 @@ void sequence_traits_test()
|
||||
vector<char> vec1( str1.begin(), str1.end() );\
|
||||
list<char> list1( str1.begin(), str1.end() );\
|
||||
\
|
||||
BOOST_CHECKPOINT( #Algo " - Inplace(string)" );\
|
||||
BOOST_TEST_CHECKPOINT( #Algo " - Inplace(string)" );\
|
||||
Algo( str1, Params ); \
|
||||
BOOST_CHECK( equals( str1, Output ) ); \
|
||||
\
|
||||
BOOST_CHECKPOINT( #Algo " - Inplace(vector)" );\
|
||||
BOOST_TEST_CHECKPOINT( #Algo " - Inplace(vector)" );\
|
||||
Algo( vec1, Params ); \
|
||||
BOOST_CHECK( equals( vec1, Output ) );\
|
||||
\
|
||||
BOOST_CHECKPOINT( #Algo " - Inplace(list)" );\
|
||||
BOOST_TEST_CHECKPOINT( #Algo " - Inplace(list)" );\
|
||||
Algo( list1, Params ); \
|
||||
BOOST_CHECK( equals( list1, Output ) );\
|
||||
}
|
||||
@ -206,7 +207,7 @@ void replace_range_test()
|
||||
{
|
||||
// replace_range
|
||||
{
|
||||
BOOST_CHECKPOINT( "replace_range" );
|
||||
BOOST_TEST_CHECKPOINT( "replace_range" );
|
||||
|
||||
string str1("1abc3abc2");
|
||||
BOOST_CHECK(
|
||||
@ -231,7 +232,7 @@ void replace_range_test()
|
||||
}
|
||||
// erase_range
|
||||
{
|
||||
BOOST_CHECKPOINT( "erase_range" );
|
||||
BOOST_TEST_CHECKPOINT( "erase_range" );
|
||||
|
||||
string str1("1abc3abc2");
|
||||
BOOST_CHECK(
|
||||
@ -305,8 +306,7 @@ void dissect_format_test()
|
||||
|
||||
}
|
||||
|
||||
// test main
|
||||
int test_main( int, char*[] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
sequence_traits_test();
|
||||
replace_first_test();
|
||||
@ -318,6 +318,4 @@ int test_main( int, char*[] )
|
||||
replace_range_test();
|
||||
collection_comp_test();
|
||||
dissect_format_test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -13,10 +13,12 @@
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
// Include unit test framework
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/test/test_tools.hpp>
|
||||
@ -44,7 +46,7 @@ void iterator_test()
|
||||
const char* pch1="xx-abc--xx-abb";
|
||||
vector<string> tokens;
|
||||
vector< vector<int> > vtokens;
|
||||
|
||||
|
||||
// find_all tests
|
||||
find_all(
|
||||
tokens,
|
||||
@ -179,12 +181,13 @@ void iterator_test()
|
||||
BOOST_CHECK(siter==split_iterator<string::iterator>(siter));
|
||||
BOOST_CHECK(siter==split_iterator<string::iterator>());
|
||||
|
||||
// Make sure we work with forward iterators
|
||||
// See bug #7989
|
||||
list<char> l1;
|
||||
find_iterator<list<char>::iterator> liter=make_find_iterator(l1, first_finder("xx"));
|
||||
}
|
||||
|
||||
// test main
|
||||
int test_main( int, char*[] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
iterator_test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,7 +11,8 @@
|
||||
#include <boost/algorithm/string/trim_all.hpp>
|
||||
|
||||
// Include unit test framework
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
@ -193,12 +194,9 @@ void trim_fill_test()
|
||||
BOOST_CHECK( trim_fill_copy_if( string("<>abc<>def<>"), "-", is_any_of( "<<>>" ) )=="abc-def" );
|
||||
}
|
||||
|
||||
// test main
|
||||
int test_main( int, char*[] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
trim_test();
|
||||
trim_all_test();
|
||||
trim_fill_test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,44 +9,59 @@
|
||||
|
||||
import testing ;
|
||||
|
||||
alias unit_test_framework
|
||||
: # sources
|
||||
/boost//unit_test_framework
|
||||
;
|
||||
|
||||
|
||||
{
|
||||
test-suite algorithm:
|
||||
# Search tests
|
||||
: [ run empty_search_test.cpp : : : : empty_search_test ]
|
||||
[ 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 : : : : ]
|
||||
: [ run empty_search_test.cpp unit_test_framework : : : : empty_search_test ]
|
||||
[ run search_test1.cpp unit_test_framework : : : : search_test1 ]
|
||||
[ run search_test2.cpp unit_test_framework : : : : search_test2 ]
|
||||
[ run search_test3.cpp unit_test_framework : : : : search_test3 ]
|
||||
[ run search_test4.cpp unit_test_framework : : : : search_test4 ]
|
||||
[ compile-fail search_fail1.cpp : : : : ]
|
||||
[ compile-fail search_fail2.cpp : : : : ]
|
||||
[ compile-fail search_fail3.cpp : : : : ]
|
||||
|
||||
# Clamp tests
|
||||
[ run clamp_test.cpp : : : : clamp_test ]
|
||||
[ run clamp_test.cpp unit_test_framework : : : : clamp_test ]
|
||||
|
||||
# Cxx11 tests
|
||||
[ run all_of_test.cpp : : : : all_of_test ]
|
||||
[ run any_of_test.cpp : : : : any_of_test ]
|
||||
[ run none_of_test.cpp : : : : none_of_test ]
|
||||
[ run one_of_test.cpp : : : : one_of_test ]
|
||||
[ run all_of_test.cpp unit_test_framework : : : : all_of_test ]
|
||||
[ run any_of_test.cpp unit_test_framework : : : : any_of_test ]
|
||||
[ run none_of_test.cpp unit_test_framework : : : : none_of_test ]
|
||||
[ run one_of_test.cpp unit_test_framework : : : : one_of_test ]
|
||||
|
||||
[ 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 ]
|
||||
[ run ordered_test.cpp unit_test_framework : : : : ordered_test ]
|
||||
[ run find_if_not_test1.cpp unit_test_framework : : : : find_if_not_test1 ]
|
||||
[ run copy_if_test1.cpp unit_test_framework : : : : copy_if_test1 ]
|
||||
[ run copy_n_test1.cpp unit_test_framework : : : : copy_n_test1 ]
|
||||
[ run iota_test1.cpp unit_test_framework : : : : iota_test1 ]
|
||||
|
||||
[ run is_permutation_test1.cpp : : : : is_permutation_test1 ]
|
||||
[ run partition_point_test1.cpp : : : : partition_point_test1 ]
|
||||
[ run is_partitioned_test1.cpp : : : : is_partitioned_test1 ]
|
||||
[ run partition_copy_test1.cpp : : : : partition_copy_test1 ]
|
||||
[ run is_permutation_test1.cpp unit_test_framework : : : : is_permutation_test1 ]
|
||||
[ run partition_point_test1.cpp unit_test_framework : : : : partition_point_test1 ]
|
||||
[ run is_partitioned_test1.cpp unit_test_framework : : : : is_partitioned_test1 ]
|
||||
[ run partition_copy_test1.cpp unit_test_framework : : : : partition_copy_test1 ]
|
||||
|
||||
# Cxx14 tests
|
||||
[ run equal_test.cpp unit_test_framework : : : : equal_test ]
|
||||
[ run mismatch_test.cpp unit_test_framework : : : : mismatch_test ]
|
||||
|
||||
# Hex tests
|
||||
[ 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 ]
|
||||
[ run hex_test1.cpp unit_test_framework : : : : hex_test1 ]
|
||||
[ run hex_test2.cpp unit_test_framework : : : : hex_test2 ]
|
||||
[ run hex_test3.cpp unit_test_framework : : : : hex_test3 ]
|
||||
[ run hex_test4.cpp unit_test_framework : : : : hex_test4 ]
|
||||
[ compile-fail hex_fail1.cpp ]
|
||||
|
||||
# Gather tests
|
||||
[ run gather_test1.cpp unit_test_framework : : : : gather_test1 ]
|
||||
[ compile-fail gather_fail1.cpp ]
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,9 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/cxx11/all_of.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
@ -79,8 +81,7 @@ void test_all ()
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_all ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,7 +9,9 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/cxx11/any_of.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
@ -98,8 +100,7 @@ void test_any ()
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_any ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,7 +9,8 @@
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/clamp.hpp>
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
|
||||
@ -205,7 +206,7 @@ void test_int_range ()
|
||||
BOOST_CHECK ( std::equal ( b_e(junk), outputs ));
|
||||
}
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_ints ();
|
||||
test_floats ();
|
||||
@ -214,5 +215,4 @@ int test_main( int , char* [] )
|
||||
test_int_range ();
|
||||
// test_float_range ();
|
||||
// test_custom_range ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,7 +9,9 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/cxx11/copy_if.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
@ -18,6 +20,7 @@
|
||||
#include <list>
|
||||
|
||||
#include <boost/algorithm/cxx11/all_of.hpp>
|
||||
#include <boost/algorithm/cxx11/none_of.hpp>
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
// namespace ba = boost;
|
||||
@ -28,7 +31,7 @@ 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 ) {
|
||||
void test_copy_if ( Container const &c ) {
|
||||
|
||||
typedef typename Container::value_type value_type;
|
||||
std::vector<value_type> v;
|
||||
@ -46,42 +49,131 @@ void test_sequence ( Container const &c ) {
|
||||
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 ()));
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.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 ()));
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.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 ( v.size () == (size_t) 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 ( v.size () == (size_t) std::count_if ( c.begin (), c.end (), is_even ));
|
||||
BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
|
||||
}
|
||||
|
||||
|
||||
template <typename Container>
|
||||
void test_copy_while ( Container const &c ) {
|
||||
|
||||
typedef typename Container::value_type value_type;
|
||||
typename Container::const_iterator it;
|
||||
std::vector<value_type> v;
|
||||
|
||||
// None of the elements
|
||||
v.clear ();
|
||||
ba::copy_while ( c.begin (), c.end (), back_inserter ( v ), is_false);
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
|
||||
v.clear ();
|
||||
ba::copy_while ( c, back_inserter ( v ), is_false);
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
|
||||
// All the elements
|
||||
v.clear ();
|
||||
ba::copy_while ( c.begin (), c.end (), back_inserter ( v ), is_true);
|
||||
BOOST_CHECK ( v.size () == c.size ());
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
|
||||
v.clear ();
|
||||
ba::copy_while ( c, back_inserter ( v ), is_true);
|
||||
BOOST_CHECK ( v.size () == c.size ());
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
|
||||
// Some of the elements
|
||||
v.clear ();
|
||||
it = ba::copy_while ( c.begin (), c.end (), back_inserter ( v ), is_even ).first;
|
||||
BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it ));
|
||||
BOOST_CHECK ( it == c.end () || !is_even ( *it ));
|
||||
BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
|
||||
v.clear ();
|
||||
it = ba::copy_while ( c, back_inserter ( v ), is_even ).first;
|
||||
BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it ));
|
||||
BOOST_CHECK ( it == c.end () || !is_even ( *it ));
|
||||
BOOST_CHECK ( ba::all_of ( v.begin (), v.end (), is_even ));
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
void test_copy_until ( Container const &c ) {
|
||||
|
||||
typedef typename Container::value_type value_type;
|
||||
typename Container::const_iterator it;
|
||||
std::vector<value_type> v;
|
||||
|
||||
// None of the elements
|
||||
v.clear ();
|
||||
ba::copy_until ( c.begin (), c.end (), back_inserter ( v ), is_true);
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
|
||||
v.clear ();
|
||||
ba::copy_until ( c, back_inserter ( v ), is_true);
|
||||
BOOST_CHECK ( v.size () == 0 );
|
||||
|
||||
// All the elements
|
||||
v.clear ();
|
||||
ba::copy_until ( c.begin (), c.end (), back_inserter ( v ), is_false);
|
||||
BOOST_CHECK ( v.size () == c.size ());
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
|
||||
v.clear ();
|
||||
ba::copy_until ( c, back_inserter ( v ), is_false);
|
||||
BOOST_CHECK ( v.size () == c.size ());
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
|
||||
// Some of the elements
|
||||
v.clear ();
|
||||
it = ba::copy_until ( c.begin (), c.end (), back_inserter ( v ), is_even ).first;
|
||||
BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it ));
|
||||
BOOST_CHECK ( it == c.end () || is_even ( *it ));
|
||||
BOOST_CHECK ( ba::none_of ( v.begin (), v.end (), is_even ));
|
||||
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ()));
|
||||
|
||||
v.clear ();
|
||||
it = ba::copy_until ( c, back_inserter ( v ), is_even ).first;
|
||||
BOOST_CHECK ( v.size () == (size_t) std::distance ( c.begin (), it ));
|
||||
BOOST_CHECK ( it == c.end () || is_even ( *it ));
|
||||
BOOST_CHECK ( ba::none_of ( v.begin (), v.end (), is_even ));
|
||||
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 );
|
||||
test_copy_if ( v );
|
||||
test_copy_while ( v );
|
||||
test_copy_until ( v );
|
||||
|
||||
std::list<int> l;
|
||||
for ( int i = 25; i > 15; --i )
|
||||
l.push_back ( i );
|
||||
test_sequence ( l );
|
||||
test_copy_if ( l );
|
||||
test_copy_while ( l );
|
||||
test_copy_until ( l );
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_sequence1 ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,7 +9,9 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/cxx11/copy_n.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
@ -78,8 +80,7 @@ void test_sequence1 () {
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_sequence1 ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -13,9 +13,10 @@
|
||||
#include <boost/algorithm/searching/boyer_moore_horspool.hpp>
|
||||
#include <boost/algorithm/searching/knuth_morris_pratt.hpp>
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
int test_main( int argc, char *argv [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
const std::string cs;
|
||||
std::string estr;
|
||||
@ -77,7 +78,4 @@ int test_main( int argc, char *argv [] )
|
||||
str.begin (), str.end (), estr.begin (), estr.end ())
|
||||
== str.begin ()
|
||||
);
|
||||
|
||||
(void) argv; (void) argc;
|
||||
return 0;
|
||||
}
|
||||
|
129
test/equal_test.cpp
Normal file
129
test/equal_test.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2013.
|
||||
|
||||
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/cxx14/equal.hpp>
|
||||
|
||||
#include "iterator_test.hpp"
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
template <typename T>
|
||||
bool eq ( const T& a, const T& b ) { return a == b; }
|
||||
|
||||
template <typename T>
|
||||
bool never_eq ( const T&, const T& ) { return false; }
|
||||
|
||||
int comparison_count = 0;
|
||||
template <typename T>
|
||||
bool counting_equals ( const T &a, const T &b ) {
|
||||
++comparison_count;
|
||||
return a == b;
|
||||
}
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
|
||||
void test_equal ()
|
||||
{
|
||||
// Note: The literal values here are tested against directly, careful if you change them:
|
||||
int num[] = { 1, 1, 2, 3, 5 };
|
||||
const int sz = sizeof (num)/sizeof(num[0]);
|
||||
|
||||
|
||||
// Empty sequences are equal to each other, but not to non-empty sequences
|
||||
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num)));
|
||||
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num),
|
||||
never_eq<int> ));
|
||||
BOOST_CHECK ( ba::equal ( random_access_iterator<int *>(num), random_access_iterator<int *>(num),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num),
|
||||
never_eq<int> ));
|
||||
|
||||
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + 1)));
|
||||
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 1), input_iterator<int *>(num + 2),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num)));
|
||||
BOOST_CHECK (!ba::equal ( random_access_iterator<int *>(num + 1), random_access_iterator<int *>(num + 2),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num)));
|
||||
|
||||
// Single element sequences are equal if they contain the same value
|
||||
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + 1)));
|
||||
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
eq<int> ));
|
||||
BOOST_CHECK ( ba::equal ( random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
|
||||
eq<int> ));
|
||||
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
never_eq<int> ));
|
||||
BOOST_CHECK (!ba::equal ( random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
|
||||
never_eq<int> ));
|
||||
|
||||
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
input_iterator<int *>(num + 1), input_iterator<int *>(num + 2)));
|
||||
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
input_iterator<int *>(num + 1), input_iterator<int *>(num + 2),
|
||||
eq<int> ));
|
||||
|
||||
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 2), input_iterator<int *>(num + 3),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + 1)));
|
||||
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 2), input_iterator<int *>(num + 3),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
eq<int> ));
|
||||
|
||||
// Identical long sequences are equal.
|
||||
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + sz)));
|
||||
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
eq<int> ));
|
||||
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
never_eq<int> ));
|
||||
BOOST_CHECK ( ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz),
|
||||
eq<int> ));
|
||||
|
||||
// different sequences are different
|
||||
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 1), input_iterator<int *>(num + sz),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + sz)));
|
||||
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 1), input_iterator<int *>(num + sz),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
eq<int> ));
|
||||
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + sz - 1)));
|
||||
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + sz - 1),
|
||||
eq<int> ));
|
||||
|
||||
// When there's a cheap check, bail early
|
||||
comparison_count = 0;
|
||||
BOOST_CHECK (!ba::equal ( random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz - 1),
|
||||
counting_equals<int> ));
|
||||
BOOST_CHECK ( comparison_count == 0 );
|
||||
// And when there's not, we can't
|
||||
comparison_count = 0;
|
||||
BOOST_CHECK (!ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + sz - 1),
|
||||
counting_equals<int> ));
|
||||
BOOST_CHECK ( comparison_count > 0 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_equal ();
|
||||
}
|
@ -11,7 +11,9 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/cxx11/find_if_not.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -83,8 +85,7 @@ void test_sequence1 () {
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_sequence1 ();
|
||||
return 0;
|
||||
}
|
||||
|
38
test/gather_fail1.cpp
Normal file
38
test/gather_fail1.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/gather.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#include "iterator_test.hpp"
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
|
||||
bool is_ten ( int i ) { return i == 10; }
|
||||
|
||||
void test_sequence1 () {
|
||||
std::vector<int> v;
|
||||
typedef input_iterator<std::vector<int>::iterator> II;
|
||||
|
||||
// This should fail to compile, since gather doesn't work with input iterators
|
||||
(void) ba::gather ( II( v.begin ()), II( v.end ()), II( v.begin ()), is_even );
|
||||
}
|
||||
|
||||
|
||||
int main ()
|
||||
{
|
||||
test_sequence1 ();
|
||||
return 0;
|
||||
}
|
138
test/gather_test1.cpp
Normal file
138
test/gather_test1.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/gather.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#include "iterator_test.hpp"
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
|
||||
template <typename Container>
|
||||
void print ( const char *prompt, const Container &c ) {
|
||||
std::cout << prompt << " { ";
|
||||
std::copy ( c.begin (), c.end (), std::ostream_iterator<typename Container::value_type>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Predicate>
|
||||
void test_iterators ( Iterator first, Iterator last, Predicate comp, std::size_t offset ) {
|
||||
// Create the pivot point
|
||||
Iterator off = first;
|
||||
std::advance(off, offset);
|
||||
|
||||
// Gather the elements
|
||||
std::pair<Iterator, Iterator> res = ba::gather ( first, last, off, comp );
|
||||
|
||||
// We should now have three sequences, any of which may be empty:
|
||||
// * [begin .. result.first) - items that do not satisfy the predicate
|
||||
// * [result.first .. result.second) - items that do satisfy the predicate
|
||||
// * [result.second .. end) - items that do not satisfy the predicate
|
||||
Iterator iter = first;
|
||||
for ( ; iter != res.first; ++iter )
|
||||
BOOST_CHECK ( !comp ( *iter ));
|
||||
for ( ; iter != res.second; ++iter)
|
||||
BOOST_CHECK ( comp ( *iter ));
|
||||
for ( ; iter != last; ++iter )
|
||||
BOOST_CHECK ( !comp ( *iter ));
|
||||
}
|
||||
|
||||
template <typename Container, typename Predicate>
|
||||
void test_iterator_types ( const Container &c, Predicate comp, std::size_t offset ) {
|
||||
typedef std::vector<typename Container::value_type> vec;
|
||||
|
||||
typedef bidirectional_iterator<typename vec::iterator> BDI;
|
||||
typedef random_access_iterator<typename vec::iterator> RAI;
|
||||
|
||||
vec v;
|
||||
v.assign ( c.begin (), c.end ());
|
||||
test_iterators ( BDI ( v.begin ()), BDI ( v.end ()), comp, offset );
|
||||
v.assign ( c.begin (), c.end ());
|
||||
test_iterators ( RAI ( v.begin ()), RAI ( v.end ()), comp, offset );
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct less_than {
|
||||
public:
|
||||
// typedef T argument_type;
|
||||
// typedef bool result_type;
|
||||
|
||||
less_than ( T foo ) : val ( foo ) {}
|
||||
less_than ( const less_than &rhs ) : val ( rhs.val ) {}
|
||||
|
||||
bool operator () ( const T &v ) const { return v < val; }
|
||||
private:
|
||||
less_than ();
|
||||
less_than operator = ( const less_than &rhs );
|
||||
T val;
|
||||
};
|
||||
|
||||
bool is_even ( int i ) { return i % 2 == 0; }
|
||||
bool is_ten ( int i ) { return i == 10; }
|
||||
|
||||
void test_sequence1 () {
|
||||
std::vector<int> v;
|
||||
|
||||
for ( int i = 5; i < 15; ++i )
|
||||
v.push_back ( i );
|
||||
test_iterator_types ( v, less_than<int>(10), 0 ); // at beginning
|
||||
test_iterator_types ( v, less_than<int>(10), 5 );
|
||||
test_iterator_types ( v, less_than<int>(10), v.size () - 1 ); // at end
|
||||
|
||||
test_iterator_types ( v, is_even, 0 );
|
||||
test_iterator_types ( v, is_even, 5 );
|
||||
test_iterator_types ( v, is_even, v.size () - 1 );
|
||||
|
||||
// Exactly one element in the sequence matches
|
||||
test_iterator_types ( v, is_ten, 0 );
|
||||
test_iterator_types ( v, is_ten, 5 );
|
||||
test_iterator_types ( v, is_ten, v.size () - 1 );
|
||||
|
||||
// Everything in the sequence matches
|
||||
test_iterator_types ( v, less_than<int>(99), 0 );
|
||||
test_iterator_types ( v, less_than<int>(99), 5 );
|
||||
test_iterator_types ( v, less_than<int>(99), v.size () - 1 );
|
||||
|
||||
// Nothing in the sequence matches
|
||||
test_iterator_types ( v, less_than<int>(0), 0 );
|
||||
test_iterator_types ( v, less_than<int>(0), 5 );
|
||||
test_iterator_types ( v, less_than<int>(0), v.size () - 1 );
|
||||
|
||||
// All the elements in the sequence are the same
|
||||
v.clear ();
|
||||
for ( int i = 0; i < 11; ++i )
|
||||
v.push_back ( 10 );
|
||||
|
||||
// Everything in the sequence matches
|
||||
test_iterator_types ( v, is_ten, 0 );
|
||||
test_iterator_types ( v, is_ten, 5 );
|
||||
test_iterator_types ( v, is_ten, v.size () - 1 );
|
||||
|
||||
// Nothing in the sequence matches
|
||||
test_iterator_types ( v, less_than<int>(5), 0 );
|
||||
test_iterator_types ( v, less_than<int>(5), 5 );
|
||||
test_iterator_types ( v, less_than<int>(5), v.size () - 1 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_sequence1 ();
|
||||
}
|
@ -9,17 +9,17 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/hex.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
// should not compile: vector is not an integral type
|
||||
int test_main( int , char* [] )
|
||||
int main( int , char* [] )
|
||||
{
|
||||
std::vector<float> v;
|
||||
std::string out;
|
||||
boost::algorithm::unhex ( out, std::back_inserter(v));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,7 +9,9 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/hex.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
@ -141,7 +143,7 @@ const wchar_t *fromhex_fail_w [] = {
|
||||
};
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_to_hex<std::string> ( tohex );
|
||||
test_from_hex_success<std::string> ( fromhex );
|
||||
@ -150,5 +152,4 @@ int test_main( int , char* [] )
|
||||
test_to_hex<std::wstring> ( tohex_w );
|
||||
test_from_hex_success<std::wstring> ( fromhex_w );
|
||||
test_from_hex_failure<std::wstring> ( fromhex_fail_w );
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,7 +11,9 @@ Test non-string cases; vector and list
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/hex.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
@ -129,9 +131,8 @@ void test_from_hex_success () {
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_to_hex ();
|
||||
test_from_hex_success ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,7 +11,9 @@ Try ostream_iterators
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/hex.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
@ -113,11 +115,10 @@ const wchar_t *fromhex_w [] = {
|
||||
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_to_hex ( tohex );
|
||||
test_to_hex ( tohex_w );
|
||||
test_from_hex_success ( fromhex );
|
||||
test_from_hex_success ( fromhex_w );
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,7 +11,9 @@ Try ostream_iterators
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/hex.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
@ -136,10 +138,8 @@ void test_nonhex_input () {
|
||||
test_nonhex_input4 ();
|
||||
}
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_short_input ();
|
||||
test_nonhex_input ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,7 +9,9 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/cxx11/iota.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@ -72,8 +74,7 @@ void test_ints () {
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_ints ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,7 +11,9 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/cxx11/is_partitioned.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -56,8 +58,7 @@ void test_sequence1 () {
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_sequence1 ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,16 +11,103 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/cxx11/is_permutation.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#include "iterator_test.hpp"
|
||||
|
||||
template <typename T>
|
||||
bool eq ( const T& a, const T& b ) { return a == b; }
|
||||
|
||||
template <typename T>
|
||||
bool never_eq ( const T&, const T& ) { return false; }
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
// namespace ba = boost;
|
||||
|
||||
void test_sequence1 () {
|
||||
int num[] = { 1, 1, 2, 3, 5 };
|
||||
const int sz = sizeof (num)/sizeof(num[0]);
|
||||
|
||||
// Empty sequences
|
||||
BOOST_CHECK (
|
||||
ba::is_permutation (
|
||||
forward_iterator<int *>(num), forward_iterator<int *>(num),
|
||||
forward_iterator<int *>(num)));
|
||||
BOOST_CHECK (
|
||||
ba::is_permutation (
|
||||
forward_iterator<int *>(num), forward_iterator<int *>(num),
|
||||
forward_iterator<int *>(num), forward_iterator<int *>(num)));
|
||||
BOOST_CHECK (
|
||||
ba::is_permutation (
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num)));
|
||||
BOOST_CHECK (
|
||||
ba::is_permutation (
|
||||
forward_iterator<int *>(num), forward_iterator<int *>(num),
|
||||
forward_iterator<int *>(num),
|
||||
never_eq<int> )); // Since the sequences are empty, the pred is never called
|
||||
|
||||
// Empty vs. non-empty
|
||||
BOOST_CHECK ( !
|
||||
ba::is_permutation (
|
||||
forward_iterator<int *>(num), forward_iterator<int *>(num),
|
||||
forward_iterator<int *>(num), forward_iterator<int *>(num + 1)));
|
||||
|
||||
BOOST_CHECK ( !
|
||||
ba::is_permutation (
|
||||
forward_iterator<int *>(num + 1), forward_iterator<int *>(num + 2),
|
||||
forward_iterator<int *>(num), forward_iterator<int *>(num)));
|
||||
|
||||
BOOST_CHECK ( !
|
||||
ba::is_permutation (
|
||||
random_access_iterator<int *>(num + 1), random_access_iterator<int *>(num + 2),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num)));
|
||||
|
||||
BOOST_CHECK ( !
|
||||
ba::is_permutation (
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num),
|
||||
random_access_iterator<int *>(num + 1), random_access_iterator<int *>(num + 2)));
|
||||
|
||||
// Something should be a permutation of itself
|
||||
BOOST_CHECK (
|
||||
ba::is_permutation (
|
||||
forward_iterator<int *>(num), forward_iterator<int *>(num + sz),
|
||||
forward_iterator<int *>(num)));
|
||||
BOOST_CHECK (
|
||||
ba::is_permutation (
|
||||
forward_iterator<int *>(num), forward_iterator<int *>(num + sz),
|
||||
forward_iterator<int *>(num), eq<int> ));
|
||||
BOOST_CHECK (
|
||||
ba::is_permutation (
|
||||
forward_iterator<int *>(num), forward_iterator<int *>(num + sz),
|
||||
forward_iterator<int *>(num), forward_iterator<int *>(num + sz )));
|
||||
BOOST_CHECK (
|
||||
ba::is_permutation (
|
||||
forward_iterator<int *>(num), forward_iterator<int *>(num + sz),
|
||||
forward_iterator<int *>(num), forward_iterator<int *>(num + sz ),
|
||||
eq<int> ));
|
||||
|
||||
BOOST_CHECK (
|
||||
ba::is_permutation (
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz)));
|
||||
BOOST_CHECK (
|
||||
ba::is_permutation (
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz),
|
||||
eq<int> ));
|
||||
BOOST_CHECK (
|
||||
ba::is_permutation (
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz),
|
||||
forward_iterator<int *>(num), forward_iterator<int *>(num + sz),
|
||||
eq<int> ));
|
||||
|
||||
|
||||
std::vector<int> v, v1;
|
||||
|
||||
v.clear ();
|
||||
@ -42,8 +129,7 @@ void test_sequence1 () {
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_sequence1 ();
|
||||
return 0;
|
||||
}
|
||||
|
296
test/iterator_test.hpp
Normal file
296
test/iterator_test.hpp
Normal file
@ -0,0 +1,296 @@
|
||||
#ifndef ITERATOR_TEST_H
|
||||
#define ITERATOR_TEST_H
|
||||
|
||||
/*
|
||||
A set of iterator adapters for constructing test cases
|
||||
From an iterator (or a pointer), you can make any class of iterator.
|
||||
Assuming you want to degrade the capabilities.
|
||||
|
||||
Modeled closely on work that Howard Hinnant did for libc++.
|
||||
*/
|
||||
|
||||
#include <iterator>
|
||||
|
||||
// == Input Iterator ==
|
||||
template <typename It>
|
||||
class input_iterator {
|
||||
public:
|
||||
typedef std::input_iterator_tag iterator_category;
|
||||
typedef typename std::iterator_traits<It>::value_type value_type;
|
||||
typedef typename std::iterator_traits<It>::difference_type difference_type;
|
||||
typedef It pointer;
|
||||
typedef typename std::iterator_traits<It>::reference reference;
|
||||
|
||||
It base() const {return it_;}
|
||||
|
||||
input_iterator() : it_() {}
|
||||
explicit input_iterator(It it) : it_(it) {}
|
||||
|
||||
template <typename U>
|
||||
input_iterator(const input_iterator<U>& u) :it_(u.it_) {}
|
||||
|
||||
reference operator*() const {return *it_;}
|
||||
pointer operator->() const {return it_;}
|
||||
|
||||
input_iterator& operator++() {++it_; return *this;}
|
||||
input_iterator operator++(int) {input_iterator tmp(*this); ++(*this); return tmp;}
|
||||
|
||||
friend bool operator==(const input_iterator& x, const input_iterator& y)
|
||||
{return x.it_ == y.it_;}
|
||||
friend bool operator!=(const input_iterator& x, const input_iterator& y)
|
||||
{return !(x == y);}
|
||||
|
||||
private:
|
||||
It it_;
|
||||
template <typename U> friend class input_iterator;
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool
|
||||
operator==(const input_iterator<T>& x, const input_iterator<U>& y)
|
||||
{
|
||||
return x.base() == y.base();
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool
|
||||
operator!=(const input_iterator<T>& x, const input_iterator<U>& y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
|
||||
// == Forward Iterator ==
|
||||
template <typename It>
|
||||
class forward_iterator {
|
||||
public:
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef typename std::iterator_traits<It>::value_type value_type;
|
||||
typedef typename std::iterator_traits<It>::difference_type difference_type;
|
||||
typedef It pointer;
|
||||
typedef typename std::iterator_traits<It>::reference reference;
|
||||
|
||||
It base() const {return it_;}
|
||||
|
||||
forward_iterator() : it_() {}
|
||||
explicit forward_iterator(It it) : it_(it) {}
|
||||
template <typename U>
|
||||
forward_iterator(const forward_iterator<U>& u) :it_(u.it_) {}
|
||||
|
||||
reference operator*() const {return *it_;}
|
||||
pointer operator->() const {return it_;}
|
||||
|
||||
forward_iterator& operator++() {++it_; return *this;}
|
||||
forward_iterator operator++(int) {forward_iterator tmp(*this); ++(*this); return tmp;}
|
||||
|
||||
friend bool operator==(const forward_iterator& x, const forward_iterator& y)
|
||||
{return x.it_ == y.it_;}
|
||||
friend bool operator!=(const forward_iterator& x, const forward_iterator& y)
|
||||
{return !(x == y);}
|
||||
private:
|
||||
It it_;
|
||||
|
||||
template <typename U> friend class forward_iterator;
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool
|
||||
operator==(const forward_iterator<T>& x, const forward_iterator<U>& y)
|
||||
{
|
||||
return x.base() == y.base();
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool
|
||||
operator!=(const forward_iterator<T>& x, const forward_iterator<U>& y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
// == Bidirectional Iterator ==
|
||||
template <typename It>
|
||||
class bidirectional_iterator
|
||||
{
|
||||
public:
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef typename std::iterator_traits<It>::value_type value_type;
|
||||
typedef typename std::iterator_traits<It>::difference_type difference_type;
|
||||
typedef It pointer;
|
||||
typedef typename std::iterator_traits<It>::reference reference;
|
||||
|
||||
It base() const {return it_;}
|
||||
|
||||
bidirectional_iterator() : it_() {}
|
||||
explicit bidirectional_iterator(It it) : it_(it) {}
|
||||
template <typename U>
|
||||
bidirectional_iterator(const bidirectional_iterator<U>& u) :it_(u.it_) {}
|
||||
|
||||
reference operator*() const {return *it_;}
|
||||
pointer operator->() const {return it_;}
|
||||
|
||||
bidirectional_iterator& operator++() {++it_; return *this;}
|
||||
bidirectional_iterator operator++(int) {bidirectional_iterator tmp(*this); ++(*this); return tmp;}
|
||||
|
||||
bidirectional_iterator& operator--() {--it_; return *this;}
|
||||
bidirectional_iterator operator--(int) {bidirectional_iterator tmp(*this); --(*this); return tmp;}
|
||||
private:
|
||||
It it_;
|
||||
template <typename U> friend class bidirectional_iterator;
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool
|
||||
operator==(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
|
||||
{
|
||||
return x.base() == y.base();
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool
|
||||
operator!=(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
|
||||
// == Random Access Iterator ==
|
||||
template <typename It>
|
||||
class random_access_iterator {
|
||||
public:
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef typename std::iterator_traits<It>::value_type value_type;
|
||||
typedef typename std::iterator_traits<It>::difference_type difference_type;
|
||||
typedef It pointer;
|
||||
typedef typename std::iterator_traits<It>::reference reference;
|
||||
|
||||
It base() const {return it_;}
|
||||
|
||||
random_access_iterator() : it_() {}
|
||||
explicit random_access_iterator(It it) : it_(it) {}
|
||||
template <typename U>
|
||||
random_access_iterator(const random_access_iterator<U>& u) :it_(u.it_) {}
|
||||
|
||||
reference operator*() const {return *it_;}
|
||||
pointer operator->() const {return it_;}
|
||||
|
||||
random_access_iterator& operator++() {++it_; return *this;}
|
||||
random_access_iterator operator++(int) {random_access_iterator tmp(*this); ++(*this); return tmp;}
|
||||
|
||||
random_access_iterator& operator--() {--it_; return *this;}
|
||||
random_access_iterator operator--(int) {random_access_iterator tmp(*this); --(*this); return tmp;}
|
||||
|
||||
random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;}
|
||||
random_access_iterator operator+ (difference_type n) const {random_access_iterator tmp(*this); tmp += n; return tmp;}
|
||||
friend random_access_iterator operator+(difference_type n, random_access_iterator x) {x += n; return x;}
|
||||
|
||||
random_access_iterator& operator-=(difference_type n) {return *this += -n;}
|
||||
random_access_iterator operator- (difference_type n) const {random_access_iterator tmp(*this); tmp -= n; return tmp;}
|
||||
|
||||
reference operator[](difference_type n) const {return it_[n];}
|
||||
private:
|
||||
It it_;
|
||||
|
||||
template <typename U> friend class random_access_iterator;
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool
|
||||
operator==(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
|
||||
{
|
||||
return x.base() == y.base();
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool
|
||||
operator!=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool
|
||||
operator<(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
|
||||
{
|
||||
return x.base() < y.base();
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool
|
||||
operator<=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
|
||||
{
|
||||
return !(y < x);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool
|
||||
operator>(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
|
||||
{
|
||||
return y < x;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool
|
||||
operator>=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
|
||||
{
|
||||
return !(x < y);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline typename std::iterator_traits<T>::difference_type
|
||||
operator-(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
|
||||
{
|
||||
return x.base() - y.base();
|
||||
}
|
||||
|
||||
|
||||
// == Output Iterator ==
|
||||
template <typename It>
|
||||
class output_iterator {
|
||||
public:
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
typedef void value_type;
|
||||
typedef typename std::iterator_traits<It>::difference_type difference_type;
|
||||
typedef It pointer;
|
||||
typedef typename std::iterator_traits<It>::reference reference;
|
||||
|
||||
It base() const {return it_;}
|
||||
|
||||
output_iterator () {}
|
||||
explicit output_iterator(It it) : it_(it) {}
|
||||
|
||||
template <typename U>
|
||||
output_iterator(const output_iterator<U>& u) :it_(u.it_) {}
|
||||
|
||||
reference operator*() const {return *it_;}
|
||||
|
||||
output_iterator& operator++() {++it_; return *this;}
|
||||
output_iterator operator++(int) {output_iterator tmp(*this); ++(*this); return tmp;}
|
||||
|
||||
private:
|
||||
It it_;
|
||||
template <typename U> friend class output_iterator;
|
||||
};
|
||||
|
||||
// No comparison operators for output iterators
|
||||
|
||||
|
||||
// == Get the base of an iterator; used for comparisons ==
|
||||
template <typename Iter>
|
||||
inline Iter base(output_iterator<Iter> i) { return i.base(); }
|
||||
|
||||
template <typename Iter>
|
||||
inline Iter base(input_iterator<Iter> i) { return i.base(); }
|
||||
|
||||
template <typename Iter>
|
||||
inline Iter base(forward_iterator<Iter> i) { return i.base(); }
|
||||
|
||||
template <typename Iter>
|
||||
inline Iter base(bidirectional_iterator<Iter> i) { return i.base(); }
|
||||
|
||||
template <typename Iter>
|
||||
inline Iter base(random_access_iterator<Iter> i) { return i.base(); }
|
||||
|
||||
template <typename Iter> // everything else
|
||||
inline Iter base(Iter i) { return i; }
|
||||
|
||||
#endif // ITERATORS_H
|
168
test/mismatch_test.cpp
Normal file
168
test/mismatch_test.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2013.
|
||||
|
||||
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/cxx14/mismatch.hpp>
|
||||
|
||||
#include "iterator_test.hpp"
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
template <typename T>
|
||||
bool eq ( const T& a, const T& b ) { return a == b; }
|
||||
|
||||
template <typename T>
|
||||
bool never_eq ( const T&, const T& ) { return false; }
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
|
||||
template <typename Iter1, typename Iter2>
|
||||
bool iter_eq ( std::pair<Iter1, Iter2> pr, Iter1 first, Iter2 second ) {
|
||||
return pr.first == first && pr.second == second;
|
||||
}
|
||||
|
||||
void test_mismatch ()
|
||||
{
|
||||
// Note: The literal values here are tested against directly, careful if you change them:
|
||||
int num[] = { 1, 1, 2, 3, 5 };
|
||||
const int sz = sizeof (num)/sizeof(num[0]);
|
||||
|
||||
|
||||
// No mismatch for empty sequences
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num)),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num)));
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num),
|
||||
never_eq<int> ),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num)));
|
||||
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( random_access_iterator<int *>(num), random_access_iterator<int *>(num),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num),
|
||||
never_eq<int> ),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num)));
|
||||
|
||||
// Empty vs. non-empty mismatch immediately
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + 1)),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num)));
|
||||
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num + 1), input_iterator<int *>(num + 2),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num)),
|
||||
input_iterator<int *>(num + 1), input_iterator<int *>(num)));
|
||||
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( random_access_iterator<int *>(num + 1), random_access_iterator<int *>(num + 2),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num)),
|
||||
random_access_iterator<int *>(num + 1), random_access_iterator<int *>(num)));
|
||||
|
||||
// Single element sequences are equal if they contain the same value
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + 1)),
|
||||
input_iterator<int *>(num + 1), input_iterator<int *>(num + 1)));
|
||||
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
eq<int> ),
|
||||
input_iterator<int *>(num + 1), input_iterator<int *>(num + 1)));
|
||||
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
|
||||
eq<int> ),
|
||||
random_access_iterator<int *>(num + 1), random_access_iterator<int *>(num + 1)));
|
||||
|
||||
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
never_eq<int> ),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num)));
|
||||
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1),
|
||||
never_eq<int> ),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num)));
|
||||
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
input_iterator<int *>(num + 1), input_iterator<int *>(num + 2)),
|
||||
input_iterator<int *>(num + 1), input_iterator<int *>(num + 2)));
|
||||
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
input_iterator<int *>(num + 1), input_iterator<int *>(num + 2),
|
||||
eq<int> ),
|
||||
input_iterator<int *>(num + 1), input_iterator<int *>(num + 2)));
|
||||
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num + 2), input_iterator<int *>(num + 3),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + 1)),
|
||||
input_iterator<int *>(num + 2), input_iterator<int *>(num)));
|
||||
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num + 2), input_iterator<int *>(num + 3),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + 1),
|
||||
eq<int> ),
|
||||
input_iterator<int *>(num + 2), input_iterator<int *>(num)));
|
||||
|
||||
|
||||
|
||||
// Identical long sequences are equal.
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + sz)),
|
||||
input_iterator<int *>(num + sz), input_iterator<int *>(num + sz)));
|
||||
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
eq<int> ),
|
||||
input_iterator<int *>(num + sz), input_iterator<int *>(num + sz)));
|
||||
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
never_eq<int> ),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num)));
|
||||
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz),
|
||||
never_eq<int> ),
|
||||
input_iterator<int *>(num), random_access_iterator<int *>(num)));
|
||||
|
||||
// different sequences are different
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num + 1), input_iterator<int *>(num + sz),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + sz)),
|
||||
input_iterator<int *>(num + 2), input_iterator<int *>(num + 1)));
|
||||
|
||||
BOOST_CHECK ( iter_eq (
|
||||
ba::mismatch ( input_iterator<int *>(num + 1), input_iterator<int *>(num + sz),
|
||||
input_iterator<int *>(num), input_iterator<int *>(num + sz),
|
||||
eq<int> ),
|
||||
input_iterator<int *>(num + 2), input_iterator<int *>(num + 1)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_mismatch ();
|
||||
}
|
@ -9,7 +9,9 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/cxx11/none_of.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
@ -89,8 +91,7 @@ void test_none()
|
||||
BOOST_CHECK (!ba::none_of ( li.begin(), l_iter, is_<int> ( 5 )));
|
||||
}
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_none();
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,7 +9,9 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/cxx11/one_of.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
@ -94,8 +96,7 @@ void test_one ()
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_one ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -13,7 +13,9 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/algorithm/cxx11/is_sorted.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
@ -146,9 +148,8 @@ test_increasing_decreasing(void)
|
||||
|
||||
}
|
||||
|
||||
int test_main( int, char * [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_ordered ();
|
||||
test_increasing_decreasing ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,7 +11,9 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/cxx11/partition_copy.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <boost/algorithm/cxx11/all_of.hpp>
|
||||
#include <boost/algorithm/cxx11/none_of.hpp>
|
||||
@ -80,8 +82,7 @@ void test_sequence1 () {
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_sequence1 ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,7 +11,9 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/cxx11/partition_point.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -91,8 +93,7 @@ void test_sequence1 () {
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
test_sequence1 ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <vector>
|
||||
#include <boost/algorithm/searching/boyer_moore.hpp>
|
||||
|
||||
int main( int argc, char *argv [] )
|
||||
int main( int , char* [] )
|
||||
{
|
||||
std::vector<char> cv;
|
||||
std::vector<int> iv;
|
||||
@ -20,7 +20,5 @@ int main( int argc, char *argv [] )
|
||||
(void) boost::algorithm::boyer_moore_search (
|
||||
cv.begin (), cv.end (), iv.begin (), iv.end ());
|
||||
|
||||
|
||||
(void) argv; (void) argc;
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/algorithm/searching/boyer_moore.hpp>
|
||||
|
||||
int main( int argc, char *argv [] )
|
||||
int main( int , char* [] )
|
||||
{
|
||||
std::vector<boost::uint8_t> cv;
|
||||
std::vector<boost:: int8_t> iv;
|
||||
@ -21,7 +21,5 @@ int main( int argc, char *argv [] )
|
||||
(void) boost::algorithm::boyer_moore_search (
|
||||
cv.begin (), cv.end (), iv.begin (), iv.end ());
|
||||
|
||||
|
||||
(void) argv; (void) argc;
|
||||
return 0;
|
||||
}
|
||||
|
@ -10,11 +10,10 @@
|
||||
#include <vector>
|
||||
#include <boost/algorithm/searching/boyer_moore.hpp>
|
||||
|
||||
int main( int argc, char *argv [] )
|
||||
int main( int , char* [] )
|
||||
{
|
||||
// Should fail to compile because the search objects are not default-constructible
|
||||
boost::algorithm::boyer_moore<std::vector<char>::iterator> bm;
|
||||
|
||||
(void) argv; (void) argc;
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,7 +11,8 @@
|
||||
#include <boost/algorithm/searching/boyer_moore_horspool.hpp>
|
||||
#include <boost/algorithm/searching/knuth_morris_pratt.hpp>
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@ -218,7 +219,7 @@ namespace {
|
||||
}
|
||||
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
std::string haystack1 ( "NOW AN FOWE\220ER ANNMAN THE ANPANMANEND" );
|
||||
std::string needle1 ( "ANPANMAN" );
|
||||
@ -268,5 +269,4 @@ int test_main( int , char* [] )
|
||||
const std::string mikhail_corpus = std::string (8, 'a') + mikhail_pattern;
|
||||
|
||||
check_one ( mikhail_corpus, mikhail_pattern, 8 );
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,9 +11,13 @@
|
||||
#include <boost/algorithm/searching/boyer_moore_horspool.hpp>
|
||||
#include <boost/algorithm/searching/knuth_morris_pratt.hpp>
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <ctime> // for clock_t
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
@ -122,7 +126,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
vec c1 = ReadFromFile ( "search_test_data/0001.corpus" );
|
||||
vec p1b = ReadFromFile ( "search_test_data/0001b.pat" );
|
||||
@ -140,6 +144,4 @@ int test_main( int , char* [] )
|
||||
check_one ( c1, p1e, c1.size() - p1e.size ());
|
||||
std::cout << "--- Not found ---" << std::endl;
|
||||
check_one ( c1, p1n, -1 ); // Not found
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,9 +11,13 @@
|
||||
#include <boost/algorithm/searching/boyer_moore_horspool.hpp>
|
||||
#include <boost/algorithm/searching/knuth_morris_pratt.hpp>
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <ctime> // for clock_t
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@ -122,7 +126,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
vec c1 = ReadFromFile ( "search_test_data/0001.corpus" );
|
||||
vec p1b = ReadFromFile ( "search_test_data/0002b.pat" );
|
||||
@ -140,6 +144,4 @@ int test_main( int , char* [] )
|
||||
check_one ( c1, p1e, c1.size() - p1e.size ());
|
||||
std::cout << "--- Not found ---" << std::endl;
|
||||
check_one ( c1, p1n, -1 ); // Not found
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -13,9 +13,12 @@
|
||||
#include <boost/algorithm/searching/boyer_moore_horspool.hpp>
|
||||
#include <boost/algorithm/searching/knuth_morris_pratt.hpp>
|
||||
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@ -93,7 +96,7 @@ namespace {
|
||||
|
||||
}
|
||||
|
||||
int test_main( int , char* [] )
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
vec c1 = ReadFromFile ( "search_test_data/0001.corpus" );
|
||||
vec p1b = ReadFromFile ( "search_test_data/0002b.pat" );
|
||||
@ -111,6 +114,4 @@ int test_main( int , char* [] )
|
||||
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