From 72b87bdfc48b8dfff4c8a1b73337e660ff7a20e8 Mon Sep 17 00:00:00 2001 From: nobody Date: Tue, 13 Sep 2005 14:20:32 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'thread_rewrite'. [SVN r30953] --- minmax/doc/minmax_benchs.html | 524 -------------------- minmax/doc/minmax_synopsis.html | 127 ----- minmax/example/Jamfile | 14 - minmax/example/minmax_ex.cpp | 36 -- minmax/example/minmax_timer.cpp | 212 --------- minmax/index.html | 528 --------------------- minmax/test/Jamfile | 33 -- minmax/test/Jamfile.v2 | 20 - minmax/test/minmax_element_test.cpp | 241 ---------- minmax/test/minmax_test.cpp | 85 ---- string/doc/Jamfile.v2 | 52 -- string/doc/concept.xml | 199 -------- string/doc/credits.xml | 19 - string/doc/design.xml | 216 --------- string/doc/environment.xml | 59 --- string/doc/external_concepts.html | 38 -- string/doc/intro.xml | 47 -- string/doc/quickref.xml | 686 --------------------------- string/doc/rationale.xml | 46 -- string/doc/release_notes.xml | 17 - string/doc/string_algo.xml | 46 -- string/doc/usage.xml | 353 -------------- string/example/Jamfile | 75 --- string/example/conv_example.cpp | 41 -- string/example/find_example.cpp | 58 --- string/example/predicate_example.cpp | 61 --- string/example/regex_example.cpp | 42 -- string/example/replace_example.cpp | 89 ---- string/example/rle_example.cpp | 241 ---------- string/example/split_example.cpp | 62 --- string/example/trim_example.cpp | 47 -- string/index.html | 9 - string/test/Jamfile | 77 --- string/test/Jamfile.v2 | 57 --- string/test/conv_test.cpp | 95 ---- string/test/find_test.cpp | 231 --------- string/test/predicate_test.cpp | 126 ----- string/test/regex_test.cpp | 137 ------ string/test/replace_test.cpp | 282 ----------- string/test/split_test.cpp | 133 ------ string/test/trim_test.cpp | 118 ----- sublibs | 1 - 42 files changed, 5580 deletions(-) delete mode 100644 minmax/doc/minmax_benchs.html delete mode 100644 minmax/doc/minmax_synopsis.html delete mode 100644 minmax/example/Jamfile delete mode 100644 minmax/example/minmax_ex.cpp delete mode 100644 minmax/example/minmax_timer.cpp delete mode 100644 minmax/index.html delete mode 100644 minmax/test/Jamfile delete mode 100644 minmax/test/Jamfile.v2 delete mode 100644 minmax/test/minmax_element_test.cpp delete mode 100644 minmax/test/minmax_test.cpp delete mode 100644 string/doc/Jamfile.v2 delete mode 100644 string/doc/concept.xml delete mode 100644 string/doc/credits.xml delete mode 100644 string/doc/design.xml delete mode 100644 string/doc/environment.xml delete mode 100644 string/doc/external_concepts.html delete mode 100644 string/doc/intro.xml delete mode 100644 string/doc/quickref.xml delete mode 100644 string/doc/rationale.xml delete mode 100644 string/doc/release_notes.xml delete mode 100644 string/doc/string_algo.xml delete mode 100644 string/doc/usage.xml delete mode 100644 string/example/Jamfile delete mode 100644 string/example/conv_example.cpp delete mode 100644 string/example/find_example.cpp delete mode 100644 string/example/predicate_example.cpp delete mode 100644 string/example/regex_example.cpp delete mode 100644 string/example/replace_example.cpp delete mode 100644 string/example/rle_example.cpp delete mode 100644 string/example/split_example.cpp delete mode 100644 string/example/trim_example.cpp delete mode 100644 string/index.html delete mode 100644 string/test/Jamfile delete mode 100644 string/test/Jamfile.v2 delete mode 100644 string/test/conv_test.cpp delete mode 100644 string/test/find_test.cpp delete mode 100644 string/test/predicate_test.cpp delete mode 100644 string/test/regex_test.cpp delete mode 100644 string/test/replace_test.cpp delete mode 100644 string/test/split_test.cpp delete mode 100644 string/test/trim_test.cpp delete mode 100644 sublibs diff --git a/minmax/doc/minmax_benchs.html b/minmax/doc/minmax_benchs.html deleted file mode 100644 index bb5713a..0000000 --- a/minmax/doc/minmax_benchs.html +++ /dev/null @@ -1,524 +0,0 @@ - - - - - - - - Boost minmax library - - - -
-

-Minmax_element Performance

- -

-About performance

-Of course, there are many factors that affect the performance of an algorithm. -The number of comparison is only one, but also branch prediction, pipelining, -locality of reference (affects cache efficiency), etc. In practice, -we observe that when the iterator type is a pointer, -boost::minmax_element -is only a tad slower than -std::min_element, and is even faster -than -boost::first_min_last_max_element! This is even more true -for slower iterators (list<>::iterator or -map<>iterator -for instance). The following experiments were conducted on a Pentium III -500 Mhz running Linux and compiled with g++, version 2.95.2, flags -O3. -In the tables, we use different distributions: Identical means that -all the elements are identical, 2-valued means that we replace the -second half of the identical elements by a distinct element, increasing -means that all the elements are distinct and in increasing order, decreasing -is the reverse, and random is produced by random_shuffle. -
-The program that created these tables is included in the distribution, -under minmax_timer.cpp -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
vector<int>::iteratorIdentical2-valuedIncreasingDecreasingRandom
std::min_element23.26M/s23.26M/s23.15M/s22.94M/s22.94M/s
std::max_element23.26M/s23.26M/s23.15M/s22.94M/s22.62M/s
boost::first_min_element23.15M/s23.04M/s23.04M/s22.94M/s22.83M/s
boost::last_min_element23.26M/s23.26M/s23.26M/s22.83M/s16.23M/s
boost::first_max_element23.15M/s23.26M/s23.15M/s23.04M/s22.93M/s
boost::last_max_element23.26M/s23.15M/s23.15M/s22.94M/s16.18M/s
boost::minmax_element21.83M/s21.83M/s21.83M/s21.55M/s17.79M/s
boost::first_min_last_max_element18.52M/s18.38M/s18.38M/s18.94M/s16.29M/s
boost::last_min_first_max_element20.08M/s20.83M/s20.75M/s19.76M/s15.87M/s
boost::last_min_last_max_element18.66M/s19.69M/s19.69M/s19.23M/s15.77M/s
Number of elements per second for standard vector -container iterators
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
list<int>::iteratorIdentical2-valuedIncreasingDecreasingRandom
std::min_element5.8M/s5.8M/s5.80M/s5.73M/s5.73M/s
std::max_element5.81M/s5.81M/s5.78M/s5.73M/s5.75M/s
boost::first_min_element5.81M/s5.81M/s5.79M/s5.75M/s5.73M/s
boost::last_min_element5.81M/s5.80M/s5.79M/s5.73M/s5.03M/s
boost::first_max_element5.81M/s5.80M/s5.78M/s5.74M/s5.73M/s
boost::last_max_element5.81M/s5.80M/s5.79M/s5.73M/s5.07M/s
boost::minmax_element5.68M/s5.80M/s5.66M/s5.74M/s5.30M/s
boost::first_min_last_max_element5.79M/s5.81M/s5.78M/s5.73M/s5.04M/s
boost::last_min_first_max_element5.69M/s5.79M/s5.69M/s5.73M/s4.84M/s
boost::last_min_last_max_element5.61M/s5.79M/s5.64M/s5.74M/s4.75M/s
Runtimes for standard list container iterators
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
multiset<int>::iteratorIdentical2-valuedIncreasingDecreasingRandom
std::min_element4.03M/s4.04M/s4.02M/s4.04M/s2.97M/s
std::max_element3.007M4.02M/s4.02M/s4.01M/s4.02M/s2.96M/s
boost::first_min_element4.01M/s4.04M/s4.03M/s4.04M/s3.01M/s
boost::last_min_element4.03M/s4.04M/s4.04M/s4.04M/s3.00M/s
boost::first_max_element4.04M/s4.04M/s4.04M/s4.06M/s3.01M/s
boost::last_max_element4.04M/s4.04M/s4.03M/s4.04M/s3.00M/s
boost::minmax_element3.98M/s3.99M/s3.98M/s3.99M/s3.00M/s
boost::first_min_last_max_element3.99M/s3.98M/s3.97M/s3.99M/s2.99M/s
boost::last_min_first_max_element3.97M/s3.98M/s3.96M/s3.98M/s3.00M/s
boost::last_min_last_max_element4.00M/s4.00M/s4.00M/s4.02M/s2.97M/s
Runtimes for standard set/multiset container iterators
- -
-
Last modified 2004-06-28 -

© Copyright Hervé -Brönnimann, Polytechnic University, 2002--2004. -Use, modification, and distribution is subject to 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) - - - diff --git a/minmax/doc/minmax_synopsis.html b/minmax/doc/minmax_synopsis.html deleted file mode 100644 index 1651a13..0000000 --- a/minmax/doc/minmax_synopsis.html +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - Boost minmax library synopsis - - - -

-

-Minmax_element complete synopsis

- -

-Synopsis of <boost/algorithm/minmax.hpp>

- -
#include <boost/tuple/tuple.hpp>
-
-namespace boost {
-
-  template <class T>
-  tuple<T const&, T const&> >
-  minmax(const T& a, const T& b);
-
-  template <class T, class BinaryPredicate>
-  tuple<T const&, T const&> >
-  minmax(const T& a, const T& b, BinaryPredicate comp);
-
-}
-
- -

-Synopsis of <boost/algorithm/minmax_element.hpp>

- -
#include <utility> //for std::pair
-
-namespace boost {
-
-  template <class ForwardIterator>
-  std::pair<ForwardIterator,ForwardIterator>
-  minmax_element(ForwardIterator first, ForwardIterator last);
-
-  template <class ForwardIterator, class BinaryPredicate>
-  std::pair<ForwardIterator,ForwardIterator>
-  minmax_element(ForwardIterator first, ForwardIterator last,
-                 BinaryPredicate comp);
-
-  // Variants
-
-  template <class ForwardIterator>
-  ForwardIterator first_min_element(ForwardIterator first, ForwardIterator last);
-
-  template <class ForwardIterator, class BinaryPredicate>
-  ForwardIterator first_min_element(ForwardIterator first, ForwardIterator last,
-                                    BinaryPredicate comp);
-
-  template <class ForwardIterator>
-  ForwardIterator last_min_element(ForwardIterator first, ForwardIterator last);
-
-  template <class ForwardIterator, class BinaryPredicate>
-  ForwardIterator last_min_element(ForwardIterator first, ForwardIterator last,
-                                   BinaryPredicate comp);
-
-  template <class ForwardIterator>
-  ForwardIterator first_max_element(ForwardIterator first, ForwardIterator last);
-
-  template <class ForwardIterator, class BinaryPredicate>
-  ForwardIterator first_max_element(ForwardIterator first, ForwardIterator last,
-                                    BinaryPredicate comp);
-
-  template <class ForwardIterator>
-  ForwardIterator last_max_element(ForwardIterator first, ForwardIterator last);
-
-  template <class ForwardIterator, class BinaryPredicate>
-  ForwardIterator last_max_element(ForwardIterator first, ForwardIterator last,
-                                   BinaryPredicate comp);
-
-  template <class ForwardIterator>
-  std::pair<ForwardIterator,ForwardIterator>
-  first_min_first_max_element(ForwardIterator first, ForwardIterator last);
-
-  template <class ForwardIterator, class BinaryPredicate>
-  std::pair<ForwardIterator,ForwardIterator>
-  first_min_first_max_element(ForwardIterator first, ForwardIterator last,
-                             BinaryPredicate comp);
-
-  template <class ForwardIterator>
-  std::pair<ForwardIterator,ForwardIterator>
-  first_min_last_max_element(ForwardIterator first, ForwardIterator last);
-
-  template <class ForwardIterator, class BinaryPredicate>
-  std::pair<ForwardIterator,ForwardIterator>
-  first_min_last_max_element(ForwardIterator first, ForwardIterator last,
-                             BinaryPredicate comp);
-
-  template <class ForwardIterator>
-  std::pair<ForwardIterator,ForwardIterator>
-  last_min_first_max_element(ForwardIterator first, ForwardIterator last);
-
-  template <class ForwardIterator, class BinaryPredicate>
-  std::pair<ForwardIterator,ForwardIterator>
-  last_min_first_max_element(ForwardIterator first, ForwardIterator last,
-                             BinaryPredicate comp);
-
-  template <class ForwardIterator>
-  std::pair<ForwardIterator,ForwardIterator>
-  last_min_last_max_element(ForwardIterator first, ForwardIterator last);
-
-  template <class ForwardIterator, class BinaryPredicate>
-  std::pair<ForwardIterator,ForwardIterator>
-  last_min_last_max_element(ForwardIterator first, ForwardIterator last,
-                            BinaryPredicate comp);
-
-}
- -
-
Last modified 2002-07-01 -

© Copyright Hervé -Brönnimann, Polytechnic University, 2002--2004. -Use, modification, and distribution is subject to 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) - - - diff --git a/minmax/example/Jamfile b/minmax/example/Jamfile deleted file mode 100644 index 6cb2e55..0000000 --- a/minmax/example/Jamfile +++ /dev/null @@ -1,14 +0,0 @@ -# Boost.Minmax Library Example Jamfile -# -# Copyright (C) 2002--2004, Herve Bronnimann -# -# Use, modification, and distribution is subject to 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) -# - -subproject libs/algorithm/minmax/example ; - -exe minmax_ex : minmax_ex.cpp ; -exe minmax_timer : minmax_timer.cpp ; - diff --git a/minmax/example/minmax_ex.cpp b/minmax/example/minmax_ex.cpp deleted file mode 100644 index d806709..0000000 --- a/minmax/example/minmax_ex.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// (C) Copyright Herve Bronnimann 2004. -// Use, modification and distribution are subject to 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) - -#include -#include -#include -#include -#include - -#include -#include - -int main() -{ - using namespace std; - - // Demonstrating minmax() - boost::tuple result1 = boost::minmax(1, 0); - assert( result1.get<0>() == 0 ); - assert( result1.get<1>() == 1 ); - - - // Demonstrating minmax_element() - list L; - typedef list::const_iterator iterator; - generate_n(front_inserter(L), 1000, rand); - pair< iterator, iterator > result2 = boost::minmax_element(L.begin(), L.end()); - - cout << "The smallest element is " << *(result2.first) << endl; - cout << "The largest element is " << *(result2.second) << endl; - - assert( result2.first == std::min_element(L.begin(), L.end()) ); - assert( result2.second == std::max_element(L.begin(), L.end()) ); -} diff --git a/minmax/example/minmax_timer.cpp b/minmax/example/minmax_timer.cpp deleted file mode 100644 index 0ab51a8..0000000 --- a/minmax/example/minmax_timer.cpp +++ /dev/null @@ -1,212 +0,0 @@ -// (C) Copyright Herve Bronnimann 2004. -// Use, modification and distribution are subject to 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) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -// What's the proper BOOST_ flag for vs -#include - -#include -#include - -template -void tie(std::pair p, T1& min, T2& max) -{ - min = p.first; max = p.second; -} - -template -struct less_count : std::less { - less_count(less_count const& lc) : _M_counter(lc._M_counter) {} - less_count(int& counter) : _M_counter(counter) {} - bool operator()(Value const& a, Value const& b) const { - ++_M_counter; - return std::less::operator()(a,b); - } - void reset() { - _M_counter = 0; - } -private: - int& _M_counter; -}; - -inline int opt_min_count(int n) { - return (n==0) ? 0 : n-1; -} -inline int opt_minmax_count(int n) { - if (n < 2) return 0; - if (n == 2) return 1; - return (n%2 == 0) ? 3*(n/2)-1 : 3*(n/2)+1; -} -inline int opt_boost_minmax_count(int n) { - if (n < 2) return 0; - if (n == 2) return 1; - return (n%2 == 0) ? 3*(n/2)-2 : 3*(n/2); -} - -int repeats = 10; - -#define TIMER( n, cmd , cmdname ) \ - t.restart(); \ - for (int i=0; i -void test_minmax_element(CIterator first, CIterator last, int n, char* name) -{ - typedef typename std::iterator_traits::value_type vtype; - boost::timer t; - - std::cout << " ON " << name << " WITH OPERATOR<()\n"; - TIMER( n, std::min_element(first, last), - "std::min_element" << name << ""); - TIMER( n, std::max_element(first, last), - "std::max_element" << name << ""); - TIMER( n, boost::first_min_element(first, last), - "boost::first_min_element" << name << ""); - TIMER( n, boost::last_min_element(first, last), - "boost::last_min_element" << name << " "); - TIMER( n, boost::first_max_element(first, last), - "boost::first_max_element" << name << ""); - TIMER( n, boost::last_max_element(first, last), - "boost::last_max_element" << name << " "); - TIMER( n, boost::minmax_element(first, last), - "boost::minmax_element" << name << " "); - TIMER( n, boost::first_min_last_max_element(first, last), - "boost::first_min_last_max_element" << name << ""); - TIMER( n, boost::last_min_first_max_element(first, last), - "boost::last_min_first_max_element" << name << ""); - TIMER( n, boost::last_min_last_max_element(first, last), - "boost::last_min_last_max_element" << name << " "); - - #define pred std::bind2nd( std::greater(), vtype(10) ) - TIMER( n, boost::min_element_if(first, last, pred), - "boost::min_element_if" << name << ""); - TIMER( n, boost::max_element_if(first, last, pred), - "boost::max_element_if" << name << ""); - TIMER( n, std::min_element(boost::make_filter_iterator(first, last, pred), - boost::make_filter_iterator(last, last, pred)), - "std::min_element_with_filter_iterator" << name << ""); - TIMER( n, std::max_element(boost::make_filter_iterator(first, last, pred), - boost::make_filter_iterator(last, last, pred)), - "std::max_element_if_with_filter_iterator" << name << ""); - #undef pred - - int counter = 0; - less_count lc(counter); - std::cout << " ON " << name << " WITH LESS<> AND COUNTING COMPARISONS\n"; - CTIMER( n, std::min_element(first, last, lc), - "std::min_element" << name << " ", - counter, opt_min_count(n) ); - CTIMER( n, std::max_element(first, last, lc), - "std::max_element" << name << " ", - counter, opt_min_count(n) ); - CTIMER( n, boost::first_min_element(first, last, lc), - "boost::first_min_element" << name << "", - counter, opt_min_count(n) ); - CTIMER( n, boost::last_min_element(first, last, lc), - "boost::last_max_element" << name << " ", - counter, opt_min_count(n) ); - CTIMER( n, boost::first_max_element(first, last, lc), - "boost::first_min_element" << name << "", - counter, opt_min_count(n) ); - CTIMER( n, boost::last_max_element(first, last, lc), - "boost::last_max_element" << name << " ", - counter, opt_min_count(n) ); - CTIMER( n, boost::minmax_element(first, last, lc), - "boost::minmax_element" << name << " ", - counter, opt_minmax_count(n) ); - CTIMER( n, boost::first_min_last_max_element(first, last, lc), - "boost::first_min_last_max_element" << name << "", - counter, opt_boost_minmax_count(n) ); - CTIMER( n, boost::last_min_first_max_element(first, last, lc), - "boost::last_min_first_max_element" << name << "", - counter, opt_boost_minmax_count(n) ); - CTIMER( n, boost::last_min_last_max_element(first, last, lc), - "boost::last_min_last_max_element" << name << " ", - counter, opt_minmax_count(n) ); -} - -template -void test_container(Iterator first, Iterator last, int n, char* name) -{ - Container c(first, last); - typename Container::iterator fit(c.begin()), lit(c.end()); - test_minmax_element(fit, lit, n, name); -} - -template -void test_range(Iterator first, Iterator last, int n) -{ - typedef typename std::iterator_traits::value_type Value; - // Test various containers with these values - test_container< std::vector, Iterator, Value >(first, last, n, ""); -#ifndef ONLY_VECTOR - test_container< std::list, Iterator, Value >(first, last, n, " "); - test_container< std::multiset, Iterator, Value >(first, last, n, " "); -#endif -} - -template -void test(int n) -{ - // Populate test vector with identical values - std::cout << "IDENTICAL VALUES... \n"; - std::vector test_vector(n, Value(1)); - typename std::vector::iterator first( test_vector.begin() ); - typename std::vector::iterator last( test_vector.end() ); - test_range(first, last, n); - - // Populate test vector with two values - std::cout << "TWO DISTINCT VALUES...\n"; - typename std::vector::iterator middle( first + n/2 ); - std::fill(middle, last, Value(2)); - test_range(first, last, n); - - // Populate test vector with increasing values - std::cout << "INCREASING VALUES... \n"; - std::fill(first, last, Value(1)); - std::accumulate(first, last, Value(0)); - test_range(first, last, n); - - // Populate test vector with decreasing values - std::cout << "DECREASING VALUES... \n"; - std::reverse(first, last); - test_range(first, last, n); - - // Populate test vector with random values - std::cout << "RANDOM VALUES... \n"; - std::random_shuffle(first, last); - test_range(first, last, n); -} - -int -main(char argc, char** argv) -{ - int n = 100; - if (argc > 1) n = atoi(argv[1]); - if (argc > 2) repeats = atoi(argv[2]); - - test(n); - - return 0; -} diff --git a/minmax/index.html b/minmax/index.html deleted file mode 100644 index c57d37d..0000000 --- a/minmax/index.html +++ /dev/null @@ -1,528 +0,0 @@ - - - - - - - - - Boost Minmax library - - - -

Header <boost/algorithm/minmax.hpp>

- - - -Motivation
-Synopsis
-Function templates description
-Definition
-Requirements on types
-Preconditions
-Postconditions
-Complexity
-Example
-Notes
-Rationale
-Note about performance
-Acknowledgements -
-
- - - -

-Motivation

- -

The minmax library is composed of two headers, <boost/algorithm/minmax.hpp> -and <boost/algorithm/minmax_element.hpp>. -(See rationale.) -The problem solved by this library is that simultaneous min and max -computation requires -only one comparison, but using std::min and std::max -forces two comparisons. Worse, to compute the minimum and -maximum elements of a range of n elements requires only -3n/2+1 comparisons, instead of the 2n (in two passes) -forced by std::min_element and std::max_element. -I always thought it is a waste to have to call two functions to compute the -extent of a range, performing two passes over the input, when one should -be enough. The present library solves both problems.

- -

The first file implements the function templates -minmax -as straightforward extensions of the C++ -standard. As it returns a pair of const&, we must use the Boost.tuple library to construct such -pairs. (Please note: the intent is not to fix the known defaults of -std::min -and std::max, but to add one more algorithms that combines both; see the -rationale.)

- -

The second file implements the function templates -minmax_element. In a -second part, it also proposes variants that can usually not be computed by -the minmax algorithm, and which are more flexible in case some elements are equal. -Those variants could have been also provided with policy-based design, -but I ruled against that (see rationale). -

- -

If you are interested about -performance, -you will see that minmax_element is just slightly less efficient -than a single min_element or max_element, and thus -twice as efficient as two separate calls to min_element and -max_element. From a -theoretical standpoint, -all the minmax_element functions perform at most -3n/2+1 -comparisons and exactly n increments of the -ForwardIterator.

- - - -

-Synopsis of <boost/algorithm/minmax.hpp>

- -
#include <boost/tuple/tuple.hpp>
-
-namespace boost {
-
-  template <class T>
-  tuple<T const&, T const&> >
-  minmax(const T& a, const T& b);
-
-  template <class T, class BinaryPredicate>
-  tuple<T const&, T const&> >
-  minmax(const T& a, const T& b, BinaryPredicate comp);
-
-}
-
- -

-Synopsis of <boost/algorithm/minmax_element.hpp>

- -
#include <utility> // for std::pair
-
-namespace boost {
-
-  template <class ForwardIterator>
-  std::pair<ForwardIterator,ForwardIterator>
-  minmax_element(ForwardIterator first, ForwardIterator last);
-
-  template <class ForwardIterator, class BinaryPredicate>
-  std::pair<ForwardIterator,ForwardIterator>
-  minmax_element(ForwardIterator first, ForwardIterator last,
-                 BinaryPredicate comp);
-
-}
-
- -In addition, there are a bunch of extensions which specify -which element(s) you want to pick in case of equal elements. They are: - -I won't bore you with the complete synopsis, they have exactly the same -declaration as their corresponding _element function. Still, -you can find the complete synopsis here. - - - -

-Function templates description

-The minmax algorithm returns a pair p containing either -(a,b) -or (b,a), such that p.first<p.second in the first version, -or comp(p.first,p.second) in the second version. If the elements -are equivalent, the pair (a,b) is returned.
[1] -

The minmax_element is semantically equivalent to first_min_first_max_element. -

First_min_element and first_max_element find the smallest -and largest elements in the range [first, last). If there are -several instance of these elements, the first one is returned. They are -identical to -std::min_element and std::max_elementand -are only included in this library for symmetry. -

Last_min_element and last_max_element find the smallest -and largest elements in the range [first, last). They are almost -identical to -std::min_element and std::max_element, except -that they return the last instance of the largest element (and not the -first, as first_min_element and last_max_element would). -

The family of algorithms comprising first_min_first_max_element, -first_min_first_max_element, -first_min_first_max_element, -and first_min_first_max_element can be described generically as -follows (using which and -what for first -or last): which_min_what_max_element finds -the (first or last, according to which) smallest element -and the (first or last, according to what) largest element -in the range -[first, last). The first version is semantically -equivalent to: -

  std::make_pair(boost::which_min_element(first,last),
-                 boost::what_max_element(first,last)),
-and the second version to: -
  std::make_pair(boost::which_min_element(first,last,comp),
-                 boost::what_max_element(first,last,comp)).
- -


Note: the first_min_last_max_element can also be described -as finding the first and last elements in the range if it were stably sorted. - - - -

-Definition

-Defined in minmax.hpp -and -in minmax_element.hpp. - - - -

-Requirements on types

-For minmax, T must be a model of
LessThan -Comparable. -

For all the other function templates, versions with two template parameters: -

-For the versions with three template parameters: - - - - -

-Preconditions

- - -
- - -

-Postconditions

-In addition to the semantic description above. for minmax_element -and all the which_min_what_max_element -variants, the return value is -last or std::make_pair(last,last) -if and only if [first, last) is an empty range. Otherwise, the -return value or both members of the resulting pair are iterators in the -range -[first, last). -
- - -

-Complexity

-Minmax performs a single comparison and is otherwise of constant complexity. -The use of boost::tuple<T const&> prevents copy -constructors in case the arguments are passed by reference. -

The complexity of all the other algorithms is linear. They all perform -exactly n increment operations, and zero comparisons if [first,last) -is empty, otherwise : -

-where n is the number of elements in [first,last). - - - -

-Example

-This example is included in the distribution in the examples section of -the library under -
minmax_ex.cpp. - -
int main()
-{
-  using namespace std;
-  boost::tuple<int const&, int const&> result1 = boost::minmax(1, 0);
-
-  assert( result1.get<0>() == 0 );
-  assert( result1.get<1>() == 1 );
-
-  list<int> L;
-  generate_n(front_inserter(L), 1000, rand);
-
-  typedef list<int>::const_iterator iterator;
-  pair< iterator, iterator > result2 = boost::minmax_element(L.begin(), L.end());
-  cout << "The smallest element is " << *(result2.first) << endl;
-  cout << "The largest element is  " << *(result2.second) << endl;
-
-  assert( result2.first  == std::min_element(L.begin(), L.end());
-  assert( result2.second == std::max_element(L.begin(), L.end());
-}
- - - -

-Notes

-
[1] We do not support -idioms such as tie(a,b)=minmax(a,b) -to order two elements a, b, although this would have -the desired effect if we returned a reference instead of a constant -reference. The reason is that two unnecessary assignments are -performed if a and b are in order. It is better to stick to if (b<a) -swap(a,b) to achieve that effect. -

[2] These algorithms always -perform at least 3n/2-2 comparisons, which is a lower bound on -the number of comparisons in any case (Cormen, Leiserson, Rivest: "Introduction -to Algorithms", section 9.1, Exercise 9.1-). The algorithms essentially compare -the elements in pairs, performing 1 comparison for the first two elements, -then 3 comparisons for each remaining pair of elements (one to order the -elements and one for updating each the minimum and and the maximum). When -the number of elements is odd, the last one needs to be compared to the -current minimum and also to the current maximum. In addition, for minmax, -in cases where equality of the two members in the pair could occur, and -the update stores the second, we save the first to check at the end if -the update should have stored the first (in case of equality). It's hard -to predict if the last comparison is performed or not, hence the at most -in both cases. -

[3] These algorithms always -perform at least 3n/2-2 comparisons, which is a lower bound on -the number of comparisons in any case. The method is the same as in note -[2] -above, and like above, when the number of elements is odd, the last one -needs to be compared to the current minimum and also to the current maximum. -We can avoid the latter comparison if the former is successful, hence the -at -most instead of exactly in the odd case. - - - -

-Rationale:

- - -

Why not a single header &boost/algorithm/minmax.hpp>?

-

This was the design originally proposed and approved in the formal -review. As the need for Boost.tuple became clear (due to the limitations -of std::pair), it became also annoying to require another -library for minmax_element which does not need it. Hence the -separation into two header files.

- -
-

Your minmax suffers from the same problems as std::min and -std::max.

-

I am aware of the problems with std::min and -std::max, and all the debate that has been going on (please consult -Alexandrescu's -paper and the links therein). But I don't see the purpose of this -library as fixing something that is part of the C++ standard. I humbly -think it's beyond the scope of this library. Rather, I am -following the way of the standard in simply providing one more function -of the same family. If someone else wants to fix std::min, their fix -would probably apply to boost::minmax as well.

- - -

Why no min/max_element_if?

-

In a first version of the library, I proposed _if versions of -all the algorithms (well, not all, because that would be too much). -However, there is simply no reason to do so, and all the versions I had -were just as fast implemented using the excellent -<boost/iterator_adaptors.hpp> library. Namely, a call to -min_element_if(first, last, pred) would be just as well -implemented by: -

-     // equivalent to min_element_if(first, last, pred)
-     min_element(boost::make_filter_iterator(first, last, pred),
-                 boost::make_filter_iterator(last, last, pred));
-
-Arguably, the min_element_if version is somewhat shorter, but -the overhead of iterator adaptors is not large, and they get rid of a -lot of code (think of all the combinations between first/last and -doubling them with _if variants!).

- -

Discussion: about std::max_element

-

This rationale is somewhat historical, but explains why there are all -these first/last_min/max_element functions.

-

The C++ standard mandates that std::min_element and std::max_element -return the first instance of the smallest and largest elements (as opposed -to, say, the last). This arbitrary choice has some consistency: In the -case of v of type vector<int>, for instance, it is true that std::min_element(v.begin(),v.end(),std::less<int>()) -== std::max_element(v.begin(),v.end(),std::greater<int>()). -

There is of course nothing wrong with this: it's simply a matter of -choice. Yet another way to specify min_element and max_element is to define -them as the first and the last elements if the range was stably sorted. -(The stable sort is necessary to disambiguate between iterators -that have the same value.) In that case, min should return the first instance -and max should return the last. Then, both functions are related by -reverse_iterator(std::first_min_element(v.begin(),v.end(),std::less<int>())) -== -std::last_max_element(v.rbegin(),v.rend(),std::greater<int>()). -This definition is subtly different from the previous one.

-

The definition problem surfaces when one tries to design a minmax_element, -using the procedure proposed in (Cormen, Leiserson, Rivest: "Introduction -to Algorithms", section 9.1). It should be possible to derive an -algorithm using only 3n/2 comparisons if [first,last) has -n -elements, but if one tries to write a function called first_min_first_max_element() -which returns both std::min_element and std::max_element -in a pair, the trivial implementation does not work. The problem, rather -subtly, is about equal elements: I had to think for a while to find a -way to perform only three -comparisons per pair and return the first min and first max elements. -For a long time, it seemed any -attempts at doing so would consume four comparisons per pair in the worst -case. This implementation achieves three.

-

It is not possible (or even desirable) to change the meaning of -max_element, -but it is still beneficial to provide a function called minmax_element, -which returns a pair of min_element and max_element. -Although it is easy enough to call min_element and max_element, -this performs -2(n-1) comparisons, and necessitates two -passes over the input. In contrast, -minmax_element will perform -the fewer comparisons and perform a single pass over the input. -The savings can be significant when the iterator type is not a raw pointer, -or even is just a model of the InputIterator concept (although in that -case the interface would have to be -changed, as the return type could not be copied, so one could e.g. -return a value).

-

In order to benefit from all the variants of the algorithm, I propose -to introduce both first_min_element and last_min_element, -and their counterparts first_max_element and last_max_element. -Then I also propose all the variants algorithms: first_min_last_max_element -and last_min_first_max_element, which perform only at most 3n/2 -comparisons, and only a single pass on the input. In fact, it can be proven -that computing minmax requires at least 3(n/2)-2 comparisons in -any instance of the problem (Cormen, Leiserson, Rivest, 2nd edition, section -9.1). The implementation I give does not perform unnecessary comparisons -(whose result could have been computed by transitivity from previous -comparisons).

-

It appears that first_min_last_max_element may be just a tad -slower than -first_min_element alone, still much less than first_min_element -and -last_max_element called separately. [2] - -

Why algorithms and not accumulators?

-

The minmax algorithms are useful in computing the extent of a range. -In computer graphics, we need a bounding box of a set of objects. -In that case the need for a single pass is even more stringent -as all three directions must be done at once. Food for thoughts: there -is matter for a nice generic programming library with stackable update_min -and update_max function objects which store a reference to the -min_resultand -max_result variables, in conjunction with the for_each -algorithm).

-

I believe many standard sequential algorithms could be reformulated -with accumulators (and many others, such as in statistics, expectation / -variance / etc.). It seems that there is room for another library, but I -do not see it competing with minmax, rather extending several algorithms -(including minmax) to the accumulator framework. However, I felt it is -beyond the scope of this library to provide such accumulators.

- - -

This first/last is a perfect application for a policy-based -design.

-

True, and I could have gone that way, with the default policy for -min_element and max_element to pick the first -occurence of the result. This would have thinned the number of -combinations of the minmax_element variants. But it would also have -meant to change the interface of boost::minmax_element. -One of the goals of the minmax_element algorithm is its -eventual addition to the C++ standard, in connection with -std::min_element and std::max_element -(and I feel that it would be quite natural -given the shortness of the implementation, and the not quite trivial -detail which is needed to get it right). So changing the interface by -adding policies would have meant unfortunately to depart from the -standard and created an obstacle towards that goal. Besides, the code -remains rather readable and simple without policies. So I am quite happy -to keep it like this. -

- - - -

About performance

- - - -

-Acknowledgements

-My students in CS903 (Polytechnic Univ.,
http://photon.poly.edu/~hbr/cs903/) -who had minmax_element as an assignment helped clarify the issues, -and also come up with the optimum number of comparisons for first_min_last_max_element. -The identification of the issue surrounding max_element is solely -my own. -

One minmax_element implementation, which performs 3(n/2)+O(log -n) comparisons on the average when the elements are random_shuffled, -was suggested by my student Marc Glisse. The current one, which performs -3(n/2)+1 -comparisons in the worst case, was suggested by John Iacono.

-

Finally, Matthew Wilson and Jeremy Siek contributed pre-review -comments, while Gennadiy Rozental, John Maddock, Craig Henderson, Gary -Powell participated in the review of the library, managed by Thomas -Witt. In particular, Gennadiy suggested a factorization of the code; -while I haven't followed it all the way, his suggestions do make the -code more readable and still work with older compilers. -Late after the review, as I finally scrounged to add the library for a -release, Eric Niebler noted the bad behavior of std::pair for -minmax and suggested to use Boost.tuple instead. -All my thanks for the excellent advice and reviews from all. -

-See also

-min, max, -min_element, -max_element, -LessThan -Comparable, -sort, -nth_element -. -
-
Last modified 2004-07-01 -

© Copyright Hervé -Brönnimann, Polytechnic University, 2002--2004. -Use, modification, and distribution is subject to 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) - - - diff --git a/minmax/test/Jamfile b/minmax/test/Jamfile deleted file mode 100644 index 1a4e85b..0000000 --- a/minmax/test/Jamfile +++ /dev/null @@ -1,33 +0,0 @@ -# Boost.Minmax Library Test Jamfile -# -# Copyright (C) 2002--2004, Herve Bronnimann -# -# Use, modification, and distribution is subject to 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) -# - -subproject libs/algorithm/minmax/test ; - -# bring in rules for testing -import testing ; - -# Make tests run by default. -DEPENDS all : test ; - -{ - test-suite algorithm/minmax - : [ run - minmax_element_test.cpp - : : - : - : minmax_element - ] - [ run - minmax_test.cpp - : : - : - : minmax - ] - ; -} diff --git a/minmax/test/Jamfile.v2 b/minmax/test/Jamfile.v2 deleted file mode 100644 index 24ae612..0000000 --- a/minmax/test/Jamfile.v2 +++ /dev/null @@ -1,20 +0,0 @@ -# Boost.Minmax Library test Jamfile -# -# Copyright (C) 2002--2004, Herve Bronnimann -# -# Use, modification, and distribution is subject to 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) -# - -import testing ; - -{ - test-suite algorithm/minmax: - : [ run minmax_element_test.cpp - : : : : minmax_element ] - [ run minmax_test.cpp - : : : : minmax ] - ; -} - diff --git a/minmax/test/minmax_element_test.cpp b/minmax/test/minmax_element_test.cpp deleted file mode 100644 index 8758f12..0000000 --- a/minmax/test/minmax_element_test.cpp +++ /dev/null @@ -1,241 +0,0 @@ -// (C) Copyright Herve Bronnimann 2004. -// Use, modification and distribution are subject to 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) - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include /* prevents some nasty warns in MSVC */ -#include -#include -#include - -class custom { - int m_x; - friend bool operator<(custom const& x, custom const& y); -public: - explicit custom(int x = 0) : m_x(x) {} - custom(custom const& y) : m_x(y.m_x) {} - custom operator+(custom const& y) const { return custom(m_x+y.m_x); } - custom& operator+=(custom const& y) { m_x += y.m_x; return *this; } -}; - -bool operator< (custom const& x, custom const& y) -{ - return x.m_x < y.m_x; -} - -BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(custom) - -namespace std { - -template <> -struct iterator_traits { - typedef random_access_iterator_tag iterator_category; - typedef int value_type; - typedef ptrdiff_t difference_type; - typedef value_type* pointer; - typedef value_type& reference; -}; - -template <> -struct iterator_traits { - typedef random_access_iterator_tag iterator_category; - typedef custom value_type; - typedef ptrdiff_t difference_type; - typedef value_type* pointer; - typedef value_type& reference; -}; - -} - -template -void tie(std::pair p, T3& first, T4& second) -{ - first = T3(p.first); second = T4(p.second); -} - -template -struct less_count : std::less { - typedef std::less Base; - less_count(less_count const& lc) : m_counter(lc.m_counter) {} - less_count(int& counter) : m_counter(counter) {} - bool operator()(Value const& a, Value const& b) const { - ++m_counter; - return Base::operator()(a,b); - } - void reset() { - m_counter = 0; - } -private: - int& m_counter; -}; - -inline int opt_min_count(int n) { - return (n==0) ? 0 : n-1; -} -inline int opt_minmax_count(int n) { - if (n < 2) return 0; - if (n == 2) return 2; - return (n%2 == 0) ? 3*(n/2)-1 : 3*(n/2)+1; -} -inline int opt_boost_minmax_count(int n) { - if (n < 2) return 0; - if (n == 2) return 1; - return (n%2 == 0) ? 3*(n/2)-2 : 3*(n/2); -} - -#define CHECK_EQUAL_ITERATORS( left, right, first ) \ -BOOST_CHECK_EQUAL( std::distance( first, left ), std::distance( first, right ) ) - -template -void test_minmax(CIterator first, CIterator last, int n) -{ - using namespace boost; - - typedef typename std::iterator_traits::value_type Value; - typedef boost::reverse_iterator RCIterator; - // assume that CIterator is BidirectionalIter - CIterator min, max; - RCIterator rfirst(last), rlast(first), rmin, rmax; - int counter = 0; - less_count lc(counter); - - // standard extensions - // first version, operator< - tie( boost::minmax_element(first, last), min, max ); - - CHECK_EQUAL_ITERATORS( min, std::min_element(first, last), first ); - CHECK_EQUAL_ITERATORS( max, std::max_element(first, last), first ); - - // second version, comp function object (keeps a counter!) - lc.reset(); - tie( boost::minmax_element(first, last, lc), min, max ); - BOOST_CHECK( counter <= opt_minmax_count(n) ); - CHECK_EQUAL_ITERATORS( min, std::min_element(first, last, lc), first ); - CHECK_EQUAL_ITERATORS( max, std::max_element(first, last, lc), first ); - - // boost extensions - // first version, operator< - CHECK_EQUAL_ITERATORS( boost::first_min_element(first, last), std::min_element(first, last), first ); - rmin = RCIterator(boost::last_min_element(first, last)); - rmin = (rmin == rfirst) ? rlast : --rmin; - CHECK_EQUAL_ITERATORS( rmin, std::min_element(rfirst, rlast), rfirst ); - CHECK_EQUAL_ITERATORS( boost::first_max_element(first, last), std::max_element(first, last), first ); - rmax = RCIterator(boost::last_max_element(first, last)); - rmax = (rmax == rfirst) ? rlast : --rmax; - CHECK_EQUAL_ITERATORS( rmax, std::max_element(rfirst, rlast), rfirst ); - tie( boost::first_min_last_max_element(first, last), min, max ); - CHECK_EQUAL_ITERATORS( min, boost::first_min_element(first, last), first ); - CHECK_EQUAL_ITERATORS( max, boost::last_max_element(first, last), first ); - tie( boost::last_min_first_max_element(first, last), min, max ); - CHECK_EQUAL_ITERATORS( min, boost::last_min_element(first, last), first ); - CHECK_EQUAL_ITERATORS( max, boost::first_max_element(first, last), first ); - tie( boost::last_min_last_max_element(first, last), min, max ); - CHECK_EQUAL_ITERATORS( min, boost::last_min_element(first, last), first ); - CHECK_EQUAL_ITERATORS( max, boost::last_max_element(first, last), first ); - - // second version, comp function object (keeps a counter!) - lc.reset(); - min = boost::first_min_element(first, last, lc); - BOOST_CHECK( counter <= opt_min_count(n) ); - CHECK_EQUAL_ITERATORS( min, std::min_element(first, last, lc), first ); - lc.reset(); - rmin = RCIterator(boost::last_min_element(first, last, lc)); - rmin = (rmin == rfirst) ? rlast : --rmin; - BOOST_CHECK( counter <= opt_min_count(n) ); - CHECK_EQUAL_ITERATORS( rmin, std::min_element(rfirst, rlast, lc), rfirst ); - lc.reset(); - max = boost::first_max_element(first, last, lc); - BOOST_CHECK( counter <= opt_min_count(n) ); - CHECK_EQUAL_ITERATORS( max, std::max_element(first, last, lc), first ); - lc.reset(); - rmax = RCIterator(boost::last_max_element(first, last, lc)); - rmax = (rmax == rfirst) ? rlast : --rmax; - BOOST_CHECK( counter <= opt_min_count(n) ); - CHECK_EQUAL_ITERATORS( rmax, std::max_element(rfirst, rlast, lc), rfirst ); - lc.reset(); - tie( boost::first_min_last_max_element(first, last, lc), min, max ); - BOOST_CHECK( counter <= opt_boost_minmax_count(n) ); - CHECK_EQUAL_ITERATORS( min, boost::first_min_element(first, last, lc), first ); - CHECK_EQUAL_ITERATORS( max, boost::last_max_element(first, last, lc), first ); - lc.reset(); - tie( boost::last_min_first_max_element(first, last, lc), min, max ); - BOOST_CHECK( counter <= opt_boost_minmax_count(n) ); - BOOST_CHECK( min == boost::last_min_element(first, last, lc) ); - CHECK_EQUAL_ITERATORS( max, boost::first_max_element(first, last, lc), first ); - lc.reset(); - tie( boost::last_min_last_max_element(first, last, lc), min, max ); - BOOST_CHECK( counter <= opt_minmax_count(n) ); - CHECK_EQUAL_ITERATORS( min, boost::last_min_element(first, last, lc), first ); - CHECK_EQUAL_ITERATORS( max, boost::last_max_element(first, last, lc), first ); -} - -template -void test_container(Iterator first, Iterator last, int n, - Container* dummy = 0 - BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Value) ) -{ - Container c(first, last); - test_minmax(c.begin(), c.end(), n); -} - -template -void test_range(Iterator first, Iterator last, int n) -{ - typedef typename std::iterator_traits::value_type Value; - // Test various containers with these values - test_container< std::vector, Iterator, Value >(first, last, n); - test_container< std::list, Iterator, Value >(first, last, n); - test_container< std::set, Iterator, Value >(first, last, n); -} - -template -void test(int n BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Value)) -{ - // Populate test vector with identical values - std::vector test_vector(n, Value(1)); - typename std::vector::iterator first( test_vector.begin() ); - typename std::vector::iterator last( test_vector.end() ); - test_range(first, last, n); - - // Populate test vector with two values - typename std::vector::iterator middle( first + n/2 ); - std::fill(middle, last, Value(2)); - test_range(first, last, n); - - // Populate test vector with increasing values - std::accumulate(first, last, Value(0)); - test_range(first, last, n); - - // Populate test vector with decreasing values - std::reverse(first, last); - test_range(first, last, n); - - // Populate test vector with random values - std::random_shuffle(first, last); - test_range(first, last, n); -} - -int test_main( int argc, char* argv[] ) -{ -#ifndef BOOST_NO_STDC_NAMESPACE - using std::atoi; -#endif - - int n = 100; - if (argc > 1) n = atoi(argv[1]); - - test(n); - test(n); - - return 0; -} diff --git a/minmax/test/minmax_test.cpp b/minmax/test/minmax_test.cpp deleted file mode 100644 index 6e8bd60..0000000 --- a/minmax/test/minmax_test.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// (C) Copyright Herve Bronnimann 2004. -// Use, modification and distribution are subject to 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) - -#include -#include - -#include -#include -#include - -class custom { - int m_x; - friend std::ostream& operator<<(std::ostream& str, custom const& x); -public: - explicit custom(int x = 0) : m_x(x) {} - custom(custom const& y) : m_x(y.m_x) {} - bool operator==(custom const& y) const { return m_x == y.m_x; } - bool operator<(custom const& y) const { return m_x < y.m_x; } - custom operator+(custom const& y) const { return custom(m_x+y.m_x); } - custom& operator+=(custom const& y) { m_x += y.m_x; return *this; } -}; - -std::ostream& -operator<<(std::ostream& str, custom const& x) -{ - return str << x.m_x; -} - -template -struct less_count : std::less { - typedef std::less Base; - less_count(less_count const& lc) : m_counter(lc.m_counter) {} - less_count(int& counter) : m_counter(counter) {} - bool operator()(Value const& a, Value const& b) const { - ++m_counter; - return Base::operator()(a,b); - } - void reset() { - m_counter = 0; - } -private: - int& m_counter; -}; - -using namespace boost; - -template -void test(BOOST_EXPLICIT_TEMPLATE_TYPE(Value)) -{ - Value zero(0), one(1); - int counter = 0; - less_count lc(counter); - - // Test functionality - tuple result1 = minmax(zero, one); - BOOST_CHECK_EQUAL( get<0>(result1), zero ); - BOOST_CHECK_EQUAL( get<1>(result1), one ); - - tuple result2 = minmax(one, zero); - BOOST_CHECK_EQUAL( get<0>(result2), zero ); - BOOST_CHECK_EQUAL( get<1>(result2), one ); - - // Test functionality and number of comparisons - lc.reset(); - tuple result3 = minmax(zero, one, lc ); - BOOST_CHECK_EQUAL( get<0>(result3), zero ); - BOOST_CHECK_EQUAL( get<1>(result3), one ); - BOOST_CHECK_EQUAL( counter, 1 ); - - lc.reset(); - tuple result4 = minmax(one, zero, lc ); - BOOST_CHECK_EQUAL( get<0>(result4), zero ); - BOOST_CHECK_EQUAL( get<1>(result4), one ); - BOOST_CHECK_EQUAL( counter, 1); -} - -int test_main( int , char* [] ) -{ - test(); // ("builtin"); - test(); // ("custom "); - - return 0; -} diff --git a/string/doc/Jamfile.v2 b/string/doc/Jamfile.v2 deleted file mode 100644 index 2c2c96e..0000000 --- a/string/doc/Jamfile.v2 +++ /dev/null @@ -1,52 +0,0 @@ -# Boost string_algo library documentation Jamfile --------------------------------- -# -# Copyright Pavol Droba 2002-2003. Use, modification and -# distribution is subject to 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) -# -# See http://www.boost.org for updates, documentation, and revision history. - -import toolset ; -toolset.using doxygen ; - -boostbook string_algo : string_algo.xml ; - -doxygen autodoc - : - [ glob ../../../../boost/algorithm/string.hpp ] - [ glob ../../../../boost/algorithm/string_regex.hpp ] - - [ glob ../../../../boost/algorithm/string/classification.hpp ] - [ glob ../../../../boost/algorithm/string/iterator_range.hpp ] - [ glob ../../../../boost/algorithm/string/sequence_traits.hpp ] - [ glob ../../../../boost/algorithm/string/std_containers_traits.hpp ] - [ glob ../../../../boost/algorithm/string/concept.hpp ] - [ glob ../../../../boost/algorithm/string/compare.hpp ] - [ glob ../../../../boost/algorithm/string/constants.hpp ] - [ glob ../../../../boost/algorithm/string/case_conv.hpp ] - [ glob ../../../../boost/algorithm/string/find.hpp ] - [ glob ../../../../boost/algorithm/string/finder.hpp ] - [ glob ../../../../boost/algorithm/string/find_iterator.hpp ] - [ glob ../../../../boost/algorithm/string/trim.hpp ] - [ glob ../../../../boost/algorithm/string/predicate.hpp ] - [ glob ../../../../boost/algorithm/string/split.hpp ] - [ glob ../../../../boost/algorithm/string/erase.hpp ] - [ glob ../../../../boost/algorithm/string/replace.hpp ] - [ glob ../../../../boost/algorithm/string/find_format.hpp ] - [ glob ../../../../boost/algorithm/string/formatter.hpp ] - [ glob ../../../../boost/algorithm/string/regex.hpp ] - [ glob ../../../../boost/algorithm/string/regex_find_format.hpp ] - : - HIDE_UNDOC_MEMBERS=YES - EXTRACT_PRIVATE=NO - ENABLE_PREPROCESSING=YES - MACRO_EXPANSION=YES - EXPAND_ONLY_PREDEF=YES - SEARCH_INCLUDES=YES - PREDEFINED="BOOST_STRING_TYPENAME=typename \"BOOST_STATIC_CONSTANT(type,var)=static const type var;\"" - ; - - - - diff --git a/string/doc/concept.xml b/string/doc/concept.xml deleted file mode 100644 index b615ead..0000000 --- a/string/doc/concept.xml +++ /dev/null @@ -1,199 +0,0 @@ - - -

- Concepts - - - - -
- Definitions - - - Notation - - - - F - A type that is a model of Finder - - - Fmt - A type that is a model of Formatter - - - Iter - - Iterator Type - - - - f - Object of type F - - - fmt - Object of type Fmt - - - i,j - Objects of type Iter - - - -
-
- -
- Finder Concept - - - Finder is a functor which searches for an arbitrary part of a container. - The result of the search is given as an iterator_range - delimiting the selected part. - - - - Valid Expressions - - - - Expression - Return Type - Effects - - - - - f(i,j) - Convertible to iterator_range<Iter> - Perform the search on the interval [i,j) and returns the result of the search - - - -
- - - Various algorithms need to perform a search in a container and a Finder is a generalization of such - search operations that allows algorithms to abstract from searching. For instance, generic replace - algorithms can replace any part of the input, and the Finder is used to select the desired one. - - - Note, that it is only required that the finder works with a particular iterator type. However, - a Finder operation can be defined as a template, allowing the Finder to work with any iterator. - - - Examples - - - - - Finder implemented as a class. This Finder always returns the whole input as a match. operator() - is templated, so that the finder can be used on any iterator type. - - -struct simple_finder -{ - template<typename ForwardIteratorT> - boost::iterator_range<ForwardIterator> operator()( - ForwardIteratorT Begin, - ForwardIteratorT End ) - { - return boost::make_range( Begin, End ); - } -}; - - - - Function Finder. Finder can be any function object. That is, any ordinary function with the - required signature can be used as well. However, such a function can be used only for - a specific iterator type. - - -boost::iterator_range<std::string> simple_finder( - std::string::const_iterator Begin, - std::string::const_iterator End ) -{ - return boost::make_range( Begin, End ); -} - - - - -
-
- Formatter concept - - - Formatters are used by replace algorithms. - They are used in close combination with finders. - A formatter is a functor, which takes a result from a Finder operation and transforms it in a specific way. - The operation of the formatter can use additional information provided by a specific finder, - for example regex_formatter() uses the match information from - regex_finder() to format the result of formatter operation. - - - - Valid Expressions - - - - Expression - Return Type - Effects - - - - - fmt(f(i,j)) - A container type, accessible using container traits - Formats the result of the finder operation - - - -
- - - Similarly to finders, formatters generalize format operations. When a finder is used to - select a part of the input, formatter takes this selection and performs some formating - on it. Algorithms can abstract from formating using a formatter. - - - Examples - - - - - Formatter implemented as a class. This Formatter does not perform any formating and - returns the match, repackaged. operator() - is templated, so that the Formatter can be used on any Finder type. - - -struct simple_formatter -{ - template<typename FindResultT> - std::string operator()( const FindResultT& Match ) - { - std::string Temp( Match.begin(), Match.end() ); - return Temp; - } -}; - - - - Function Formatter. Similarly to Finder, Formatter can be any function object. - However, as a function, it can be used only with a specific Finder type. - - -std::string simple_formatter( boost::iterator_range<std::string::const_iterator>& Match ) -{ - std::string Temp( Match.begin(), Match.end() ); - return Temp; -} - - - - -
-
diff --git a/string/doc/credits.xml b/string/doc/credits.xml deleted file mode 100644 index ecc11e6..0000000 --- a/string/doc/credits.xml +++ /dev/null @@ -1,19 +0,0 @@ - - -
- Credits -
- Acknowledgments - - The author would like to thank everybody who gave suggestions and comments. Especially valuable - were the contributions of Thorsten Ottosen, Jeff Garland and the other boost members who participated - in the review process, namely David Abrahams, Daniel Frey, Beman Dawes, John Maddock, David B.Held, Pavel Vozenilek - and many other. - - - Additional thanks go to Stefan Slapeta and Toon Knapen, who have been very resourceful in solving various - portability issues. - -
-
diff --git a/string/doc/design.xml b/string/doc/design.xml deleted file mode 100644 index 2affb7a..0000000 --- a/string/doc/design.xml +++ /dev/null @@ -1,216 +0,0 @@ - - -
- Design Topics - - - - -
- String Representation - - - As the name suggest, this library works mainly with strings. However, in the context of this library, - a string is not restricted to any particular implementation (like std::basic_string), - rather it is a concept. This allows the algorithms in this library to be reused for any string type, - that satisfies the given requirements. - - - Definition: A string is a - range of characters accessible in sequential - ordered fashion. Character is any value type with "cheap" copying and assignment. - - - First requirement of string-type is that it must accessible using - Boost.Range. This facility allows to access - the elements inside the string in a uniform iterator-based fashion. - This is sufficient for our library - - - Second requirement defines the way in which the characters are stored in the string. Algorithms in - this library work with an assumption that copying a character is cheaper then allocating extra - storage to cache results. This is a natural assumption for common character types. Algorithms will - work even if this requirement is not satisfied, however at the cost of performance degradation. - - - In addition some algorithms have additional requirements on the string-type. Particularly, it is required - that an algorithm can create a new string of the given type. In this case, it is required that - the type satisfies the sequence (Std §23.1.1) requirements. - - - In the reference and also in the code, requirement on the string type is designated by the name of - template argument. RangeT means that the basic range requirements must hold. - SequenceT designates extended sequence requirements. - -
- -
- Sequence Traits - - - The major difference between std::list and std::vector is not in the interfaces - they provide, but rather in the inner details of the class and the way how it performs - various operations. The problem is that it is not possible to infer this difference from the - definitions of classes without some special mechanism. - However, some algorithms can run significantly faster with the knowledge of the properties - of a particular container. - - - Sequence traits allow one to specify additional properties of a sequence container (see Std.§32.2). - These properties are then used by algorithms to select optimized handling for some operations. - The sequence traits are declared in the header - boost/algorithm/string/sequence_traits.hpp. - - - - In the table C denotes a container and c is an object of C. - - - Sequence Traits - - - - Trait - Description - - - - - has_native_replace<C>::value - Specifies that the sequence has std::string like replace method - - - has_stable_iterators<C>::value - - Specifies that the sequence has stable iterators. It means, - that operations like insert/erase/replace - do not invalidate iterators. - - - - has_const_time_insert<C>::value - - Specifies that the insert method of the sequence has - constant time complexity. - - - - has_const_time_erase<C>::value - - Specifies that the erase method of the sequence has constant time complexity - - - - -
- - - Current implementation contains specializations for std::list<T> and - std::basic_string<T> from the standard library and SGI's std::rope<T> and std::slist<T>. - -
-
- Find Algorithms - - - Find algorithms have similar functionality to std::search() algorithm. They provide a different - interface which is more suitable for common string operations. - Instead of returning just the start of matching subsequence they return a range which is necessary - when the length of the matching subsequence is not known beforehand. - This feature also allows a partitioning of the input sequence into three - parts: a prefix, a substring and a suffix. - - - Another difference is an addition of various searching methods besides find_first, including find_regex. - - - It the library, find algorithms are implemented in terms of - Finders. Finders are used also by other facilities - (replace,split). - For convenience, there are also function wrappers for these finders to simplify find operations. - - - Currently the library contains only naive implementation of find algorithms with complexity - O(n * m) where n is the size of the input sequence and m is the size of the search sequence. - There are algorithms with complexity O(n), but for smaller sequence a constant overhead is - rather big. For small m << n (m by magnitude smaller than n) the current implementation - provides acceptable efficiency. - Even the C++ standard defines the required complexity for search algorithm as O(n * m). - It is possible that a future version of library will also contain algorithms with linear - complexity as an option - -
-
- Replace Algorithms - - - The implementation of replace algorithms follows the layered structure of the library. The - lower layer implements generic substitution of a range in the input sequence. - This layer takes a Finder object and a - Formatter object as an input. These two - functors define what to replace and what to replace it with. The upper layer functions - are just wrapping calls to the lower layer. Finders are shared with the find and split facility. - - - As usual, the implementation of the lower layer is designed to work with a generic sequence while - taking advantage of specific features if possible - (by using Sequence traits) - -
-
- Find Iterators & Split Algorithms - - - Find iterators are a logical extension of the find facility. - Instead of searching for one match, the whole input can be iteratively searched for multiple matches. - The result of the search is then used to partition the input. It depends on the algorithms which parts - are returned as the result. They can be the matching parts (find_iterator) of the parts in - between (split_iterator). - - - In addition the split algorithms like find_all() and split() - can simplify the common operations. They use a find iterator to search the whole input and copy the - matches they found into the supplied container. - -
-
- Exception Safety - - - The library requires that all operations on types used as template - or function arguments provide the basic exception-safety guarantee. - In turn, all functions and algorithms in this library, except where stated - otherwise, will provide the basic exception-safety guarantee. - In other words: - The library maintains its invariants and does not leak resources in - the face of exceptions. Some library operations give stronger - guarantees, which are documented on an individual basis. - - - - Some functions can provide the strong exception-safety guarantee. - That means that following statements are true: - - - If an exception is thrown, there are no effects other than those - of the function - - - If an exception is thrown other than by the function, there are no effects - - - This guarantee can be provided under the condition that the operations - on the types used for arguments for these functions either - provide the strong exception guarantee or do not alter the global state . - - - In the reference, under the term strong exception-safety guarantee, we mean the - guarantee as defined above. - - - For more information about the exception safety topics, follow this - link - -
-
diff --git a/string/doc/environment.xml b/string/doc/environment.xml deleted file mode 100644 index aec08e4..0000000 --- a/string/doc/environment.xml +++ /dev/null @@ -1,59 +0,0 @@ - - -
- Environment -
- Build - - The whole library is provided in headers. Regex variants of some algorithms, - however, are dependent on the Boost.Regex library. All such algorithms are - separated in boost/algorithm/string_regex.hpp. - If this header is used, the application must be linked with the Boost.Regex - library. - -
- -
- Examples - - Examples showing the basic usage of the library can be found in the libs/algorithm/string/example - directory. There is a separate file for the each part of the library. Please follow the boost - build guidelines to build examples using the bjam. To successfully build regex examples - the Boost.Regex library is required. - -
- -
- Tests - - A full set of test cases for the library is located in the libs/algorithm/string/test directory. - The test cases can be executed using the boost build system. For the tests of regular - expression variants of algorithms, the Boost.Regex library is required. - -
- -
- Portability - - The library has been successfully compiled and tested with the following compilers: - - - Microsoft Visual C++ 7.0 - Microsoft Visual C++ 7.1 - GCC 3.2 - GCC 3.3.1 - - - See Boost regression tables - for additional info for a particular compiler. - - - There are known limitation on platforms not supporting partial template specialization. - Library depends on correctly implemented std::iterator_traits class. - If a standard library provided with compiler is broken, the String Algorithm Library - cannot function properly. Usually it implies that primitive pointer iterators are not - working with the library functions. - -
-
diff --git a/string/doc/external_concepts.html b/string/doc/external_concepts.html deleted file mode 100644 index 7a4a502..0000000 --- a/string/doc/external_concepts.html +++ /dev/null @@ -1,38 +0,0 @@ - Concepts and External Concepts

Concepts and External Concepts

Generic programming in C++ is characterized by the use of function and class templates where - the template parameter(s) must satisfy certain requirements.Often these - requirements are so important that we give them a name: we call - such a set of type requirements a concept. We say that a type - conforms to a concept or that it is a model of a concept if it - satisfies all of those requirements. The concept can be specified as a set - of member functions with well-defined semantics - and a set of nested typedefs with well-defined properties.

Often it much more flexible to provide free-standing functions and typedefs - which provides the exact same semantics (but a different syntax) as - specified - by the concept. This allows generic code to treat different types as if - they fulfilled the concept. In this case we say that the concept has - been externalized or that the new requirements constitutes an external - concept . We say that a type conforms to an external concept - or that it is a model of an external concept . A concept may exist - without a corresponding external concept and conversely.

Whenever a concept specifies a member function, the corresponding external - concept - must specify a free-standing function of the same name, same return type and - the same argument list except there is an extra first argument which must - be of the type (or a reference to that type) that is to fulfill the external - concept. If the corresonding member function has any cv-qulifiers, the - first argument must have the same cv-qualifiers. Whenever a concept - specifies a nested typedef, the corresponding external concept - specifies a type-generator, that is, a type with a nested typedef - named type. The type-generator has the name as the nested typedef with - _of appended. - The converse relationship of an external concept and its corresponding concept - also holds.

Example:

A type T fulfills the FooConcept if it - has the follwing public members:

void T::foo( int ) const;
- int T::bar();
- typedef implementation defined foo_type;

The corresponding external concept is the ExternalFooConcept.

A type T fullfills the ExternalFooConcept if these - free-standing functions and type-generators exists:

void foo( const T&, int );
- int bar( T& );
- foo_type_of< T >::type;



Literature


© Thorsten Ottosen 2003-2004 (nesotto_AT_cs.auc.dk). - Permission to copy, use, modify, sell and distribute this software is granted provided this copyright notice appears - in all copies. This software is provided "as is" without express or implied warranty, and with no - claim as to its suitability for any purpose.































- \ No newline at end of file diff --git a/string/doc/intro.xml b/string/doc/intro.xml deleted file mode 100644 index f59cd2f..0000000 --- a/string/doc/intro.xml +++ /dev/null @@ -1,47 +0,0 @@ - - -
- Introduction - - - The String Algorithm Library provides a generic implementation of - string-related algorithms which are missing in STL. It is an extension - to the algorithms library of STL and it includes trimming, case conversion, - predicates and find/replace functions. All of them come in different variants - so it is easier to choose the best fit for a particular need. - - - The implementation is not restricted to work with a particular container - (like std::basic_string), rather it is as generic as - possible. This generalization is not compromising the performance since - algorithms are using container specific features when it means a performance - gain. - - - - Important note: In this documentation we use term string to - designate a sequence of characters stored in an arbitrary container. - A string is not restricted to std::basic_string and - character does not have to be char or wchar_t, - although these are most common candidates. - - Consult the design chapter to see precise specification of - supported string types. - - - The library interface functions and classes are defined in namespace boost::algorithm, and - they are lifted into namespace boost via using declaration. - - - The documentation is divided into several sections. For a quick start read the - Usage section followed by - Quick Reference. - The Design Topics, - Concepts and Rationale - provide some explanation about the library design and structure an explain how it should be used. - See the Reference for the complete list of provided utilities - and algorithms. Functions and classes in the reference are organized by the headers in which they are defined. - The reference contains links to the detailed description for every entity in the library. - -
diff --git a/string/doc/quickref.xml b/string/doc/quickref.xml deleted file mode 100644 index 51a0114..0000000 --- a/string/doc/quickref.xml +++ /dev/null @@ -1,686 +0,0 @@ - - -
- Quick Reference - - - - -
- Algorithms - - - Case Conversion - - - - Algorithm name - Description - Functions - - - - - to_upper - Convert a string to upper case - - to_upper_copy() - - to_upper() - - - - to_lower - Convert a string to lower case - - to_lower_copy() - - to_lower() - - - - -
- - Trimming - - - - Algorithm name - Description - Functions - - - - - trim_left - Remove leading spaces from a string - - trim_left_copy_if() - - trim_left_if() - - trim_left_copy() - - trim_left() - - - - trim_right - Remove trailing spaces from a string - - trim_right_copy_if() - - trim_right_if() - - trim_right_copy() - - trim_right() - - - - trim - Remove leading and trailing spaces from a string - - trim_copy_if() - - trim_if() - - trim_copy() - - trim() - - - - - -
- - Predicates - - - - Algorithm name - Description - Functions - - - - - starts_with - Check if a string is a prefix of the other one - - starts_with() - - istarts_with() - - - - ends_with - Check if a string is a suffix of the other one - - ends_with() - - iends_with() - - - - contains - Check if a string is contained of the other one - - contains() - - icontains() - - - - equals - Check if two strings are equal - - equals() - - iequals() - - - - all - Check if all elements of a string satisfy the given predicate - - all() - - - - -
- - Find algorithms - - - - Algorithm name - Description - Functions - - - - - find_first - Find the first occurrence of a string in the input - - find_first() - - ifind_first() - - - - find_last - Find the last occurrence of a string in the input - - find_last() - - ifind_last() - - - - find_nth - Find the nth (zero-indexed) occurrence of a string in the input - - find_nth() - - ifind_nth() - - - - find_head - Retrieve the head of a string - - find_head() - - - - find_tail - Retrieve the tail of a string - - find_tail() - - - - find_token - Find first matching token in the string - - find_token() - - - - find_regex - Use the regular expression to search the string - - find_regex() - - - - find - Generic find algorithm - - find() - - - - -
- - Erase/Replace - - - - Algorithm name - Description - Functions - - - - - replace/erase_first - Replace/Erase the first occurrence of a string in the input - - replace_first() - - replace_first_copy() - - ireplace_first() - - ireplace_first_copy() - - erase_first() - - erase_first_copy() - - ierase_first() - - ierase_first_copy() - - - - replace/erase_last - Replace/Erase the last occurrence of a string in the input - - replace_last() - - replace_last_copy() - - ireplace_last() - - ireplace_last_copy() - - erase_last() - - erase_last_copy() - - ierase_last() - - ierase_last_copy() - - - - replace/erase_nth - Replace/Erase the nth (zero-indexed) occurrence of a string in the input - - replace_nth() - - replace_nth_copy() - - ireplace_nth() - - ireplace_nth_copy() - - erase_nth() - - erase_nth_copy() - - ierase_nth() - - ierase_nth_copy() - - - - replace/erase_all - Replace/Erase the all occurrences of a string in the input - - replace_all() - - replace_all_copy() - - ireplace_all() - - ireplace_all_copy() - - erase_all() - - erase_all_copy() - - ierase_all() - - ierase_all_copy() - - - - replace/erase_head - Replace/Erase the head of the input - - replace_head() - - replace_head_copy() - - erase_head() - - erase_head_copy() - - - - - replace/erase_tail - Replace/Erase the tail of the input - - replace_tail() - - replace_tail_copy() - - erase_tail() - - erase_tail_copy() - - - - - replace/erase_regex - Replace/Erase a substring matching the given regular expression - - replace_regex() - - replace_regex_copy() - - erase_regex() - - erase_regex_copy() - - - - - replace/erase_regex_all - Replace/Erase all substrings matching the given regular expression - - replace_all_regex() - - replace_all_regex_copy() - - erase_all_regex() - - erase_all_regex_copy() - - - - - find_format - Generic replace algorithm - - find_format() - - find_format_copy() - - find_format_all() - - find_format_all_copy()() - - - - -
- - Split - - - - Algorithm name - Description - Functions - - - - - find_all - Find/Extract all matching substrings in the input - - find_all() - - ifind_all() - - find_all_regex() - - - - split - Split input into parts - - split() - - split_regex() - - - - -
-
-
- Finders and Formatters - - - Finders - - - - Finder - Description - Generators - - - - - first_finder - Search for the first match of the string in an input - - first_finder() - - - - last_finder - Search for the last match of the string in an input - - last_finder() - - - - nth_finder - Search for the nth (zero-indexed) match of the string in an input - - nth_finder() - - - - head_finder - Retrieve the head of an input - - head_finder() - - - - tail_finder - Retrieve the tail of an input - - tail_finder() - - - - token_finder - Search for a matching token in an input - - token_finder() - - - - range_finder - Do no search, always returns the given range - - range_finder() - - - - regex_finder - Search for a substring matching the given regex - - regex_finder() - - - - -
- - - Formatters - - - - Formatter - Description - Generators - - - - - const_formatter - Constant formatter. Always return the specified string - - const_formatter() - - - - identity_formatter - Identity formatter. Return unmodified input input - - identity_formatter() - - - - empty_formatter - Null formatter. Always return an empty string - - empty_formatter() - - - - regex_formatter - Regex formatter. Format regex match using the specification in the format string - - regex_formatter() - - - - -
-
-
- Iterators - - - Find Iterators - - - - Iterator name - Description - Iterator class - - - - - find_iterator - Iterates through matching substrings in the input - - find_iterator - - - - split_iterator - Iterates through gaps between matching substrings in the input - - split_iterator - - - - -
-
- -
- Classification - - - Predicates - - - - Predicate name - Description - Generator - - - - - is_classified - Generic ctype mask based classification - - is_classified() - - - - is_space - Recognize spaces - - is_space() - - - - is_alnum - Recognize alphanumeric characters - - is_alnum() - - - - is_alpha - Recognize letters - - is_alpha() - - - - is_cntrl - Recognize control characters - - is_cntrl() - - - - is_digit - Recognize decimal digits - - is_digit() - - - - is_graph - Recognize graphical characters - - is_graph() - - - - is_lower - Recognize lower case characters - - is_lower() - - - - is_print - Recognize printable characters - - is_print() - - - - is_punct - Recognize punctuation characters - - is_punct() - - - - is_upper - Recognize uppercase characters - - is_upper() - - - - is_xdigit - Recognize hexadecimal digits - - is_xdigit() - - - - -
-
-
diff --git a/string/doc/rationale.xml b/string/doc/rationale.xml deleted file mode 100644 index efbd502..0000000 --- a/string/doc/rationale.xml +++ /dev/null @@ -1,46 +0,0 @@ - - -
- Rationale - - - - -
- Locales - - - Locales have a very close relation to string processing. They contain information about - the character sets and are used, for example, to change the case of characters and - to classify the characters. - - - C++ allows to work with multiple different instances of locales at once. If an algorithm - manipulates some data in a way that requires the usage of locales, there must be a way - to specify them. However, one instance of locales is sufficient for most of the applications, - and for a user it could be very tedious to specify which locales to use at every place - where it is needed. - - - Fortunately, the C++ standard allows to specify the global locales (using static member - function std:locale::global()). When instantiating an - std::locale class without explicit information, the instance will - be initialized with the global locale. This implies, that if an algorithm needs a locale, - it should have an std::locale parameter defaulting to std::locale(). - If a user needs to specify locales explicitly, she can do so. Otherwise the global - locales are used. - -
-
- Regular Expressions - - - Regular expressions are an essential part of text processing. For this reason, the library - also provides regex variants of some algorithms. The library does not attempt to replace - Boost.Regex; it merely wraps its functionality in a new interface. - As a part of this library, regex algorithms integrate smoothly with other components, which - brings additional value. - -
-
diff --git a/string/doc/release_notes.xml b/string/doc/release_notes.xml deleted file mode 100644 index e9007c8..0000000 --- a/string/doc/release_notes.xml +++ /dev/null @@ -1,17 +0,0 @@ - - -
- Release Notes - - - - 1.32 - Initial release in Boost - - - 1.33 - Internal version of collection traits removed, library adapted to Boost.Range - - -
diff --git a/string/doc/string_algo.xml b/string/doc/string_algo.xml deleted file mode 100644 index c31999a..0000000 --- a/string/doc/string_algo.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - Pavol - Droba - - - - 2002 - 2003 - 2004 - Pavol Droba - - - - Use, modification and distribution is subject to 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) - - - - - A set of generic string-related algorithms and utilities - - - - - - Boost String Algorithms Library - - - - - - - - - - - - diff --git a/string/doc/usage.xml b/string/doc/usage.xml deleted file mode 100644 index e3b2324..0000000 --- a/string/doc/usage.xml +++ /dev/null @@ -1,353 +0,0 @@ - - -
- Usage - - - - - -
- First Example - - - Using the algorithms is straightforward. Let us have a look at the first example: - - - #include <boost/algorithm/string.hpp> - using namespace std; - using namespace boost; - - // ... - - string str1(" hello world! "); - to_upper(str1); // str1 == " HELLO WORLD! " - trim(str1); // str1 == "HELLO WORLD!" - - string str2= - to_lower_copy( - ireplace_first_copy( - str1,"hello","goodbye")); // str2 == "goodbye world!" - - - This example converts str1 to upper case and trims spaces from the start and the end - of the string. str2 is then created as a copy of str1 with "hello" replaced with "goodbye". - This example demonstrates several important concepts used in the library: - - - - Container parameters: - Unlike in the STL algorithms, parameters are not specified only in the form - of iterators. The STL convention allows for great flexibility, - but it has several limitations. It is not possible to stack algorithms together, - because a container is passed in two parameters. Therefore it is not possible to use - a return value from another algorithm. It is considerably easier to write - to_lower(str1), than to_lower(str1.begin(), str1.end()). - - - The magic of Boost.Range - provides a uniform way of handling different string types. - If there is a need to pass a pair of iterators, - boost::iterator_range - can be used to package iterators into a structure with a compatible interface. - - - - Copy vs. Mutable: - Many algorithms in the library are performing a transformation of the input. - The transformation can be done in-place, mutating the input sequence, or a copy - of the transformed input can be created, leaving the input intact. None of - these possibilities is superior to the other one and both have different - advantages and disadvantages. For this reason, both are provided with the library. - - - - Algorithm stacking: - Copy versions return a transformed input as a result, thus allow a simple chaining of - transformations within one expression (i.e. one can write trim_copy(to_upper_copy(s))). - Mutable versions have void return, to avoid misuse. - - - - Naming: - Naming follows the conventions from the Standard C++ Library. If there is a - copy and a mutable version of the same algorithm, the mutable version has no suffix - and the copy version has the suffix _copy. - Some algorithms have the prefix i - (e.g. ifind_first()). - This prefix identifies that the algorithm works in a case-insensitive manner. - - - - - To use the library, include the boost/algorithm/string.hpp header. - If the regex related functions are needed, include the - boost/algorithm/string_regex.hpp header. - -
-
- Case conversion - - - STL has a nice way of converting character case. Unfortunately, it works only - for a single character and we want to convert a string, - - - string str1("HeLlO WoRld!"); - to_upper(str1); // str1=="HELLO WORLD!" - - - to_upper() and to_lower() convert the case of - characters in a string using a specified locale. - - - For more information see the reference for boost/algorithm/string/case_conv.hpp. - -
-
- Predicates and Classification - - A part of the library deals with string related predicates. Consider this example: - - - bool is_executable( string& filename ) - { - return - iends_with(filename, ".exe") || - iends_with(filename, ".com"); - } - - // ... - string str1("command.com"); - cout - << str1 - << is_executable("command.com")? "is": "is not" - << "an executable" - << endl; // prints "command.com is an executable" - - //.. - char text1[]="hello world!"; - cout - << text1 - << all( text1, is_lower() )? "is": "is not" - << " written in the lower case" - << endl; // prints "hello world! is written in the lower case" - - - The predicates determine whether if a substring is contained in the input string - under various conditions. The conditions are: a string starts with the substring, - ends with the substring, - simply contains the substring or if both strings are equal. See the reference for - boost/algorithm/string/predicate.hpp for more details. - - - In addition the algorithm all() checks - all elements of a container to satisfy a condition specified by a predicate. - This predicate can be any unary predicate, but the library provides a bunch of - useful string-related predicates and combinators ready for use. - These are located in the boost/algorithm/string/classification.hpp header. - Classification predicates can be combined using logical combinators to form - a more complex expressions. For example: is_from_range('a','z') || is_digit() - -
-
- Trimming - - - When parsing the input from a user, strings usually have unwanted leading or trailing - characters. To get rid of them, we need trim functions: - - - string str1=" hello world! "; - string str2=trim_left_copy(str1); // str2 == "hello world! " - string str3=trim_right_copy(str2); // str3 == " hello world!" - trim(str1); // str1 == "hello world!" - - string phone="00423333444"; - // remove leading 0 from the phone number - trim_left_if(phone,is_any_of("0")); // phone == "423333444" - - - It is possible to trim the spaces on the right, on the left or on both sides of a string. - And for those cases when there is a need to remove something else than blank space, there - are _if variants. Using these, a user can specify a functor which will - select the space to be removed. It is possible to use classification - predicates like is_digit() mentioned in the previous paragraph. - See the reference for the boost/algorithm/string/trim.hpp. - -
-
- Find algorithms - - - The library contains a set of find algorithms. Here is an example: - - - char text[]="hello dolly!"; - iterator_range<char*> result=find_last(text,"ll"); - - transform( result.begin(), result.end(), result.begin(), bind2nd(plus<char>(), 1) ); - // text = "hello dommy!" - - to_upper(result); // text == "hello doMMy!" - - // iterator_range is convertible to bool - if(find_first(text, "dolly")) - { - cout << "Dolly is there" << endl; - } - - - We have used find_last() to search the text for "ll". - The result is given in the boost::iterator_range. - This range delimits the - part of the input which satisfies the find criteria. In our example it is the last occurrence of "ll". - - As we can see, input of the find_last() algorithm can be also - char[] because this type is supported by - Boost.Range. - - The following lines transform the result. Notice that - boost::iterator_range has familiar - begin() and end() methods, so it can be used like any other STL container. - Also it is convertible to bool therefore it is easy to use find algorithms for a simple containment checking. - - - Find algorithms are located in boost/algorithm/string/find.hpp. - -
-
- Replace Algorithms - - Find algorithms can be used for searching for a specific part of string. Replace goes one step - further. After a matching part is found, it is substituted with something else. The substitution is computed - from the original, using some transformation. - - - string str1="Hello Dolly, Hello World!" - replace_first(str1, "Dolly", "Jane"); // str1 == "Hello Jane, Hello World!" - replace_last(str1, "Hello", "Goodbye"); // str1 == "Hello Jane, Goodbye World!" - erase_all(str1, " "); // str1 == "HelloJane,GoodbyeWorld!" - erase_head(str1, 6); // str1 == "Jane,GoodbyeWorld!" - - - For the complete list of replace and erase functions see the - reference. - There is a lot of predefined function for common usage, however, the library allows you to - define a custom replace() that suits a specific need. There is a generic find_format() - function which takes two parameters. - The first one is a Finder object, the second one is - a Formatter object. - The Finder object is a functor which performs the searching for the replacement part. The Formatter object - takes the result of the Finder (usually a reference to the found substring) and creates a - substitute for it. Replace algorithm puts these two together and makes the desired substitution. - - - Check boost/algorithm/string/replace.hpp, boost/algorithm/string/erase.hpp and - boost/algorithm/string/find_format.hpp for reference. - -
-
- Find Iterator - - - An extension to find algorithms it the Find Iterator. Instead of searching for just a one part of a string, - the find iterator allows us to iterate over the substrings matching the specified criteria. - This facility is using the Finder to incrementally - search the string. - Dereferencing a find iterator yields an boost::iterator_range - object, that delimits the current match. - - - There are two iterators provided find_iterator and - split_iterator. The former iterates over substrings that are found using the specified - Finder. The latter iterates over the gaps between these substrings. - - - string str1("abc-*-ABC-*-aBc"); - // Find all 'abc' substrings (ignoring the case) - // Create a find_iterator - typedef find_iterator<string::iterator> string_find_iterator; - for(string_find_iterator It= - make_find_iterator(str1, first_finder("abc", is_iequal())); - It!=string_find_iterator(); - ++It) - { - cout << copy_range<std::string>(*It) << endl; - } - - // Output will be: - // abc - // ABC - // aBC - - typedef split_iterator<string::iterator> string_split_iterator; - for(string_find_iterator It= - make_split_iterator(str1, first_finder("-*-", is_iequal())); - It!=string_find_iterator(); - ++It) - { - cout << copy_range<std::string>(*It) << endl; - } - - // Output will be: - // abc - // ABC - // aBC - - - Note that the find iterators have only one template parameter. It is the base iterator type. - The Finder is specified at runtime. This allows us to typedef a find iterator for - common string types and reuse it. Additionally make_*_iterator functions help - to construct a find iterator for a particular range. - - - See the reference in boost/algorithm/string/find_iterator.hpp. - -
-
- Split - - - Split algorithms are an extension to the find iterator for one common usage scenario. - These algorithms use a find iterator and store all matches into the provided - container. This container must be able to hold copies (e.g. std::string) or - references (e.g. iterator_range) of the extracted substrings. - - - Two algorithms are provided. find_all() finds all copies - of a string in the input. split() splits the input into parts. - - - - string str1("hello abc-*-ABC-*-aBc goodbye"); - - typedef vector< iterator_range<string::iterator> > find_vector_type; - - find_vector_type FindVec; // #1: Search for separators - ifind_all( FindVec, str1, "abc" ); // FindVec == { [abc],[ABC],[aBc] } - - typedef vector< string > split_vector_type; - - split_vector_type SplitVec; // #2: Search for tokens - split( SplitVec, str1, is_any_of("-*") ); // SplitVec == { "hello abc","ABC","aBc goodbye" } - - - [hello] designates an iterator_range delimiting this substring. - - - First example show how to construct a container to hold references to all extracted - substrings. Algorithm ifind_all() puts into FindVec references - to all substrings that are in case-insensitive manner equal to "abc". - - - Second example uses split() to split string str1 into parts - separated by characters '-' or '*'. These parts are then put into the SplitVec. - It is possible to specify if adjacent separators are concatenated or not. - - - More information can be found in the reference: boost/algorithm/string/split.hpp. - -
-
diff --git a/string/example/Jamfile b/string/example/Jamfile deleted file mode 100644 index ac5a52d..0000000 --- a/string/example/Jamfile +++ /dev/null @@ -1,75 +0,0 @@ -# Boost string_algo library examples Jamfile --------------------------------- -# -# Copyright Pavol Droba 2002-2003. Use, modification and -# distribution is subject to 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) -# -# See http://www.boost.org for updates, documentation, and revision history. - -subproject libs/algorithm/string/example ; - -exe conv_example - : - conv_example.cpp - : - $(BOOST_ROOT) - : - ; - -exe predicate_example - : - predicate_example.cpp - : - $(BOOST_ROOT) - : - ; - -exe find_example - : - find_example.cpp - : - $(BOOST_ROOT) - : - ; - -exe replace_example - : - replace_example.cpp - : - $(BOOST_ROOT) - : - ; - -exe rle_example - : - rle_example.cpp - : - $(BOOST_ROOT) - : - ; - -exe trim_example - : - trim_example.cpp - : - $(BOOST_ROOT) - : - ; - -exe regex_example - : - regex_example.cpp - ../../../regex/build/boost_regex - : - $(BOOST_ROOT) - : - ; - -exe split_example - : - split_example.cpp - : - $(BOOST_ROOT) - : - ; diff --git a/string/example/conv_example.cpp b/string/example/conv_example.cpp deleted file mode 100644 index b6a08f9..0000000 --- a/string/example/conv_example.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// Boost string_algo library example file ---------------------------------// - -// Copyright Pavol Droba 2002-2003. Use, modification and -// distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include -#include - -using namespace std; -using namespace boost; - -int main() -{ - cout << "* Case Conversion Example *" << endl << endl; - - string str1("AbCdEfG"); - vector vec1( str1.begin(), str1.end() ); - - // Convert vector of chars to lower case - cout << "lower-cased copy of vec1: "; - to_lower_copy( ostream_iterator(cout), vec1 ); - cout << endl; - - // Conver string str1 to upper case ( copy the input ) - cout << "upper-cased copy of str1: " << to_upper_copy( str1 ) << endl; - - // Inplace conversion - to_lower( str1 ); - cout << "lower-cased str1: " << str1 << endl; - - cout << endl; - - return 0; -} diff --git a/string/example/find_example.cpp b/string/example/find_example.cpp deleted file mode 100644 index 7fd7e60..0000000 --- a/string/example/find_example.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// Boost string_algo library example file ---------------------------------// - -// Copyright Pavol Droba 2002-2003. Use, modification and -// distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace boost; - -int main() -{ - cout << "* Find Example *" << endl << endl; - - string str1("abc___cde___efg"); - string str2("abc"); - - // find "cde" substring - iterator_range range=find_first( str1, string("cde") ); - - // convert a substring to upper case - // note that iterator range can be directly passed to the algorithm - to_upper( range ); - - cout << "str1 with upper-cased part matching cde: " << str1 << endl; - - // get a head of the string - iterator_range head=find_head( str1, 3 ); - cout << "head(3) of the str1: " << string( head.begin(), head.end() ) << endl; - - // get the tail - head=find_tail( str2, 5 ); - cout << "tail(5) of the str2: " << string( head.begin(), head.end() ) << endl; - - // char processing - char text[]="hello dolly!"; - iterator_range crange=find_last(text,"ll"); - - // transform the range ( add 1 ) - transform( crange.begin(), crange.end(), crange.begin(), bind2nd( plus(), 1 ) ); - // uppercase the range - to_upper( crange ); - - cout << text << endl; - - cout << endl; - - return 0; -} diff --git a/string/example/predicate_example.cpp b/string/example/predicate_example.cpp deleted file mode 100644 index c89c653..0000000 --- a/string/example/predicate_example.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Boost string_algo library example file ---------------------------------// - -// Copyright Pavol Droba 2002-2003. Use, modification and -// distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include -#include -#include - - -using namespace std; -using namespace boost; - -int main() -{ - cout << "* Predicate Example *" << endl << endl; - - string str1("123xxx321"); - string str2("abc"); - - // Check if str1 starts with '123' - cout << "str1 starts with \"123\": " << - (starts_with( str1, string("123") )?"true":"false") << endl; - - // Check if str1 ends with '123' - cout << "str1 ends with \"123\": " << - (ends_with( str1, string("123") )?"true":"false") << endl; - - // Check if str1 containes 'xxx' - cout << "str1 contains \"xxx\": " << - (contains( str1, string("xxx") )?"true":"false") << endl; - - - // Check if str2 equals to 'abc' - cout << "str2 equals \"abc\": " << - (equals( str2, string("abc") )?"true":"false") << endl; - - - // Classification functors and all predicate - if ( all(";.,", is_punct() ) ) - { - cout << "\";.,\" are all punctuation characters" << endl; - } - - // Classification predicates can be combined - if ( all("abcxxx", is_any_of("xabc") && !is_space() ) ) - { - cout << "true" << endl; - } - - cout << endl; - - return 0; -} diff --git a/string/example/regex_example.cpp b/string/example/regex_example.cpp deleted file mode 100644 index 9eba1c7..0000000 --- a/string/example/regex_example.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// Boost string_algo library example file ---------------------------------// - -// Copyright Pavol Droba 2002-2003. Use, modification and -// distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include -#include - -using namespace std; -using namespace boost; - -int main() -{ - cout << "* Regex Example *" << endl << endl; - - string str1("abc__(456)__123__(123)__cde"); - - // Replace all substrings matching (digit+) - cout << - "replace all (digit+) in str1 with #digit+# :" << - replace_all_regex_copy( str1, regex("\\(([0-9]+)\\)"), string("#$1#") ) << endl; - - // Erase all substrings matching (digit+) - cout << - "remove all sequences of letters from str1 :" << - erase_all_regex_copy( str1, regex("[[:alpha:]]+") ) << endl; - - // in-place regex transformation - replace_all_regex( str1, regex("_(\\([^\\)]*\\))_"), string("-$1-") ); - cout << "transformad str1: " << str1 << endl; - - cout << endl; - - return 0; -} diff --git a/string/example/replace_example.cpp b/string/example/replace_example.cpp deleted file mode 100644 index 12089fa..0000000 --- a/string/example/replace_example.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// Boost string_algo library example file ---------------------------------// - -// Copyright Pavol Droba 2002-2003. Use, modification and -// distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -//#include -//#include -//#include -#include - -//Following two includes contain second-layer function. -//They are already included by first-layer header - -//#include -//#include - -using namespace std; -using namespace boost; - -// uppercase formatter -/* - Convert an input to upper case. - Note, that this formatter can be used only on std::string inputs. -*/ -inline string upcase_formatter( - const iterator_range& Replace ) -{ - string Temp(Replace.begin(), Replace.end()); - to_upper(Temp); - return Temp; -} - -int main() -{ - cout << "* Replace Example *" << endl << endl; - - string str1("abc___cde___efg"); - - // Erase 6-9th characters from the string - cout << "str1 without 6th to 9th character:" << - erase_range_copy( str1, make_iterator_range(str1.begin()+6, str1.begin()+9) ) << endl; - - // Replace 6-9th character with '+++' - cout << "str1 with 6th to 9th character replaced with '+++': " << - replace_range_copy( - str1, make_iterator_range(str1.begin()+6, str1.begin()+9), "+++" ) << endl; - - cout << "str1 with 'cde' replaced with 'XYZ': "; - - // Replace first 'cde' with 'XYZ'. Modify the input - replace_first_copy( ostream_iterator(cout), str1, "cde", "XYZ" ); - cout << endl; - - // Replace all '___' - cout << "str1 with all '___' replaced with '---': " << - replace_all_copy( str1, "___", "---" ) << endl; - - // Erase all '___' - cout << "str1 without all '___': " << - erase_all_copy( str1, "___" ) << endl; - - // replace third and 5th occurrence of _ in str1 - // note that nth argument is 0-based - replace_nth( str1, "_", 4, "+" ); - replace_nth( str1, "_", 2, "+" ); - - cout << "str1 with third and 5th occurrence of _ replace: " << str1 << endl; - - // Custom formatter examples - string str2("abC-xxxx-AbC-xxxx-abc"); - - // Find string 'abc' ignoring the case and convert it to upper case - cout << "Upcase all 'abc'(s) in the str2: " << - find_format_all_copy( - str2, - first_finder("abc", is_iequal()), - upcase_formatter ); - - cout << endl; - - return 0; -} diff --git a/string/example/rle_example.cpp b/string/example/rle_example.cpp deleted file mode 100644 index 26ec5b8..0000000 --- a/string/example/rle_example.cpp +++ /dev/null @@ -1,241 +0,0 @@ -// Boost string_algo library example file ---------------------------------// - -// Copyright Pavol Droba 2002-2003. Use, modification and -// distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -/* - RLE compression using replace framework. Goal is to compress a sequence of - repeating characters into 3 bytes ( repeat mark, character and repetition count ). - For simplification, it works only on numeric-value sequences. -*/ - -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace boost; - -// replace mark specification, specialize for a specific element type -template< typename T > T repeat_mark() { return (std::numeric_limits::max)(); }; - -// Compression ----------------------------------------------------------------------- - - -// compress finder -rle -/* - Find a sequence which can be compressed. It has to be at least 3-character long - sequence of repetitive characters -*/ -struct find_compressF -{ - // Construction - find_compressF() {} - - // Operation - template - iterator_range operator()( - ForwardIteratorT Begin, - ForwardIteratorT End ) const - { - typedef ForwardIteratorT input_iterator_type; - typedef typename boost::detail::iterator_traits::value_type value_type; - typedef iterator_range result_type; - - // begin of the matching segment - input_iterator_type MStart=End; - // Repetition counter - value_type Cnt=0; - - // Search for a sequence of repetitive characters - for(input_iterator_type It=Begin; It!=End;) - { - input_iterator_type It2=It++; - - if ( It==End || Cnt>=(std::numeric_limits::max)() ) - { - return result_type( MStart, It ); - } - - if ( *It==*It2 ) - { - if ( MStart==End ) - { - // Mark the start - MStart=It2; - } - - // Increate repetition counter - Cnt++; - } - else - { - if ( MStart!=End ) - { - if ( Cnt>2 ) - return result_type( MStart, It ); - else - { - MStart=End; - Cnt=0; - } - } - } - } - - return result_type( End, End ); - } -}; - -// rle compress format -/* - Transform a sequence into repeat mark, character and count -*/ -template -struct format_compressF -{ -private: - typedef SeqT result_type; - typedef typename SeqT::value_type value_type; - -public: - // Construction - format_compressF() {}; - - // Operation - template< typename ReplaceT > - result_type operator()( const ReplaceT& Replace ) const - { - SeqT r; - r.push_back( repeat_mark() ); - r.push_back( *(Replace.begin()) ); - r.push_back( value_type( Replace.size() ) ); - - return r; - } -}; - -// Decompression ----------------------------------------------------------------------- - - -// find decompress-rle functor -/* - find a repetition block -*/ -struct find_decompressF -{ - // Construction - find_decompressF() {} - - // Operation - template - iterator_range operator()( - ForwardIteratorT Begin, - ForwardIteratorT End ) const - { - typedef ForwardIteratorT input_iterator_type; - typedef typename boost::detail::iterator_traits::value_type value_type; - typedef iterator_range result_type; - - for(input_iterator_type It=Begin; It!=End; It++) - { - if( *It==repeat_mark() ) - { - // Repeat mark found, extract body - input_iterator_type It2=It++; - - if ( It==End ) break; - It++; - if ( It==End ) break; - It++; - - return result_type( It2, It ); - } - } - - return result_type( End, End ); - } -}; - -// rle decompress format -/* - transform a repetition block into a sequence of characters -*/ -template< typename SeqT > -struct format_decompressF -{ -private: - typedef SeqT result_type; - typedef typename SeqT::value_type value_type; - -public: - // Construction - format_decompressF() {}; - - // Operation - template< typename ReplaceT > - result_type operator()( const ReplaceT& Replace ) const - { - // extract info - typename ReplaceT::const_iterator It=Replace.begin(); - - value_type Value=*(++It); - value_type Repeat=*(++It); - - SeqT r; - for( value_type Index=0; Index() ); - - cout << "Compressed string: " << compress << endl; - - // Copy decompression - string decompress=find_format_all_copy( - compress, - find_decompressF(), - format_decompressF() ); - - cout << "Decompressed string: " << decompress << endl; - - // in-place compression - find_format_all( - original, - find_compressF(), - format_compressF() ); - - cout << "Compressed string: " << original << endl; - - // in-place decompression - find_format_all( - original, - find_decompressF(), - format_decompressF() ); - - cout << "Decompressed string: " << original << endl; - - cout << endl; - - return 0; -} diff --git a/string/example/split_example.cpp b/string/example/split_example.cpp deleted file mode 100644 index 27e261c..0000000 --- a/string/example/split_example.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// Boost string_algo library example file ---------------------------------// - -// Copyright Pavol Droba 2002-2003. Use, modification and -// distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace boost; - -int main() -{ - cout << "* Split Example *" << endl << endl; - - string str1("abc-*-ABC-*-aBc"); - - cout << "Before: " << str1 << endl; - - // Find all 'abc' substrings (ignoring the case) - // Create a find_iterator - typedef find_iterator string_find_iterator; - for(string_find_iterator It= - make_find_iterator(str1, first_finder("abc", is_iequal())); - It!=string_find_iterator(); - ++It) - { - cout << copy_range(*It) << endl; - // shift all chars in the match by one - transform( - It->begin(), It->end(), - It->begin(), - bind2nd( plus(), 1 ) ); - } - - // Print the string now - cout << "After: " << str1 << endl; - - // Split the string into tokens ( use '-' and '*' as delimiters ) - // We need copies of the input only, and adjacent tokens are compressed - vector ResultCopy; - split(ResultCopy, str1, is_any_of("-*"), token_compress_on); - - for(unsigned int nIndex=0; nIndex -#include -#include -#include - -using namespace std; -using namespace boost; - -int main() -{ - cout << "* Trim Example *" << endl << endl; - - string str1(" 1x x x x1 "); - string str2("<>trim<>"); - string str3("123abs343"); - - // Simple left trim - cout << "trim_left copy of str1: " << "\"" << trim_left_copy( str1 ) << "\"" << endl; - - // Inplace right trim - trim_right( str1 ); - cout << "trim_right on str1: " << "\"" << str1 << "\"" << endl; - - // Parametric trim. 'Space' is defined using is_any_of predicate - cout - << "trimmed copy of str4 ( space='<>' ): " - << "\""<< trim_copy_if( str2, is_any_of("<>") ) << "\"" << endl; - - - // Parametric trim. 'Space' is defined using is_digit predicate - cout - << "trimmed copy of str5 ( space=digit ): " - << "\"" << trim_copy_if( str3, is_digit() ) << "\"" << endl; - - cout << endl; - - return 0; -} diff --git a/string/index.html b/string/index.html deleted file mode 100644 index 717d7cf..0000000 --- a/string/index.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - -Automatic redirection failed, please go to -../../doc/html/string_algo.html - - diff --git a/string/test/Jamfile b/string/test/Jamfile deleted file mode 100644 index 3dbe393..0000000 --- a/string/test/Jamfile +++ /dev/null @@ -1,77 +0,0 @@ -# Boost string_algo library test suite Jamfile ---------------------------- -# -# Copyright Pavol Droba 2002-2003. Use, modification and -# distribution is subject to 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) -# -# See http://www.boost.org for updates, documentation, and revision history. - -subproject libs/algorithm/string/test ; - -# bring in rules for testing -import testing ; - -# Make tests run by default. -DEPENDS all : test ; - -{ - test-suite algorithm/string - : [ run - trim_test.cpp - : : - : - std::locale-support - std::facet-support - : trim - ] - [ run - conv_test.cpp - : : - : - std::locale-support - std::facet-support - : conv - ] - [ run - predicate_test.cpp - : : - : - std::locale-support - std::facet-support - : predicate - ] - [ run - find_test.cpp - : : - : - std::locale-support - std::facet-support - : find - ] - [ run - split_test.cpp - : : - : - std::locale-support - std::facet-support - : split - ] - [ run - replace_test.cpp - : : - : - std::locale-support - std::facet-support - : replace - ] - [ run - regex_test.cpp - ../../../regex/build/boost_regex - : : - : - : regex - ] - ; -} - diff --git a/string/test/Jamfile.v2 b/string/test/Jamfile.v2 deleted file mode 100644 index d8e35b7..0000000 --- a/string/test/Jamfile.v2 +++ /dev/null @@ -1,57 +0,0 @@ -# Boost string_algo library test suite Jamfile ---------------------------- -# -# Copyright Pavol Droba 2002-2003. Use, modification and -# distribution is subject to 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) -# -# See http://www.boost.org for updates, documentation, and revision history. - -import testing ; - -test-suite algorithm/string - : [ run - trim_test.cpp - : : - : - : trim - ] - [ run - conv_test.cpp - : : - : - : conv - ] - [ run - predicate_test.cpp - : : - : - : predicate - ] - [ run - find_test.cpp - : : - : - : find - ] - [ run - split_test.cpp - : : - : - : split - ] - [ run - replace_test.cpp - : : - : - : replace - ] - [ run - regex_test.cpp - ../../../regex/build//boost_regex - : : - : - : regex - ] - ; - diff --git a/string/test/conv_test.cpp b/string/test/conv_test.cpp deleted file mode 100644 index ca3c5ff..0000000 --- a/string/test/conv_test.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// Boost string_algo library conv_test.cpp file ---------------------------// - -// Copyright Pavol Droba 2002-2003. Use, modification and -// distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -// Include unit test framework -#include - -#include -#include -#include -#include - -using namespace std; -using namespace boost; - -void conv_test() -{ - string str1("AbCdEfG 123 xxxYYYzZzZ"); - string str2("AbCdEfG 123 xxxYYYzZzZ"); - string str3(""); - const char pch[]="AbCdEfG 123 xxxYYYzZzZ"; - unsigned int pchlen=sizeof(pch); - - char* pch1=new char[pchlen]; - std::copy(pch, pch+pchlen, pch1); - char* pch2=new char[pchlen]; - std::copy(pch, pch+pchlen, pch2); - - // *** iterator tests *** // - - string strout; - to_lower_copy( back_inserter(strout), str1 ); - BOOST_CHECK( strout=="abcdefg 123 xxxyyyzzzz" ); - strout.clear(); - to_upper_copy( back_inserter(strout), str1 ); - BOOST_CHECK( strout=="ABCDEFG 123 XXXYYYZZZZ" ); - - strout.clear(); - to_lower_copy( back_inserter(strout), "AbCdEfG 123 xxxYYYzZzZ" ); - BOOST_CHECK( strout=="abcdefg 123 xxxyyyzzzz" ); - strout.clear(); - to_upper_copy( back_inserter(strout), "AbCdEfG 123 xxxYYYzZzZ" ); - BOOST_CHECK( strout=="ABCDEFG 123 XXXYYYZZZZ" ); - - strout.clear(); - to_lower_copy( back_inserter(strout), pch1 ); - BOOST_CHECK( strout=="abcdefg 123 xxxyyyzzzz" ); - strout.clear(); - to_upper_copy( back_inserter(strout), pch1 ); - BOOST_CHECK( strout=="ABCDEFG 123 XXXYYYZZZZ" ); - - // *** value passing tests *** // - - BOOST_CHECK( to_lower_copy( str1 )=="abcdefg 123 xxxyyyzzzz" ); - BOOST_CHECK( to_upper_copy( str1 )=="ABCDEFG 123 XXXYYYZZZZ" ); - - BOOST_CHECK( to_lower_copy( str3 )=="" ); - BOOST_CHECK( to_upper_copy( str3 )=="" ); - - // *** inplace tests *** // - - to_lower( str1 ); - BOOST_CHECK( str1=="abcdefg 123 xxxyyyzzzz" ); - to_upper( str2 ); - BOOST_CHECK( str2=="ABCDEFG 123 XXXYYYZZZZ" ); - - // c-string modification - to_lower( pch1 ); - BOOST_CHECK( string(pch1)=="abcdefg 123 xxxyyyzzzz" ); - to_upper( pch2 ); - BOOST_CHECK( string(pch2)=="ABCDEFG 123 XXXYYYZZZZ" ); - - to_lower( str3 ); - BOOST_CHECK( str3=="" ); - to_upper( str3 ); - BOOST_CHECK( str3=="" ); - - delete[] pch1; - delete[] pch2; -} - -// test main -int test_main( int, char*[] ) -{ - conv_test(); - - return 0; -} diff --git a/string/test/find_test.cpp b/string/test/find_test.cpp deleted file mode 100644 index 92e4812..0000000 --- a/string/test/find_test.cpp +++ /dev/null @@ -1,231 +0,0 @@ -// Boost string_algo library substr_test.cpp file ------------------// - -// Copyright Pavol Droba 2002-2003. Use, modification and -// distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -// Include unit test framework -#include - -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace boost; - -void find_test() -{ - string str1("123abcxXxabcXxXabc321"); - string str2("abc"); - string str3(""); - const char* pch1="123abcxxxabcXXXabc321"; - vector vec1( str1.begin(), str1.end() ); - - // find results ------------------------------------------------------------// - iterator_range nc_result; - iterator_range cv_result; - - iterator_range::iterator> nc_vresult; - iterator_range::const_iterator> cv_vresult; - - iterator_range ch_result; - - // basic tests ------------------------------------------------------------// - - - // find_first - BOOST_CHECKPOINT( "find_first" ); - - nc_result=find_first( str1, string("abc") ); - BOOST_CHECK( - ( (nc_result.begin()-str1.begin()) == 3) && - ( (nc_result.end()-str1.begin()) == 6) ); - - cv_result=find_first( const_cast(str1), str2 ); - BOOST_CHECK( - ( (cv_result.begin()-str1.begin()) == 3) && - ( (cv_result.end()-str1.begin()) == 6) ); - - cv_result=ifind_first( const_cast(str1), "xXX" ); - BOOST_CHECK( - ( (cv_result.begin()-str1.begin()) == 6) && - ( (cv_result.end()-str1.begin()) == 9) ); - - ch_result=find_first( pch1, "abc" ); - BOOST_CHECK(( (ch_result.begin() - pch1 ) == 3) && ( (ch_result.end() - pch1 ) == 6 ) ); - - // find_last - BOOST_CHECKPOINT( "find_last" ); - - nc_result=find_last( str1, string("abc") ); - BOOST_CHECK( - ( (nc_result.begin()-str1.begin()) == 15) && - ( (nc_result.end()-str1.begin()) == 18) ); - - cv_result=find_last( const_cast(str1), str2 ); - BOOST_CHECK( - ( (cv_result.begin()-str1.begin()) == 15) && - ( (cv_result.end()-str1.begin()) == 18) ); - - cv_result=ifind_last( const_cast(str1), "XXx" ); - BOOST_CHECK( - ( (cv_result.begin()-str1.begin()) == 12) && - ( (cv_result.end()-str1.begin()) == 15) ); - - ch_result=find_last( pch1, "abc" ); - BOOST_CHECK(( (ch_result.begin() - pch1 ) == 15) && ( (ch_result.end() - pch1 ) == 18 ) ); - - // find_nth - BOOST_CHECKPOINT( "find_nth" ); - - nc_result=find_nth( str1, string("abc"), 1 ); - BOOST_CHECK( - ( (nc_result.begin()-str1.begin()) == 9) && - ( (nc_result.end()-str1.begin()) == 12) ); - - cv_result=find_nth( const_cast(str1), str2, 1 ); - BOOST_CHECK( - ( (cv_result.begin()-str1.begin()) == 9) && - ( (cv_result.end()-str1.begin()) == 12) ); - - cv_result=ifind_nth( const_cast(str1), "xxx", 1 ); - BOOST_CHECK( - ( (cv_result.begin()-str1.begin()) == 12) && - ( (cv_result.end()-str1.begin()) == 15) ); - - ch_result=find_nth( pch1, "abc", 1 ); - BOOST_CHECK(( (ch_result.begin() - pch1 ) == 9) && ( (ch_result.end() - pch1 ) == 12 ) ); - - // find_head - BOOST_CHECKPOINT( "find_head" ); - - nc_result=find_head( str1, 6 ); - BOOST_CHECK( - ( (nc_result.begin()-str1.begin()) == 0) && - ( (nc_result.end()-str1.begin()) == 6) ); - - cv_result=find_head( const_cast(str1), 6 ); - BOOST_CHECK( - ( (cv_result.begin()-str1.begin()) == 0) && - ( (cv_result.end()-str1.begin()) == 6) ); - - ch_result=find_head( pch1, 6 ); - BOOST_CHECK( ( (ch_result.begin() - pch1 ) == 0 ) && ( (ch_result.end() - pch1 ) == 6 ) ); - - // find_tail - BOOST_CHECKPOINT( "find_tail" ); - - nc_result=find_tail( str1, 6 ); - BOOST_CHECK( - ( (nc_result.begin()-str1.begin()) == 15) && - ( (nc_result.end()-str1.begin()) == 21) ); - - cv_result=find_tail( const_cast(str1), 6 ); - BOOST_CHECK( - ( (cv_result.begin()-str1.begin()) == 15) && - ( (cv_result.end()-str1.begin()) == 21) ); - - ch_result=find_tail( pch1, 6 ); - BOOST_CHECK( ( (ch_result.begin() - pch1 ) == 15 ) && ( (ch_result.end() - pch1 ) == 21 ) ); - - // find_token - BOOST_CHECKPOINT( "find_token" ); - - nc_result=find_token( str1, is_any_of("abc"), token_compress_on ); - BOOST_CHECK( - ( (nc_result.begin()-str1.begin()) == 3) && - ( (nc_result.end()-str1.begin()) == 6) ); - - cv_result=find_token( const_cast(str1), is_any_of("abc"), token_compress_on ); - BOOST_CHECK( - ( (cv_result.begin()-str1.begin()) == 3) && - ( (cv_result.end()-str1.begin()) == 6) ); - - nc_result=find_token( str1, is_any_of("abc"), token_compress_off ); - BOOST_CHECK( - ( (nc_result.begin()-str1.begin()) == 3) && - ( (nc_result.end()-str1.begin()) == 4) ); - - cv_result=find_token( const_cast(str1), is_any_of("abc"), token_compress_off ); - BOOST_CHECK( - ( (cv_result.begin()-str1.begin()) == 3) && - ( (cv_result.end()-str1.begin()) == 4) ); - - ch_result=find_token( pch1, is_any_of("abc"), token_compress_off ); - BOOST_CHECK( ( (ch_result.begin() - pch1 ) == 3 ) && ( (ch_result.end() - pch1 ) == 4 ) ); - - // generic find - BOOST_CHECKPOINT( "generic find" ); - - nc_result=find(str1, first_finder(string("abc"))); - BOOST_CHECK( - ( (nc_result.begin()-str1.begin()) == 3) && - ( (nc_result.end()-str1.begin()) == 6) ); - - cv_result=find(const_cast(str1), first_finder(str2) ); - BOOST_CHECK( - ( (cv_result.begin()-str1.begin()) == 3) && - ( (cv_result.end()-str1.begin()) == 6) ); - - // multi-type comparison test - BOOST_CHECKPOINT( "multi-type" ); - - nc_vresult=find_first( vec1, string("abc") ); - BOOST_CHECK( - ( (nc_result.begin()-str1.begin()) == 3) && - ( (nc_result.end()-str1.begin()) == 6) ); - - cv_vresult=find_first( const_cast&>(vec1), str2 ); - BOOST_CHECK( - ( (cv_result.begin()-str1.begin()) == 3) && - ( (cv_result.end()-str1.begin()) == 6) ); - - // overflow test - BOOST_CHECKPOINT( "overflow" ); - - nc_result=find_first( str2, string("abcd") ); - BOOST_CHECK( nc_result.begin()==nc_result.end() ); - cv_result=find_first( const_cast(str2), string("abcd") ); - BOOST_CHECK( cv_result.begin()==cv_result.end() ); - - cv_result=find_head( const_cast(str2), 4 ); - BOOST_CHECK( string( cv_result.begin(), cv_result.end() )== string("abc") ); - cv_result=find_tail( const_cast(str2), 4 ); - BOOST_CHECK( string( cv_result.begin(), cv_result.end() )== string("abc") ); - - // Empty string test - BOOST_CHECKPOINT( "empty" ); - - nc_result=find_first( str3, string("abcd") ); - BOOST_CHECK( nc_result.begin()==nc_result.end() ); - nc_result=find_first( str1, string("") ); - BOOST_CHECK( nc_result.begin()==nc_result.end() ); - - cv_result=find_first( const_cast(str3), string("abcd") ); - BOOST_CHECK( cv_result.begin()==cv_result.end() ); - cv_result=find_first( const_cast(str1), string("") ); - BOOST_CHECK( cv_result.begin()==cv_result.end() ); - - // iterator_range specific tests - ostringstream osstr; - osstr << find_first( str1, "abc" ); - BOOST_CHECK( osstr.str()=="abc" ); -} - -// test main -int test_main( int, char*[] ) -{ - find_test(); - - return 0; -} diff --git a/string/test/predicate_test.cpp b/string/test/predicate_test.cpp deleted file mode 100644 index d2d0f0e..0000000 --- a/string/test/predicate_test.cpp +++ /dev/null @@ -1,126 +0,0 @@ -// Boost string_algo library predicate_test.cpp file ------------------// - -// Copyright Pavol Droba 2002-2003. Use, modification and -// distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -// Include unit test framework -#include - -#include -#include -#include -#include -#include - -using namespace std; -using namespace boost; - -void predicate_test() -{ - string str1("123xxx321"); - string str1_prefix("123"); - string str2("abc"); - string str3(""); - string str4("abc"); - vector vec1( str1.begin(), str1.end() ); - - // Basic tests - BOOST_CHECK( starts_with( str1, string("123") ) ); - BOOST_CHECK( !starts_with( str1, string("1234") ) ); - - BOOST_CHECK( istarts_with( "aBCxxx", "abc" ) ); - BOOST_CHECK( !istarts_with( "aBCxxx", "abcd" ) ); - - BOOST_CHECK( ends_with( str1, string("321") ) ); - BOOST_CHECK( !ends_with( str1, string("123") ) ); - - BOOST_CHECK( iends_with( "aBCxXx", "XXX" ) ); - BOOST_CHECK( !iends_with( "aBCxxX", "xXXX" ) ); - - BOOST_CHECK( contains( str1, string("xxx") ) ); - BOOST_CHECK( !contains( str1, string("yyy") ) ); - - BOOST_CHECK( icontains( "123XxX321", "xxx" ) ); - BOOST_CHECK( !icontains( "123xXx321", "yyy" ) ); - - BOOST_CHECK( equals( str2, string("abc") ) ); - BOOST_CHECK( !equals( str1, string("yyy") ) ); - - BOOST_CHECK( iequals( "AbC", "abc" ) ); - BOOST_CHECK( !iequals( "aBc", "yyy" ) ); - - // multi-type comparison test - BOOST_CHECK( starts_with( vec1, string("123") ) ); - BOOST_CHECK( ends_with( vec1, string("321") ) ); - BOOST_CHECK( contains( vec1, string("xxx") ) ); - BOOST_CHECK( equals( vec1, str1 ) ); - - // overflow test - BOOST_CHECK( !starts_with( str2, string("abcd") ) ); - BOOST_CHECK( !ends_with( str2, string("abcd") ) ); - BOOST_CHECK( !contains( str2, string("abcd") ) ); - BOOST_CHECK( !equals( str2, string("abcd") ) ); - - // equal test - BOOST_CHECK( starts_with( str2, string("abc") ) ); - BOOST_CHECK( ends_with( str2, string("abc") ) ); - BOOST_CHECK( contains( str2, string("abc") ) ); - BOOST_CHECK( equals( str2, string("abc") ) ); - - //! Empty string test - BOOST_CHECK( starts_with( str2, string("") ) ); - BOOST_CHECK( ends_with( str2, string("") ) ); - BOOST_CHECK( contains( str2, string("") ) ); - BOOST_CHECK( equals( str3, string("") ) ); - - //! Container compatibility test - BOOST_CHECK( starts_with( "123xxx321", "123" ) ); - BOOST_CHECK( ends_with( "123xxx321", "321" ) ); - BOOST_CHECK( contains( "123xxx321", "xxx" ) ); - BOOST_CHECK( equals( "123xxx321", "123xxx321" ) ); -} - -#define TEST_CLASS( Pred, YesInput, NoInput )\ -{\ - BOOST_CHECK( all( string(YesInput), Pred ) );\ - BOOST_CHECK( !all( string(NoInput), Pred ) );\ -} - -void classification_test() -{ - TEST_CLASS( is_space(), "\n\r\t ", "..." ); - TEST_CLASS( is_alnum(), "ab129ABc", "_ab129ABc" ); - TEST_CLASS( is_alpha(), "abc", "abc1" ); - TEST_CLASS( is_cntrl(), "\n\t\r", "..." ); - TEST_CLASS( is_digit(), "1234567890", "abc" ); - TEST_CLASS( is_graph(), "123abc.,", " \t" ); - TEST_CLASS( is_lower(), "abc", "Aasdf" ); - TEST_CLASS( is_print(), "abs", "\003\004asdf" ); - TEST_CLASS( is_punct(), ".,;\"", "abc" ); - TEST_CLASS( is_upper(), "ABC", "aBc" ); - TEST_CLASS( is_xdigit(), "ABC123", "XFD" ); - TEST_CLASS( is_any_of( string("abc") ), "aaabbcc", "aaxb" ); - TEST_CLASS( is_any_of( "abc" ), "aaabbcc", "aaxb" ); - TEST_CLASS( is_from_range( 'a', 'c' ), "aaabbcc", "aaxb" ); - - TEST_CLASS( !is_classified(std::ctype_base::space), "...", "..\n\r\t " ); - TEST_CLASS( ( !is_any_of("abc") && is_from_range('a','e') ) || is_space(), "d e", "abcde" ); -} - -#undef TEST_CLASS - -// test main -int test_main( int, char*[] ) -{ - predicate_test(); - classification_test(); - - return 0; -} diff --git a/string/test/regex_test.cpp b/string/test/regex_test.cpp deleted file mode 100644 index a21c20d..0000000 --- a/string/test/regex_test.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// Boost string_algo library substr_test.cpp file ------------------// - -// Copyright Pavol Droba 2002-2003. Use, modification and -// distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -// Include unit test framework -#include - -#include -#include -#include -#include -#include - -using namespace std; -using namespace boost; - -static void find_test() -{ - string str1("123a1cxxxa23cXXXa456c321"); - const char* pch1="123a1cxxxa23cXXXa456c321"; - regex rx("a[0-9]+c"); - vector vec1( str1.begin(), str1.end() ); - vector tokens; - - // find results - iterator_range nc_result; - iterator_range cv_result; - - iterator_range::iterator> nc_vresult; - iterator_range::const_iterator> cv_vresult; - - iterator_range ch_result; - - // basic tests - nc_result=find_regex( str1, rx ); - BOOST_CHECK( - ( (nc_result.begin()-str1.begin()) == 3) && - ( (nc_result.end()-str1.begin()) == 6) ); - - cv_result=find_regex( str1, rx ); - BOOST_CHECK( - ( (cv_result.begin()-str1.begin()) == 3) && - ( (cv_result.end()-str1.begin()) == 6) ); - - ch_result=find_regex( pch1, rx ); - BOOST_CHECK(( (ch_result.begin() - pch1 ) == 3) && ( (ch_result.end() - pch1 ) == 6 ) ); - - // multi-type comparison test - nc_vresult=find_regex( vec1, rx ); - BOOST_CHECK( - ( (nc_result.begin()-str1.begin()) == 3) && - ( (nc_result.end()-str1.begin()) == 6) ); - - cv_vresult=find_regex( vec1, rx ); - BOOST_CHECK( - ( (cv_result.begin()-str1.begin()) == 3) && - ( (cv_result.end()-str1.begin()) == 6) ); - - // find_all_regex test - find_all_regex( tokens, str1, rx ); - - BOOST_REQUIRE( tokens.size()==3 ); - BOOST_CHECK( tokens[0]==string("a1c") ); - BOOST_CHECK( tokens[1]==string("a23c") ); - BOOST_CHECK( tokens[2]==string("a456c") ); - - // split_regex test - split_regex( tokens, str1, rx ); - - BOOST_REQUIRE( tokens.size()==4 ); - BOOST_CHECK( tokens[0]==string("123") ); - BOOST_CHECK( tokens[1]==string("xxx") ); - BOOST_CHECK( tokens[2]==string("XXX") ); - BOOST_CHECK( tokens[3]==string("321") ); - -} - -static void replace_test() -{ - string str1("123a1cxxxa23cXXXa456c321"); - regex rx1("a([0-9]+)c"); - regex rx2("([xX]+)"); - regex rx3("_[^_]*_"); - string fmt1("_A$1C_"); - string fmt2("_xXx_"); - vector vec1( str1.begin(), str1.end() ); - - // inmutable tests - - // basic tests - BOOST_CHECK( replace_regex_copy( str1, rx1, fmt1 )==string("123_A1C_xxxa23cXXXa456c321") ); - BOOST_CHECK( replace_all_regex_copy( str1, rx1, fmt1 )==string("123_A1C_xxx_A23C_XXX_A456C_321") ); - BOOST_CHECK( erase_regex_copy( str1, rx1 )==string("123xxxa23cXXXa456c321") ); - BOOST_CHECK( erase_all_regex_copy( str1, rx1 )==string(string("123xxxXXX321")) ); - - // output iterator variants test - string strout; - replace_regex_copy( back_inserter(strout), str1, rx1, fmt1 ); - BOOST_CHECK( strout==string("123_A1C_xxxa23cXXXa456c321") ); - strout.clear(); - replace_all_regex_copy( back_inserter(strout), str1, rx1, fmt1 ); - BOOST_CHECK( strout==string("123_A1C_xxx_A23C_XXX_A456C_321") ); - strout.clear(); - erase_regex_copy( back_inserter(strout), str1, rx1 ); - BOOST_CHECK( strout==string("123xxxa23cXXXa456c321") ); - strout.clear(); - erase_all_regex_copy( back_inserter(strout), str1, rx1 ); - BOOST_CHECK( strout==string("123xxxXXX321") ); - strout.clear(); - - // in-place test - replace_regex( str1, rx1, fmt2 ); - BOOST_CHECK( str1==string("123_xXx_xxxa23cXXXa456c321") ); - - replace_all_regex( str1, rx2, fmt1 ); - BOOST_CHECK( str1==string("123__AxXxC___AxxxC_a23c_AXXXC_a456c321") ); - erase_regex( str1, rx3 ); - BOOST_CHECK( str1==string("123AxXxC___AxxxC_a23c_AXXXC_a456c321") ); - erase_all_regex( str1, rx3 ); - BOOST_CHECK( str1==string("123AxXxCa23ca456c321") ); -} - -int test_main( int, char*[] ) -{ - find_test(); - replace_test(); - - return 0; -} diff --git a/string/test/replace_test.cpp b/string/test/replace_test.cpp deleted file mode 100644 index 79f2a65..0000000 --- a/string/test/replace_test.cpp +++ /dev/null @@ -1,282 +0,0 @@ -// Boost string_algo library substr_test.cpp file ------------------// - -// Copyright Pavol Droba 2002-2003. Use, modification and -// distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include - -// Include unit test framework -#include - -#include -#include -#include -#include - -// equals predicate is used for result comparison -#include - -#include - -using namespace std; -using namespace boost; - -void sequence_traits_test() -{ - // basic_string traits - BOOST_CHECK( boost::algorithm::has_native_replace::value ); - BOOST_CHECK( !boost::algorithm::has_stable_iterators::value ); - BOOST_CHECK( !boost::algorithm::has_const_time_insert::value ); - BOOST_CHECK( !boost::algorithm::has_const_time_erase::value ); - - // vector traits - BOOST_CHECK( !boost::algorithm::has_native_replace< vector >::value ); - BOOST_CHECK( !boost::algorithm::has_stable_iterators< vector >::value ); - BOOST_CHECK( !boost::algorithm::has_const_time_insert< vector >::value ); - BOOST_CHECK( !boost::algorithm::has_const_time_erase< vector >::value ); - - // list traits - BOOST_CHECK( !boost::algorithm::has_native_replace< list >::value ); - BOOST_CHECK( boost::algorithm::has_stable_iterators< list >::value ); - BOOST_CHECK( boost::algorithm::has_const_time_insert< list >::value ); - BOOST_CHECK( boost::algorithm::has_const_time_erase< list >::value ); -} - -// Combine tests for all variants of the algorithm -#define C_ , -#define TEST_ALGO( Algo, Input, Params, Output ) \ -{\ - BOOST_CHECKPOINT( #Algo " - Copy" );\ -\ - string str1(Input);\ -\ - /* Copy test */ \ - BOOST_CHECK( Algo##_copy( str1, Params )==Output );\ -\ - BOOST_CHECKPOINT( #Algo " - Iterator" );\ - /* Iterator test */\ - string strout;\ - Algo##_copy( back_inserter(strout), str1, Params );\ - BOOST_CHECK( strout==Output ); \ -\ - /* In-place test */\ - vector vec1( str1.begin(), str1.end() );\ - list list1( str1.begin(), str1.end() );\ -\ - BOOST_CHECKPOINT( #Algo " - Inplace(string)" );\ - Algo( str1, Params ); \ - BOOST_CHECK( equals( str1, Output ) ); \ -\ - BOOST_CHECKPOINT( #Algo " - Inplace(vector)" );\ - Algo( vec1, Params ); \ - BOOST_CHECK( equals( vec1, Output ) );\ -\ - BOOST_CHECKPOINT( #Algo " - Inplace(list)" );\ - Algo( list1, Params ); \ - BOOST_CHECK( equals( list1, Output ) );\ -} - -void replace_first_test() -{ - // replace first - TEST_ALGO( replace_first, "1abc3abc2", string("abc") C_ string("YYY"), string("1YYY3abc2") ); - TEST_ALGO( ireplace_first, "1AbC3abc2", "aBc" C_ "YYY", string("1YYY3abc2") ); - TEST_ALGO( replace_first, "1abc3abc2", string("abc") C_ string("Z"), string("1Z3abc2") ); - TEST_ALGO( replace_first, "1abc3abc2", string("abc") C_ string("XXXX"), string("1XXXX3abc2") ); - TEST_ALGO( replace_first, "1abc3abc2", string("") C_ string("XXXX"), string("1abc3abc2") ); - TEST_ALGO( replace_first, "1abc3abc2", "" C_ "XXXX", string("1abc3abc2") ); - TEST_ALGO( replace_first, "", string("") C_ string("XXXX"), string("") ); - TEST_ALGO( erase_first, "1abc3abc2", string("abc"), string("13abc2") ); - TEST_ALGO( ierase_first, "1aBc3abc2", "abC", "13abc2" ); - TEST_ALGO( erase_first, "1abc3abc2", "abc", "13abc2" ); - TEST_ALGO( erase_first, "1abc3abc2", string(""), string("1abc3abc2") ); - TEST_ALGO( erase_first, "", string("abc"), string("") ); -} - -void replace_last_test() -{ - // replace last - TEST_ALGO( replace_last, "1abc3abc2", string("abc") C_ string("YYY"), string("1abc3YYY2") ); - TEST_ALGO( ireplace_last, "1abc3AbC2", "aBc" C_ "YYY", string("1abc3YYY2") ); - TEST_ALGO( replace_last, "1abc3abc2", string("abc") C_ string("Z"), string("1abc3Z2") ); - TEST_ALGO( replace_last, "1abc3abc2", string("abc") C_ string("XXXX"), string("1abc3XXXX2") ); - TEST_ALGO( replace_last, "1abc3abc2", "abc" C_ "XXXX", string("1abc3XXXX2") ); - TEST_ALGO( replace_last, "", string("") C_ string("XXXX"), string("") ); - TEST_ALGO( erase_last, "1abc3abc2", string("abc"), string("1abc32") ); - TEST_ALGO( ierase_last, "1aBc3aBc2", "ABC", string("1aBc32") ); - TEST_ALGO( erase_last, "1abc3abc2", "abc", string("1abc32") ); - TEST_ALGO( erase_last, "1abc3abc2", string(""), string("1abc3abc2") ); - TEST_ALGO( erase_last, "", string("abc"), string("") ); -} - -void replace_all_test() -{ - // replace all - TEST_ALGO( replace_all, "1abc3abc2", string("abc") C_ string("YYY"), string("1YYY3YYY2") ); - TEST_ALGO( ireplace_all, "1aBc3AbC2", "abC" C_ "YYY", string("1YYY3YYY2") ); - TEST_ALGO( replace_all, "1abc3abc2", string("abc") C_ string("Z"), string("1Z3Z2") ); - TEST_ALGO( replace_all, "1abc3abc2", string("abc") C_ string("XXXX"), string("1XXXX3XXXX2") ); - TEST_ALGO( replace_all, "1abc3abc2", "abc" C_ "XXXX", string("1XXXX3XXXX2") ); - TEST_ALGO( replace_all, "", string("") C_ string("XXXX"), string("") ); - TEST_ALGO( erase_all, "1abc3abc2", string("abc"), string("132") ); - TEST_ALGO( ierase_all, "1aBc3aBc2", "aBC", string("132") ); - TEST_ALGO( erase_all, "1abc3abc2", "abc", string("132") ); - TEST_ALGO( erase_all, "1abc3abc2", string(""), string("1abc3abc2") ); - TEST_ALGO( erase_all, "", string("abc"), string("") ); -} - -void replace_nth_test() -{ - // replace nth - TEST_ALGO( replace_nth, "1abc3abc2", string("abc") C_ 0 C_ string("YYY"), string("1YYY3abc2") ); - TEST_ALGO( ireplace_nth, "1AbC3abc2", "aBc" C_ 0 C_ "YYY", string("1YYY3abc2") ); - TEST_ALGO( replace_nth, "1abc3abc2", string("abc") C_ 0 C_ string("Z"), string("1Z3abc2") ); - TEST_ALGO( replace_nth, "1abc3abc2", string("abc") C_ 0 C_ string("XXXX"), string("1XXXX3abc2") ); - TEST_ALGO( replace_nth, "1abc3abc2", "abc" C_ 0 C_ "XXXX", string("1XXXX3abc2") ); - TEST_ALGO( replace_nth, "1abc3abc2", string("") C_ 0 C_ string("XXXX"), string("1abc3abc2") ); - TEST_ALGO( replace_nth, "", string("") C_ 0 C_ string("XXXX"), string("") ); - TEST_ALGO( erase_nth, "1abc3abc2", string("abc") C_ 0, string("13abc2") ); - TEST_ALGO( ierase_nth, "1aBc3aBc2", "ABC" C_ 0, string("13aBc2") ); - TEST_ALGO( erase_nth, "1abc3abc2", "abc" C_ 0, string("13abc2") ); - TEST_ALGO( erase_nth, "1abc3abc2", string("") C_ 0, string("1abc3abc2") ); - TEST_ALGO( erase_nth, "", string("abc") C_ 0, string("") ); - TEST_ALGO( replace_nth, "1abc3abc2", string("abc") C_ 1 C_ string("YYY"), string("1abc3YYY2") ); - TEST_ALGO( replace_nth, "1abc3abc2", string("abc") C_ 2 C_ string("YYY"), string("1abc3abc2") ); -} - -void replace_head_test() -{ - // replace head - TEST_ALGO( replace_head, "abc3abc2", 3 C_ string("YYY"), string("YYY3abc2") ); - TEST_ALGO( replace_head, "abc3abc2", 3 C_ "YYY", string("YYY3abc2") ); - TEST_ALGO( replace_head, "abc", 3 C_ string("Z"), string("Z") ); - TEST_ALGO( replace_head, "abc", 6 C_ string("XXXX"), string("XXXX") ); - TEST_ALGO( replace_head, "abc3abc2", 0 C_ string("XXXX"), string("abc3abc2") ); - TEST_ALGO( replace_head, "", 4 C_ string("XXXX"), string("") ); - TEST_ALGO( erase_head, "abc3abc2", 3, string("3abc2") ); - TEST_ALGO( erase_head, "abc3abc2", 0, string("abc3abc2") ); - TEST_ALGO( erase_head, "", 4, string("") ); -} - -void replace_tail_test() -{ - // replace tail - TEST_ALGO( replace_tail, "abc3abc", 3 C_ string("YYY"), string("abc3YYY") ); - TEST_ALGO( replace_tail, "abc3abc", 3 C_ "YYY", string("abc3YYY") ); - TEST_ALGO( replace_tail, "abc", 3 C_ string("Z"), string("Z") ); - TEST_ALGO( replace_tail, "abc", 6 C_ string("XXXX"), string("XXXX") ); - TEST_ALGO( replace_tail, "abc3abc", 0 C_ string("XXXX"), string("abc3abc") ); - TEST_ALGO( replace_tail, "", 4 C_ string("XXXX"), string("") ); - TEST_ALGO( erase_tail, "abc3abc", 3, string("abc3") ); - TEST_ALGO( erase_tail, "abc3abc", 0, string("abc3abc") ); - TEST_ALGO( erase_tail, "", 4, string("") ); -} - -void replace_range_test() -{ - // replace_range - { - BOOST_CHECKPOINT( "replace_range" ); - - string str1("1abc3abc2"); - BOOST_CHECK( - replace_range_copy( - str1, - make_iterator_range(str1.begin()+1, str1.begin()+4), - string("XXX") )==string("1XXX3abc2") ); - - string strout; - replace_range_copy( - back_inserter( strout ), - str1, - make_iterator_range(str1.begin()+1, str1.begin()+4), - string("XXX") ); - BOOST_CHECK( strout==string("1XXX3abc2") ); - - replace_range( - str1, - make_iterator_range(str1.begin()+1, str1.begin()+4), - string("XXX") ); - BOOST_CHECK( str1==string("1XXX3abc2") ); - } - // erase_range - { - BOOST_CHECKPOINT( "erase_range" ); - - string str1("1abc3abc2"); - BOOST_CHECK( - erase_range_copy( - str1, - make_iterator_range(str1.begin()+1, str1.begin()+4))==string("13abc2") ); - - string strout; - erase_range_copy( - back_inserter( strout ), - str1, - make_iterator_range(str1.begin()+1, str1.begin()+4)); - BOOST_CHECK( strout==string("13abc2") ); - - erase_range( - str1, - make_iterator_range(str1.begin()+1, str1.begin()+4)); - BOOST_CHECK( str1==string("13abc2") ); - } -} - -void collection_comp_test() -{ - // container traits compatibility tests - { - string strout; - replace_first_copy( back_inserter(strout), "1abc3abc2", "abc", "YYY" ); - BOOST_CHECK( strout==string("1YYY3abc2") ); - } - { - string strout; - replace_last_copy( back_inserter(strout), "1abc3abc2", "abc", "YYY" ); - BOOST_CHECK( strout==string("1abc3YYY2") ); - } - { - string strout; - replace_all_copy( back_inserter(strout), "1abc3abc2", "abc", "YYY" ); - BOOST_CHECK( strout==string("1YYY3YYY2") ); - } - { - string strout; - replace_nth_copy( back_inserter(strout), "1abc3abc2", "abc", 1, "YYY" ); - BOOST_CHECK( strout==string("1abc3YYY2") ); - } - { - string strout; - replace_head_copy( back_inserter(strout), "abc3abc2", 3 , "YYY" ); - BOOST_CHECK( strout==string("YYY3abc2") ); - } - { - string strout; - replace_tail_copy( back_inserter(strout), "abc3abc", 3 , "YYY" ); - BOOST_CHECK( strout==string("abc3YYY") ); - } -} - -// test main -int test_main( int, char*[] ) -{ - sequence_traits_test(); - replace_first_test(); - replace_last_test(); - replace_all_test(); - replace_nth_test(); - replace_head_test(); - replace_tail_test(); - replace_range_test(); - collection_comp_test(); - - return 0; -} diff --git a/string/test/split_test.cpp b/string/test/split_test.cpp deleted file mode 100644 index f1de543..0000000 --- a/string/test/split_test.cpp +++ /dev/null @@ -1,133 +0,0 @@ -// Boost string_algo library iterator_test.cpp file ---------------------------// - -// Copyright Pavol Droba 2002-2003. Use, modification and -// distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -// equals predicate is used for result comparison -#include - -// Include unit test framework -#include - -#include -#include -#include - -#include - - -using namespace std; -using namespace boost; - -template< typename T1, typename T2 > -void deep_compare( const T1& X, const T2& Y ) -{ - BOOST_REQUIRE( X.size() == Y.size() ); - for( unsigned int nIndex=0; nIndex tokens; - vector< vector > vtokens; - - // find_all tests - find_all( - tokens, - pch1, - "xx" ); - - BOOST_REQUIRE( tokens.size()==2 ); - BOOST_CHECK( tokens[0]==string("xx") ); - BOOST_CHECK( tokens[1]==string("xx") ); - - ifind_all( - tokens, - str2, - "xx" ); - - BOOST_REQUIRE( tokens.size()==3 ); - BOOST_CHECK( tokens[0]==string("Xx") ); - BOOST_CHECK( tokens[1]==string("xX") ); - BOOST_CHECK( tokens[2]==string("xx") ); - - find_all( - tokens, - str1, - "xx" ); - - BOOST_REQUIRE( tokens.size()==2 ); - BOOST_CHECK( tokens[0]==string("xx") ); - BOOST_CHECK( tokens[1]==string("xx") ); - - find_all( - vtokens, - str1, - string("xx") ); - deep_compare( tokens, vtokens ); - - // split tests - split( - tokens, - str2, - is_any_of("xX"), - token_compress_on ); - - BOOST_REQUIRE( tokens.size()==4 ); - BOOST_CHECK( tokens[0]==string("") ); - BOOST_CHECK( tokens[1]==string("-abc--") ); - BOOST_CHECK( tokens[2]==string("-abb-") ); - BOOST_CHECK( tokens[3]==string("") ); - - split( - tokens, - pch1, - is_any_of("x"), - token_compress_on ); - - BOOST_REQUIRE( tokens.size()==3 ); - BOOST_CHECK( tokens[0]==string("") ); - BOOST_CHECK( tokens[1]==string("-abc--") ); - BOOST_CHECK( tokens[2]==string("-abb") ); - - split( - vtokens, - str1, - is_any_of("x"), - token_compress_on ); - deep_compare( tokens, vtokens ); - - split( - tokens, - str1, - is_punct(), - token_compress_off ); - - BOOST_REQUIRE( tokens.size()==5 ); - BOOST_CHECK( tokens[0]==string("xx") ); - BOOST_CHECK( tokens[1]==string("abc") ); - BOOST_CHECK( tokens[2]==string("") ); - BOOST_CHECK( tokens[3]==string("xx") ); - BOOST_CHECK( tokens[4]==string("abb") ); -} - -// test main -int test_main( int, char*[] ) -{ - iterator_test(); - - return 0; -} diff --git a/string/test/trim_test.cpp b/string/test/trim_test.cpp deleted file mode 100644 index ed80c28..0000000 --- a/string/test/trim_test.cpp +++ /dev/null @@ -1,118 +0,0 @@ -// Boost string_algo library trim_test.cpp file ---------------------------// - -// Copyright Pavol Droba 2002-2003. Use, modification and -// distribution is subject to 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) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -// Include unit test framework -#include - -#include -#include -#include - -using namespace std; -using namespace boost; - -void trim_test() -{ - string str1(" 1x x x x1 "); - string str2(" 2x x x x2 "); - string str3(" "); - - // *** value passing tests *** // - - // general string test - BOOST_CHECK( trim_left_copy( str1 )=="1x x x x1 " ) ; - BOOST_CHECK( trim_right_copy( str1 )==" 1x x x x1" ) ; - BOOST_CHECK( trim_copy( str1 )=="1x x x x1" ) ; - - // spaces-only string test - BOOST_CHECK( trim_left_copy( str3 )=="" ); - BOOST_CHECK( trim_right_copy( str3 )=="" ); - BOOST_CHECK( trim_copy( str3 )=="" ); - - // empty string check - BOOST_CHECK( trim_left_copy( string("") )=="" ); - BOOST_CHECK( trim_right_copy( string("") )=="" ); - BOOST_CHECK( trim_copy( string("") )=="" ); - - // iterator tests - string str; - trim_left_copy_if( std::back_inserter(str), str1, is_space() ); - BOOST_CHECK( str=="1x x x x1 " ); - - str.clear(); - trim_right_copy_if( std::back_inserter(str), str1, is_space() ); - BOOST_CHECK( str==" 1x x x x1" ); - - str.clear(); - trim_copy_if( std::back_inserter(str), str1, is_space() ); - BOOST_CHECK( str=="1x x x x1" ); - - str.clear(); - trim_left_copy_if( - std::back_inserter(str), - " 1x x x x1 ", - is_space() ); - BOOST_CHECK( str=="1x x x x1 " ); - - str.clear(); - trim_right_copy_if( - std::back_inserter(str), - " 1x x x x1 ", - is_space() ); - BOOST_CHECK( str==" 1x x x x1" ); - - str.clear(); - trim_copy_if( - std::back_inserter(str), - " 1x x x x1 ", - is_space() ); - BOOST_CHECK( str=="1x x x x1" ); - // *** inplace tests *** // - - // general string test - trim_left( str1 ); - BOOST_CHECK( str1=="1x x x x1 " ); - trim_right( str1 ); - BOOST_CHECK( str1=="1x x x x1" ); - trim( str2 ); - BOOST_CHECK( str2=="2x x x x2" ); - - // spaces-only string test - str3 = " "; trim_left( str3 ); - BOOST_CHECK( str3=="" ); - str3 = " "; trim_right( str3 ); - BOOST_CHECK( str3=="" ); - str3 = " "; trim( str3 ); - BOOST_CHECK( str3=="" ); - - // empty string check - str3 = ""; trim_left( str3 ); - BOOST_CHECK( str3=="" ); - str3 = ""; trim_right( str3 ); - BOOST_CHECK( str3=="" ); - str3 = ""; trim( str3 ); - BOOST_CHECK( str3=="" ); - - // *** non-standard predicate tests *** // - BOOST_CHECK( - trim_copy_if( - string("123abc456"), - is_classified(std::ctype_base::digit) )=="abc" ); - BOOST_CHECK( trim_copy_if( string("<>abc<>"), is_any_of( "<<>>" ) )=="abc" ); -} - -// test main -int test_main( int, char*[] ) -{ - trim_test(); - - return 0; -} diff --git a/sublibs b/sublibs deleted file mode 100644 index 721d7c4..0000000 --- a/sublibs +++ /dev/null @@ -1 +0,0 @@ -The existance of this file tells the regression reporting programs that the directory contains sub-directories which are libraries. \ No newline at end of file