summaryrefslogtreecommitdiff
path: root/libs/algorithm/string
diff options
context:
space:
mode:
Diffstat (limited to 'libs/algorithm/string')
-rw-r--r--libs/algorithm/string/doc/Jamfile.v259
-rw-r--r--libs/algorithm/string/doc/concept.xml205
-rw-r--r--libs/algorithm/string/doc/credits.xml25
-rw-r--r--libs/algorithm/string/doc/design.xml223
-rw-r--r--libs/algorithm/string/doc/environment.xml65
-rw-r--r--libs/algorithm/string/doc/external_concepts.html40
-rw-r--r--libs/algorithm/string/doc/intro.xml54
-rw-r--r--libs/algorithm/string/doc/quickref.xml758
-rw-r--r--libs/algorithm/string/doc/rationale.xml52
-rw-r--r--libs/algorithm/string/doc/release_notes.xml45
-rw-r--r--libs/algorithm/string/doc/string_algo.xml52
-rw-r--r--libs/algorithm/string/doc/usage.xml366
-rw-r--r--libs/algorithm/string/example/Jamfile18
-rw-r--r--libs/algorithm/string/example/conv_example.cpp41
-rw-r--r--libs/algorithm/string/example/find_example.cpp58
-rw-r--r--libs/algorithm/string/example/predicate_example.cpp61
-rw-r--r--libs/algorithm/string/example/regex_example.cpp42
-rw-r--r--libs/algorithm/string/example/replace_example.cpp89
-rw-r--r--libs/algorithm/string/example/rle_example.cpp248
-rw-r--r--libs/algorithm/string/example/split_example.cpp62
-rw-r--r--libs/algorithm/string/example/trim_example.cpp47
-rw-r--r--libs/algorithm/string/index.html14
-rw-r--r--libs/algorithm/string/test/Jamfile.v274
-rw-r--r--libs/algorithm/string/test/conv_test.cpp94
-rw-r--r--libs/algorithm/string/test/find_format_test.cpp162
-rw-r--r--libs/algorithm/string/test/find_test.cpp273
-rw-r--r--libs/algorithm/string/test/join_test.cpp78
-rw-r--r--libs/algorithm/string/test/predicate_test.cpp160
-rw-r--r--libs/algorithm/string/test/regex_test.cpp158
-rw-r--r--libs/algorithm/string/test/replace_test.cpp321
-rw-r--r--libs/algorithm/string/test/split_test.cpp193
-rw-r--r--libs/algorithm/string/test/trim_test.cpp202
32 files changed, 4339 insertions, 0 deletions
diff --git a/libs/algorithm/string/doc/Jamfile.v2 b/libs/algorithm/string/doc/Jamfile.v2
new file mode 100644
index 000000000..9ddebb8b6
--- /dev/null
+++ b/libs/algorithm/string/doc/Jamfile.v2
@@ -0,0 +1,59 @@
+# 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 autodoc
+ :
+ <xsl:param>boost.root=../../../../..
+ <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
+ ;
+
+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/iter_find.hpp ]
+ [ glob ../../../../boost/algorithm/string/erase.hpp ]
+ [ glob ../../../../boost/algorithm/string/join.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 ]
+ [ glob ../../../../boost/algorithm/string/trim_all.hpp ]
+ :
+ <doxygen:param>HIDE_UNDOC_MEMBERS=YES
+ <doxygen:param>EXTRACT_PRIVATE=NO
+ <doxygen:param>ENABLE_PREPROCESSING=YES
+ <doxygen:param>MACRO_EXPANSION=YES
+ <doxygen:param>EXPAND_ONLY_PREDEF=YES
+ <doxygen:param>SEARCH_INCLUDES=YES
+ <doxygen:param>PREDEFINED="BOOST_STRING_TYPENAME=typename \"BOOST_STATIC_CONSTANT(type,var)=static const type var;\""
+ ;
+
+
+
+
diff --git a/libs/algorithm/string/doc/concept.xml b/libs/algorithm/string/doc/concept.xml
new file mode 100644
index 000000000..4f17b43a0
--- /dev/null
+++ b/libs/algorithm/string/doc/concept.xml
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+<!-- Copyright (c) 2002-2006 Pavol Droba.
+ Subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+-->
+
+<section id="string_algo.concept" last-revision="$Date: 2012-12-28 10:19:25 -0800 (Fri, 28 Dec 2012) $">
+ <title>Concepts</title>
+
+ <using-namespace name="boost"/>
+ <using-namespace name="boost::algorithm"/>
+
+ <section>
+ <title>Definitions</title>
+
+ <table>
+ <title>Notation</title>
+ <tgroup cols="2" align="left">
+ <tbody>
+ <row>
+ <entry><code>F</code></entry>
+ <entry>A type that is a model of Finder</entry>
+ </row>
+ <row>
+ <entry><code>Fmt</code></entry>
+ <entry>A type that is a model of Formatter</entry>
+ </row>
+ <row>
+ <entry><code>Iter</code></entry>
+ <entry>
+ Iterator Type
+ </entry>
+ </row>
+ <row>
+ <entry><code>f</code></entry>
+ <entry>Object of type <code>F</code></entry>
+ </row>
+ <row>
+ <entry><code>fmt</code></entry>
+ <entry>Object of type <code>Fmt</code></entry>
+ </row>
+ <row>
+ <entry><code>i,j</code></entry>
+ <entry>Objects of type <code>Iter</code></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section id="string_algo.finder_concept">
+ <title>Finder Concept</title>
+
+ <para>
+ Finder is a functor which searches for an arbitrary part of a container.
+ The result of the search is given as an <classname>iterator_range</classname>
+ delimiting the selected part.
+ </para>
+
+ <table>
+ <title>Valid Expressions</title>
+ <tgroup cols="3" align="left">
+ <thead>
+ <row>
+ <entry>Expression</entry>
+ <entry>Return Type</entry>
+ <entry>Effects</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><code>f(i,j)</code></entry>
+ <entry>Convertible to <code>iterator_range&lt;Iter&gt;</code></entry>
+ <entry>Perform the search on the interval [i,j) and returns the result of the search</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ 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.
+ </para>
+ <para>
+ 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.
+ </para>
+ <para>
+ <emphasis role="bold">Examples</emphasis>
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ Finder implemented as a class. This Finder always returns the whole input as a match. <code>operator()</code>
+ is templated, so that the finder can be used on any iterator type.
+
+ <programlisting>
+struct simple_finder
+{
+ template&lt;typename ForwardIteratorT&gt;
+ boost::iterator_range&lt;ForwardIteratorT&gt; operator()(
+ ForwardIteratorT Begin,
+ ForwardIteratorT End )
+ {
+ return boost::make_range( Begin, End );
+ }
+};
+ </programlisting>
+ </listitem>
+ <listitem>
+ 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.
+
+ <programlisting>
+boost::iterator_range&lt;std::string&gt; simple_finder(
+ std::string::const_iterator Begin,
+ std::string::const_iterator End )
+{
+ return boost::make_range( Begin, End );
+}
+ </programlisting>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </section>
+ <section id="string_algo.formatter_concept">
+ <title>Formatter concept</title>
+
+ <para>
+ Formatters are used by <link linkend="string_algo.replace">replace algorithms</link>.
+ 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 <functionname>regex_formatter()</functionname> uses the match information from
+ <functionname>regex_finder()</functionname> to format the result of formatter operation.
+ </para>
+
+ <table>
+ <title>Valid Expressions</title>
+ <tgroup cols="3" align="left">
+ <thead>
+ <row>
+ <entry>Expression</entry>
+ <entry>Return Type</entry>
+ <entry>Effects</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><code>fmt(f(i,j))</code></entry>
+ <entry>A container type, accessible using container traits</entry>
+ <entry>Formats the result of the finder operation</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ 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 formatting
+ on it. Algorithms can abstract from formatting using a formatter.
+ </para>
+ <para>
+ <emphasis role="bold">Examples</emphasis>
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ Formatter implemented as a class. This Formatter does not perform any formatting and
+ returns the match, repackaged. <code>operator()</code>
+ is templated, so that the Formatter can be used on any Finder type.
+
+ <programlisting>
+struct simple_formatter
+{
+ template&lt;typename FindResultT&gt;
+ std::string operator()( const FindResultT&amp; Match )
+ {
+ std::string Temp( Match.begin(), Match.end() );
+ return Temp;
+ }
+};
+ </programlisting>
+ </listitem>
+ <listitem>
+ 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.
+
+ <programlisting>
+std::string simple_formatter( boost::iterator_range&lt;std::string::const_iterator&gt;&amp; Match )
+{
+ std::string Temp( Match.begin(), Match.end() );
+ return Temp;
+}
+ </programlisting>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </section>
+</section>
diff --git a/libs/algorithm/string/doc/credits.xml b/libs/algorithm/string/doc/credits.xml
new file mode 100644
index 000000000..c8959e9ab
--- /dev/null
+++ b/libs/algorithm/string/doc/credits.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+<!-- Copyright (c) 2002-2006 Pavol Droba.
+ Subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+-->
+
+<section id="string_algo.credits" last-revision="$Date: 2008-02-27 12:00:24 -0800 (Wed, 27 Feb 2008) $">
+ <title>Credits</title>
+ <section id="string_algo.ack">
+ <title>Acknowledgments</title>
+ <para>
+ 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.
+ </para>
+ <para>
+ Additional thanks go to Stefan Slapeta and Toon Knapen, who have been very resourceful in solving various
+ portability issues.
+ </para>
+ </section>
+</section>
diff --git a/libs/algorithm/string/doc/design.xml b/libs/algorithm/string/doc/design.xml
new file mode 100644
index 000000000..2d614a563
--- /dev/null
+++ b/libs/algorithm/string/doc/design.xml
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+
+<!-- Copyright (c) 2002-2006 Pavol Droba.
+ Subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+-->
+
+<section id="string_algo.design" last-revision="$Date: 2010-04-21 16:00:35 -0700 (Wed, 21 Apr 2010) $">
+ <title>Design Topics</title>
+
+ <using-namespace name="boost"/>
+ <using-namespace name="boost::algorithm"/>
+
+ <section id="string_algo.string">
+ <title>String Representation</title>
+
+ <para>
+ 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 <code>std::basic_string</code>),
+ rather it is a concept. This allows the algorithms in this library to be reused for any string type,
+ that satisfies the given requirements.
+ </para>
+ <para>
+ <emphasis role="bold">Definition:</emphasis> A string is a
+ <ulink url="../../libs/range/index.html">range</ulink> of characters accessible in sequential
+ ordered fashion. Character is any value type with "cheap" copying and assignment.
+ </para>
+ <para>
+ First requirement of string-type is that it must accessible using
+ <ulink url="../../libs/range/index.html">Boost.Range</ulink>. This facility allows to access
+ the elements inside the string in a uniform iterator-based fashion.
+ This is sufficient for our library
+ </para>
+ <para>
+ 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.
+ <para>
+ </para>
+ 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 &sect;23.1.1) requirements.
+ </para>
+ <para>
+ In the reference and also in the code, requirement on the string type is designated by the name of
+ template argument. <code>RangeT</code> means that the basic range requirements must hold.
+ <code>SequenceT</code> designates extended sequence requirements.
+ </para>
+ </section>
+
+ <section id="string_algo.sequence_traits">
+ <title>Sequence Traits</title>
+
+ <para>
+ The major difference between <code>std::list</code> and <code>std::vector</code> 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.
+ </para>
+ <para>
+ Sequence traits allow one to specify additional properties of a sequence container (see Std.&sect;32.2).
+ These properties are then used by algorithms to select optimized handling for some operations.
+ The sequence traits are declared in the header
+ <headername>boost/algorithm/string/sequence_traits.hpp</headername>.
+ </para>
+
+ <para>
+ In the table C denotes a container and c is an object of C.
+ </para>
+ <table>
+ <title>Sequence Traits</title>
+ <tgroup cols="2" align="left">
+ <thead>
+ <row>
+ <entry>Trait</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><classname>has_native_replace&lt;C&gt;</classname>::value</entry>
+ <entry>Specifies that the sequence has std::string like replace method</entry>
+ </row>
+ <row>
+ <entry><classname>has_stable_iterators&lt;C&gt;</classname>::value</entry>
+ <entry>
+ Specifies that the sequence has stable iterators. It means,
+ that operations like <code>insert</code>/<code>erase</code>/<code>replace</code>
+ do not invalidate iterators.
+ </entry>
+ </row>
+ <row>
+ <entry><classname>has_const_time_insert&lt;C&gt;</classname>::value</entry>
+ <entry>
+ Specifies that the insert method of the sequence has
+ constant time complexity.
+ </entry>
+ </row>
+ <row>
+ <entry><classname>has_const_time_erase&lt;C&gt;</classname>::value</entry>
+ <entry>
+ Specifies that the erase method of the sequence has constant time complexity
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Current implementation contains specializations for std::list&lt;T&gt; and
+ std::basic_string&lt;T&gt; from the standard library and SGI's std::rope&lt;T&gt; and std::slist&lt;T&gt;.
+ </para>
+ </section>
+ <section id="string_algo.find">
+ <title>Find Algorithms</title>
+
+ <para>
+ Find algorithms have similar functionality to <code>std::search()</code> 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.
+ </para>
+ <para>
+ Another difference is an addition of various searching methods besides find_first, including find_regex.
+ </para>
+ <para>
+ It the library, find algorithms are implemented in terms of
+ <link linkend="string_algo.finder_concept">Finders</link>. Finders are used also by other facilities
+ (replace,split).
+ For convenience, there are also function wrappers for these finders to simplify find operations.
+ </para>
+ <para>
+ 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 &lt;&lt; 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
+ </para>
+ </section>
+ <section id="string_algo.replace">
+ <title>Replace Algorithms</title>
+
+ <para>
+ 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 <link linkend="string_algo.finder_concept">Finder</link> object and a
+ <link linkend="string_algo.formatter_concept">Formatter</link> 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.
+ </para>
+ <para>
+ 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 <link linkend="string_algo.sequence_traits">Sequence traits</link>)
+ </para>
+ </section>
+ <section id="string_algo.split">
+ <title>Find Iterators &amp; Split Algorithms</title>
+
+ <para>
+ Find iterators are a logical extension of the <link linkend="string_algo.find">find facility</link>.
+ 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 (<classname>find_iterator</classname>) of the parts in
+ between (<classname>split_iterator</classname>).
+ </para>
+ <para>
+ In addition the split algorithms like <functionname>find_all()</functionname> and <functionname>split()</functionname>
+ 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.
+ </para>
+ </section>
+ <section id="string_algo.exception">
+ <title>Exception Safety</title>
+
+ <para>
+ The library requires that all operations on types used as template
+ or function arguments provide the <emphasis>basic exception-safety guarantee</emphasis>.
+ In turn, all functions and algorithms in this library, except where stated
+ otherwise, will provide the <emphasis>basic exception-safety guarantee</emphasis>.
+ 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.
+ </para>
+
+ <para>
+ Some functions can provide the <emphasis>strong exception-safety guarantee</emphasis>.
+ That means that following statements are true:
+ <itemizedlist>
+ <listitem>
+ If an exception is thrown, there are no effects other than those
+ of the function
+ </listitem>
+ <listitem>
+ If an exception is thrown other than by the function, there are no effects
+ </listitem>
+ </itemizedlist>
+ 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 .
+ </para>
+ <para>
+ In the reference, under the term <emphasis>strong exception-safety guarantee</emphasis>, we mean the
+ guarantee as defined above.
+ </para>
+ <para>
+ For more information about the exception safety topics, follow this
+ <ulink url="http://www.boost.org/more/generic_exception_safety.html">link</ulink>
+ </para>
+ </section>
+</section>
diff --git a/libs/algorithm/string/doc/environment.xml b/libs/algorithm/string/doc/environment.xml
new file mode 100644
index 000000000..3b65ce99d
--- /dev/null
+++ b/libs/algorithm/string/doc/environment.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+<!-- Copyright (c) 2002-2006 Pavol Droba.
+ Subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+-->
+
+<section id="string_algo.env" last-revision="$Date: 2008-02-27 12:00:24 -0800 (Wed, 27 Feb 2008) $">
+ <title>Environment</title>
+ <section>
+ <title>Build</title>
+ <para>
+ The whole library is provided in headers. Regex variants of some algorithms,
+ however, are dependent on the <libraryname>Boost.Regex</libraryname> library. All such algorithms are
+ separated in <headername>boost/algorithm/string_regex.hpp</headername>.
+ If this header is used, the application must be linked with the <libraryname>Boost.Regex</libraryname>
+ library.
+ </para>
+ </section>
+
+ <section>
+ <title>Examples</title>
+ <para>
+ 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 <libraryname>Boost.Regex</libraryname> library is required.
+ </para>
+ </section>
+
+ <section>
+ <title>Tests</title>
+ <para>
+ 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 <libraryname>Boost.Regex</libraryname> library is required.
+ </para>
+ </section>
+
+ <section>
+ <title>Portability</title>
+ <para>
+ The library has been successfully compiled and tested with the following compilers:
+
+ <itemizedlist>
+ <listitem>Microsoft Visual C++ 7.0</listitem>
+ <listitem>Microsoft Visual C++ 7.1</listitem>
+ <listitem>GCC 3.2</listitem>
+ <listitem>GCC 3.3.1</listitem>
+ </itemizedlist>
+
+ See <ulink url="http://boost.sourceforge.net/regression-logs/">Boost regression tables</ulink>
+ for additional info for a particular compiler.
+ </para>
+ <para>
+ There are known limitation on platforms not supporting partial template specialization.
+ Library depends on correctly implemented <code>std::iterator_traits</code> 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.
+ </para>
+ </section>
+</section>
diff --git a/libs/algorithm/string/doc/external_concepts.html b/libs/algorithm/string/doc/external_concepts.html
new file mode 100644
index 000000000..af403bebb
--- /dev/null
+++ b/libs/algorithm/string/doc/external_concepts.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title> Concepts and External Concepts </title><meta http-equiv="Content-Type"content="text/html; charset=iso-8859-1"></head> <body><table ><tr ><td ><img src="../../../../boost.png" width="100%" border="0"></td><td ><h1 >Concepts and External Concepts</h1></td></tr></table><p >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 <b>concept</b>. We say that a type <i>
+ conforms to a concept</i> or that it <i>is a model of a concept</i> 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.</p><p >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 <i> as if
+ </i> they fulfilled the concept. In this case we say that the concept has
+ been <b> externalized </b> or that the new requirements constitutes an <b>external
+ concept </b>. We say that a type <i> conforms to an external concept </i>
+ or that it <i> is a model of an external concept </i>. A concept may exist
+ without a corresponding external concept and conversely.</p><p >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 <b>type-generator</b>, that is, a type with a nested typedef
+ named <code>type</code>. The type-generator has the name as the nested typedef with
+ <code>_of</code> appended.
+ The converse relationship of an external concept and its corresponding concept
+ also holds.</p><p ><b ><i >Example:</i></b></p><p >A type <code>T</code> fulfills the FooConcept if it
+ has the follwing public members:</p><code> void T::foo( int ) const; <br>
+ int T::bar(); <br>
+ typedef <i>implementation defined </i> foo_type;</code><p >The corresponding external concept is the ExternalFooConcept.</p><p >A type <code>T</code> fullfills the ExternalFooConcept if these
+ free-standing functions and type-generators exists:</p><code>void foo( const T&, int ); <br>
+ int bar( T& ); <br>
+ foo_type_of< T >::type;</code> <br> <br><hr size="1" ><h3 >Literature</h3><ul ><li > <a href="http://www.boost.org/more/generic_programming.html#type_generator" target="_self" >Type Generators</a> </li><li > <a href="http://www.boost.org/more/generic_programming.html#concept" target="_self" >Concepts</a> </li><li > <a href="http://www.sgi.com/tech/stl/stl_introduction.html" target="_self" >Concepts and SGI STL</a> </li></ul><hr size="1" ><p >&copy; Thorsten Ottosen 2003-2004 (nesotto_AT_cs.auc.dk).
+<br>Use, modification and distribution is subject to the Boost
+ Software License, Version 1.0. (See accompanying file
+ <code class="filename">LICENSE_1_0.txt</code> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+</br>
+</p>
+ <!-- Copyright Dezide Aps 2003-2004 -->
diff --git a/libs/algorithm/string/doc/intro.xml b/libs/algorithm/string/doc/intro.xml
new file mode 100644
index 000000000..b2afe661c
--- /dev/null
+++ b/libs/algorithm/string/doc/intro.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+
+<!-- Copyright (c) 2002-2006 Pavol Droba.
+ Subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+-->
+
+<section id="string_algo.intro" last-revision="$Date: 2008-02-27 12:00:24 -0800 (Wed, 27 Feb 2008) $">
+ <title>Introduction</title>
+
+ <para>
+ 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.
+ </para>
+ <para>
+ The implementation is not restricted to work with a particular container
+ (like <code>std::basic_string</code>), 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.
+ </para>
+ <para>
+ <emphasis role="bold">
+ Important note: In this documentation we use term <emphasis>string</emphasis> to
+ designate a sequence of <emphasis>characters</emphasis> stored in an arbitrary container.
+ A <emphasis>string</emphasis> is not restricted to <code>std::basic_string</code> and
+ <emphasis>character</emphasis> does not have to be <code>char</code> or <code>wchar_t</code>,
+ although these are most common candidates.
+ </emphasis>
+ Consult the <link linkend="string_algo.design">design chapter</link> to see precise specification of
+ supported string types.
+ </para>
+ <para>
+ The library interface functions and classes are defined in namespace <code>boost::algorithm</code>, and
+ they are lifted into namespace <code>boost</code> via using declaration.
+ </para>
+ <para>
+ The documentation is divided into several sections. For a quick start read the
+ <link linkend="string_algo.usage">Usage</link> section followed by
+ <link linkend="string_algo.quickref">Quick Reference</link>.
+ <link linkend="string_algo.design">The Design Topics</link>,
+ <link linkend="string_algo.concept">Concepts</link> and <link linkend="string_algo.rationale">Rationale</link>
+ provide some explanation about the library design and structure an explain how it should be used.
+ See the <link linkend="string_algo.reference">Reference</link> 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.
+ </para>
+</section>
diff --git a/libs/algorithm/string/doc/quickref.xml b/libs/algorithm/string/doc/quickref.xml
new file mode 100644
index 000000000..8f495bc01
--- /dev/null
+++ b/libs/algorithm/string/doc/quickref.xml
@@ -0,0 +1,758 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+<!-- Copyright (c) 2002-2006 Pavol Droba.
+ Subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+-->
+
+<section id="string_algo.quickref" last-revision="$Date: 2012-01-15 08:49:25 -0800 (Sun, 15 Jan 2012) $">
+ <title>Quick Reference</title>
+
+ <using-namespace name="boost"/>
+ <using-namespace name="boost::algorithm"/>
+
+ <section>
+ <title>Algorithms</title>
+
+ <table>
+ <title>Case Conversion</title>
+ <tgroup cols="3" align="left">
+ <thead>
+ <row>
+ <entry>Algorithm name</entry>
+ <entry>Description</entry>
+ <entry>Functions</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><code>to_upper</code></entry>
+ <entry>Convert a string to upper case</entry>
+ <entry>
+ <functionname>to_upper_copy()</functionname>
+ <sbr/>
+ <functionname>to_upper()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry><code>to_lower</code></entry>
+ <entry>Convert a string to lower case</entry>
+ <entry>
+ <functionname>to_lower_copy()</functionname>
+ <sbr/>
+ <functionname>to_lower()</functionname>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <table>
+ <title>Trimming</title>
+ <tgroup cols="3" align="left">
+ <thead>
+ <row>
+ <entry>Algorithm name</entry>
+ <entry>Description</entry>
+ <entry>Functions</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><code>trim_left</code></entry>
+ <entry>Remove leading spaces from a string</entry>
+ <entry>
+ <functionname>trim_left_copy_if()</functionname>
+ <sbr/>
+ <functionname>trim_left_if()</functionname>
+ <sbr/>
+ <functionname>trim_left_copy()</functionname>
+ <sbr/>
+ <functionname>trim_left()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry><code>trim_right</code></entry>
+ <entry>Remove trailing spaces from a string</entry>
+ <entry>
+ <functionname>trim_right_copy_if()</functionname>
+ <sbr/>
+ <functionname>trim_right_if()</functionname>
+ <sbr/>
+ <functionname>trim_right_copy()</functionname>
+ <sbr/>
+ <functionname>trim_right()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry><code>trim</code></entry>
+ <entry>Remove leading and trailing spaces from a string</entry>
+ <entry>
+ <functionname>trim_copy_if()</functionname>
+ <sbr/>
+ <functionname>trim_if()</functionname>
+ <sbr/>
+ <functionname>trim_copy()</functionname>
+ <sbr/>
+ <functionname>trim()</functionname>
+ </entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+ <table>
+ <title>Predicates</title>
+ <tgroup cols="3" align="left">
+ <thead>
+ <row>
+ <entry>Algorithm name</entry>
+ <entry>Description</entry>
+ <entry>Functions</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><code>starts_with</code></entry>
+ <entry>Check if a string is a prefix of the other one</entry>
+ <entry>
+ <functionname>starts_with()</functionname>
+ <sbr/>
+ <functionname>istarts_with()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry><code>ends_with</code></entry>
+ <entry>Check if a string is a suffix of the other one</entry>
+ <entry>
+ <functionname>ends_with()</functionname>
+ <sbr/>
+ <functionname>iends_with()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry><code>contains</code></entry>
+ <entry>Check if a string is contained of the other one</entry>
+ <entry>
+ <functionname>contains()</functionname>
+ <sbr/>
+ <functionname>icontains()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry><code>equals</code></entry>
+ <entry>Check if two strings are equal</entry>
+ <entry>
+ <functionname>equals()</functionname>
+ <sbr/>
+ <functionname>iequals()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry><code>lexicographical_compare</code></entry>
+ <entry>Check if a string is lexicographically less then another one</entry>
+ <entry>
+ <functionname>lexicographical_compare()</functionname>
+ <sbr/>
+ <functionname>ilexicographical_compare()</functionname>
+ </entry>
+ </row>
+
+ <row>
+ <entry><code>all</code></entry>
+ <entry>Check if all elements of a string satisfy the given predicate</entry>
+ <entry>
+ <functionname>all()</functionname>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <table>
+ <title>Find algorithms</title>
+ <tgroup cols="3" align="left">
+ <thead>
+ <row>
+ <entry>Algorithm name</entry>
+ <entry>Description</entry>
+ <entry>Functions</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>find_first</entry>
+ <entry>Find the first occurrence of a string in the input</entry>
+ <entry>
+ <functionname>find_first()</functionname>
+ <sbr/>
+ <functionname>ifind_first()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>find_last</entry>
+ <entry>Find the last occurrence of a string in the input</entry>
+ <entry>
+ <functionname>find_last()</functionname>
+ <sbr/>
+ <functionname>ifind_last()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>find_nth</entry>
+ <entry>Find the nth (zero-indexed) occurrence of a string in the input</entry>
+ <entry>
+ <functionname>find_nth()</functionname>
+ <sbr/>
+ <functionname>ifind_nth()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>find_head</entry>
+ <entry>Retrieve the head of a string</entry>
+ <entry>
+ <functionname>find_head()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>find_tail</entry>
+ <entry>Retrieve the tail of a string</entry>
+ <entry>
+ <functionname>find_tail()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>find_token</entry>
+ <entry>Find first matching token in the string</entry>
+ <entry>
+ <functionname>find_token()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>find_regex</entry>
+ <entry>Use the regular expression to search the string</entry>
+ <entry>
+ <functionname>find_regex()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>find</entry>
+ <entry>Generic find algorithm</entry>
+ <entry>
+ <functionname>find()</functionname>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <table>
+ <title>Erase/Replace</title>
+ <tgroup cols="3" align="left">
+ <thead>
+ <row>
+ <entry>Algorithm name</entry>
+ <entry>Description</entry>
+ <entry>Functions</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>replace/erase_first</entry>
+ <entry>Replace/Erase the first occurrence of a string in the input</entry>
+ <entry>
+ <functionname>replace_first()</functionname>
+ <sbr/>
+ <functionname>replace_first_copy()</functionname>
+ <sbr/>
+ <functionname>ireplace_first()</functionname>
+ <sbr/>
+ <functionname>ireplace_first_copy()</functionname>
+ <sbr/>
+ <functionname>erase_first()</functionname>
+ <sbr/>
+ <functionname>erase_first_copy()</functionname>
+ <sbr/>
+ <functionname>ierase_first()</functionname>
+ <sbr/>
+ <functionname>ierase_first_copy()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>replace/erase_last</entry>
+ <entry>Replace/Erase the last occurrence of a string in the input</entry>
+ <entry>
+ <functionname>replace_last()</functionname>
+ <sbr/>
+ <functionname>replace_last_copy()</functionname>
+ <sbr/>
+ <functionname>ireplace_last()</functionname>
+ <sbr/>
+ <functionname>ireplace_last_copy()</functionname>
+ <sbr/>
+ <functionname>erase_last()</functionname>
+ <sbr/>
+ <functionname>erase_last_copy()</functionname>
+ <sbr/>
+ <functionname>ierase_last()</functionname>
+ <sbr/>
+ <functionname>ierase_last_copy()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>replace/erase_nth</entry>
+ <entry>Replace/Erase the nth (zero-indexed) occurrence of a string in the input</entry>
+ <entry>
+ <functionname>replace_nth()</functionname>
+ <sbr/>
+ <functionname>replace_nth_copy()</functionname>
+ <sbr/>
+ <functionname>ireplace_nth()</functionname>
+ <sbr/>
+ <functionname>ireplace_nth_copy()</functionname>
+ <sbr/>
+ <functionname>erase_nth()</functionname>
+ <sbr/>
+ <functionname>erase_nth_copy()</functionname>
+ <sbr/>
+ <functionname>ierase_nth()</functionname>
+ <sbr/>
+ <functionname>ierase_nth_copy()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>replace/erase_all</entry>
+ <entry>Replace/Erase the all occurrences of a string in the input</entry>
+ <entry>
+ <functionname>replace_all()</functionname>
+ <sbr/>
+ <functionname>replace_all_copy()</functionname>
+ <sbr/>
+ <functionname>ireplace_all()</functionname>
+ <sbr/>
+ <functionname>ireplace_all_copy()</functionname>
+ <sbr/>
+ <functionname>erase_all()</functionname>
+ <sbr/>
+ <functionname>erase_all_copy()</functionname>
+ <sbr/>
+ <functionname>ierase_all()</functionname>
+ <sbr/>
+ <functionname>ierase_all_copy()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>replace/erase_head</entry>
+ <entry>Replace/Erase the head of the input</entry>
+ <entry>
+ <functionname>replace_head()</functionname>
+ <sbr/>
+ <functionname>replace_head_copy()</functionname>
+ <sbr/>
+ <functionname>erase_head()</functionname>
+ <sbr/>
+ <functionname>erase_head_copy()</functionname>
+ <sbr/>
+ </entry>
+ </row>
+ <row>
+ <entry>replace/erase_tail</entry>
+ <entry>Replace/Erase the tail of the input</entry>
+ <entry>
+ <functionname>replace_tail()</functionname>
+ <sbr/>
+ <functionname>replace_tail_copy()</functionname>
+ <sbr/>
+ <functionname>erase_tail()</functionname>
+ <sbr/>
+ <functionname>erase_tail_copy()</functionname>
+ <sbr/>
+ </entry>
+ </row>
+ <row>
+ <entry>replace/erase_regex</entry>
+ <entry>Replace/Erase a substring matching the given regular expression</entry>
+ <entry>
+ <functionname>replace_regex()</functionname>
+ <sbr/>
+ <functionname>replace_regex_copy()</functionname>
+ <sbr/>
+ <functionname>erase_regex()</functionname>
+ <sbr/>
+ <functionname>erase_regex_copy()</functionname>
+ <sbr/>
+ </entry>
+ </row>
+ <row>
+ <entry>replace/erase_regex_all</entry>
+ <entry>Replace/Erase all substrings matching the given regular expression</entry>
+ <entry>
+ <functionname>replace_all_regex()</functionname>
+ <sbr/>
+ <functionname>replace_all_regex_copy()</functionname>
+ <sbr/>
+ <functionname>erase_all_regex()</functionname>
+ <sbr/>
+ <functionname>erase_all_regex_copy()</functionname>
+ <sbr/>
+ </entry>
+ </row>
+ <row>
+ <entry>find_format</entry>
+ <entry>Generic replace algorithm</entry>
+ <entry>
+ <functionname>find_format()</functionname>
+ <sbr/>
+ <functionname>find_format_copy()</functionname>
+ <sbr/>
+ <functionname>find_format_all()</functionname>
+ <sbr/>
+ <functionname>find_format_all_copy()()</functionname>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <table>
+ <title>Split</title>
+ <tgroup cols="3" align="left">
+ <thead>
+ <row>
+ <entry>Algorithm name</entry>
+ <entry>Description</entry>
+ <entry>Functions</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>find_all</entry>
+ <entry>Find/Extract all matching substrings in the input</entry>
+ <entry>
+ <functionname>find_all()</functionname>
+ <sbr/>
+ <functionname>ifind_all()</functionname>
+ <sbr/>
+ <functionname>find_all_regex()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>split</entry>
+ <entry>Split input into parts</entry>
+ <entry>
+ <functionname>split()</functionname>
+ <sbr/>
+ <functionname>split_regex()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>iter_find</entry>
+ <entry>Iteratively apply the finder to the input to find all matching substrings</entry>
+ <entry>
+ <functionname>iter_find()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>iter_split</entry>
+ <entry>Use the finder to find matching substrings in the input and use them as separators to split the input into parts</entry>
+ <entry>
+ <functionname>iter_split()</functionname>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <table>
+ <title>Join</title>
+ <tgroup cols="3" align="left">
+ <thead>
+ <row>
+ <entry>Algorithm name</entry>
+ <entry>Description</entry>
+ <entry>Functions</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>join</entry>
+ <entry>Join all elements in a container into a single string</entry>
+ <entry>
+ <functionname>join</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>join_if</entry>
+ <entry>Join all elements in a container that satisfies the condition into a single string</entry>
+ <entry>
+ <functionname>join_if()</functionname>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>Finders and Formatters</title>
+
+ <table>
+ <title>Finders</title>
+ <tgroup cols="3" align="left">
+ <thead>
+ <row>
+ <entry>Finder</entry>
+ <entry>Description</entry>
+ <entry>Generators</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>first_finder</entry>
+ <entry>Search for the first match of the string in an input</entry>
+ <entry>
+ <functionname>first_finder()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>last_finder</entry>
+ <entry>Search for the last match of the string in an input</entry>
+ <entry>
+ <functionname>last_finder()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>nth_finder</entry>
+ <entry>Search for the nth (zero-indexed) match of the string in an input</entry>
+ <entry>
+ <functionname>nth_finder()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>head_finder</entry>
+ <entry>Retrieve the head of an input</entry>
+ <entry>
+ <functionname>head_finder()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>tail_finder</entry>
+ <entry>Retrieve the tail of an input</entry>
+ <entry>
+ <functionname>tail_finder()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>token_finder</entry>
+ <entry>Search for a matching token in an input</entry>
+ <entry>
+ <functionname>token_finder()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>range_finder</entry>
+ <entry>Do no search, always returns the given range</entry>
+ <entry>
+ <functionname>range_finder()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>regex_finder</entry>
+ <entry>Search for a substring matching the given regex</entry>
+ <entry>
+ <functionname>regex_finder()</functionname>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table>
+ <title>Formatters</title>
+ <tgroup cols="3" align="left">
+ <thead>
+ <row>
+ <entry>Formatter</entry>
+ <entry>Description</entry>
+ <entry>Generators</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>const_formatter</entry>
+ <entry>Constant formatter. Always return the specified string</entry>
+ <entry>
+ <functionname>const_formatter()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>identity_formatter</entry>
+ <entry>Identity formatter. Return unmodified input input</entry>
+ <entry>
+ <functionname>identity_formatter()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>empty_formatter</entry>
+ <entry>Null formatter. Always return an empty string</entry>
+ <entry>
+ <functionname>empty_formatter()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>regex_formatter</entry>
+ <entry>Regex formatter. Format regex match using the specification in the format string</entry>
+ <entry>
+ <functionname>regex_formatter()</functionname>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>Iterators</title>
+
+ <table>
+ <title>Find Iterators</title>
+ <tgroup cols="3" align="left">
+ <thead>
+ <row>
+ <entry>Iterator name</entry>
+ <entry>Description</entry>
+ <entry>Iterator class</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>find_iterator</entry>
+ <entry>Iterates through matching substrings in the input</entry>
+ <entry>
+ <classname>find_iterator</classname>
+ </entry>
+ </row>
+ <row>
+ <entry>split_iterator</entry>
+ <entry>Iterates through gaps between matching substrings in the input</entry>
+ <entry>
+ <classname>split_iterator</classname>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ <section>
+ <title>Classification</title>
+
+ <table>
+ <title>Predicates</title>
+ <tgroup cols="3" align="left">
+ <thead>
+ <row>
+ <entry>Predicate name</entry>
+ <entry>Description</entry>
+ <entry>Generator</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>is_classified</entry>
+ <entry>Generic <code>ctype</code> mask based classification</entry>
+ <entry>
+ <functionname>is_classified()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>is_space</entry>
+ <entry>Recognize spaces</entry>
+ <entry>
+ <functionname>is_space()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>is_alnum</entry>
+ <entry>Recognize alphanumeric characters</entry>
+ <entry>
+ <functionname>is_alnum()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>is_alpha</entry>
+ <entry>Recognize letters</entry>
+ <entry>
+ <functionname>is_alpha()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>is_cntrl</entry>
+ <entry>Recognize control characters</entry>
+ <entry>
+ <functionname>is_cntrl()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>is_digit</entry>
+ <entry>Recognize decimal digits</entry>
+ <entry>
+ <functionname>is_digit()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>is_graph</entry>
+ <entry>Recognize graphical characters</entry>
+ <entry>
+ <functionname>is_graph()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>is_lower</entry>
+ <entry>Recognize lower case characters</entry>
+ <entry>
+ <functionname>is_lower()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>is_print</entry>
+ <entry>Recognize printable characters</entry>
+ <entry>
+ <functionname>is_print()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>is_punct</entry>
+ <entry>Recognize punctuation characters</entry>
+ <entry>
+ <functionname>is_punct()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>is_upper</entry>
+ <entry>Recognize uppercase characters</entry>
+ <entry>
+ <functionname>is_upper()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>is_xdigit</entry>
+ <entry>Recognize hexadecimal digits</entry>
+ <entry>
+ <functionname>is_xdigit()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>is_any_of</entry>
+ <entry>Recognize any of a sequence of characters</entry>
+ <entry>
+ <functionname>is_any_of()</functionname>
+ </entry>
+ </row>
+ <row>
+ <entry>is_from_range</entry>
+ <entry>Recognize characters inside a min..max range</entry>
+ <entry>
+ <functionname>is_from_range()</functionname>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+</section>
diff --git a/libs/algorithm/string/doc/rationale.xml b/libs/algorithm/string/doc/rationale.xml
new file mode 100644
index 000000000..fe4e8f1c3
--- /dev/null
+++ b/libs/algorithm/string/doc/rationale.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+<!-- Copyright (c) 2002-2006 Pavol Droba.
+ Subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+-->
+
+<section id="string_algo.rationale" last-revision="$Date: 2008-02-27 12:00:24 -0800 (Wed, 27 Feb 2008) $">
+ <title>Rationale</title>
+
+ <using-namespace name="boost"/>
+ <using-namespace name="boost::algorithm"/>
+
+ <section it="string_algo.locale">
+ <title>Locales</title>
+
+ <para>
+ 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.
+ </para>
+ <para>
+ 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.
+ </para>
+ <para>
+ Fortunately, the C++ standard allows to specify the <emphasis>global</emphasis> locales (using static member
+ function <code>std:locale::global()</code>). When instantiating an
+ <code>std::locale</code> class without explicit information, the instance will
+ be initialized with the <emphasis>global</emphasis> locale. This implies, that if an algorithm needs a locale,
+ it should have an <code>std::locale</code> parameter defaulting to <code>std::locale()</code>.
+ If a user needs to specify locales explicitly, she can do so. Otherwise the <emphasis>global</emphasis>
+ locales are used.
+ </para>
+ </section>
+ <section id="string_algo.regex">
+ <title>Regular Expressions</title>
+
+ <para>
+ 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
+ <libraryname>Boost.Regex</libraryname>; 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.
+ </para>
+ </section>
+</section>
diff --git a/libs/algorithm/string/doc/release_notes.xml b/libs/algorithm/string/doc/release_notes.xml
new file mode 100644
index 000000000..ba2a39c5d
--- /dev/null
+++ b/libs/algorithm/string/doc/release_notes.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+<!-- Copyright (c) 2002-2006 Pavol Droba.
+ Subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+-->
+
+<section id="string_algo.release_notes" last-revision="$Date: 2012-12-28 10:19:25 -0800 (Fri, 28 Dec 2012) $">
+
+ <using-namespace name="boost"/>
+ <using-namespace name="boost::algorithm"/>
+
+ <title>Release Notes</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">1.32</emphasis></para>
+ <para>Initial release in Boost</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">1.33</emphasis></para>
+ <para>Internal version of collection traits removed, library adapted to Boost.Range</para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">1.34</emphasis></para>
+ <itemizedlist>
+ <listitem>
+ <functionname>lexicographical_compare()</functionname>
+ </listitem>
+ <listitem>
+ <functionname>join()</functionname> and <functionname>join_if()</functionname>
+ </listitem>
+ <listitem>
+ New comparison predicates <code>is_less</code>, <code>is_not_greater</code>
+ </listitem>
+ <listitem>
+ Negative indexes support (like Perl) in various algorithms
+ (<code>*_head/tail</code>, <code>*_nth</code>).
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+</section>
diff --git a/libs/algorithm/string/doc/string_algo.xml b/libs/algorithm/string/doc/string_algo.xml
new file mode 100644
index 000000000..1eb4a2c8d
--- /dev/null
+++ b/libs/algorithm/string/doc/string_algo.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+<!-- Copyright (c) 2002-2006 Pavol Droba.
+ Subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+-->
+
+<library name="String Algorithms" dirname="algorithm/string" xmlns:xi="http://www.w3.org/2001/XInclude"
+ id="string_algo" last-revision="$Date: 2010-07-10 13:29:03 -0700 (Sat, 10 Jul 2010) $">
+ <libraryinfo>
+ <author>
+ <firstname>Pavol</firstname>
+ <surname>Droba</surname>
+ </author>
+
+ <copyright>
+ <year>2002</year>
+ <year>2003</year>
+ <year>2004</year>
+ <holder>Pavol Droba</holder>
+ </copyright>
+
+ <legalnotice>
+ <para>Use, modification and distribution is subject to the Boost
+ Software License, Version 1.0. (See accompanying file
+ <filename>LICENSE_1_0.txt</filename> or copy at <ulink
+ url="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</ulink>)
+ </para>
+ </legalnotice>
+
+ <librarypurpose>
+ A set of generic string-related algorithms and utilities
+ </librarypurpose>
+ <librarycategory name="category:algorithms"/>
+ <librarycategory name="category:string-text"/>
+ </libraryinfo>
+
+ <title>Boost String Algorithms Library</title>
+ <xi:include href="intro.xml"/>
+ <xi:include href="release_notes.xml"/>
+ <xi:include href="usage.xml"/>
+ <xi:include href="quickref.xml"/>
+ <xi:include href="design.xml"/>
+ <xi:include href="concept.xml"/>
+ <xi:include href="autodoc.xml"/>
+ <xi:include href="rationale.xml"/>
+ <xi:include href="environment.xml"/>
+ <xi:include href="credits.xml"/>
+</library>
+
diff --git a/libs/algorithm/string/doc/usage.xml b/libs/algorithm/string/doc/usage.xml
new file mode 100644
index 000000000..4d14ee16c
--- /dev/null
+++ b/libs/algorithm/string/doc/usage.xml
@@ -0,0 +1,366 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+
+<!-- Copyright (c) 2002-2006 Pavol Droba.
+ Subject to the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+-->
+
+
+<section id="string_algo.usage" last-revision="$Date: 2013-05-22 08:10:49 -0700 (Wed, 22 May 2013) $">
+ <title>Usage</title>
+
+ <using-namespace name="boost"/>
+ <using-namespace name="boost::algorithm"/>
+
+
+ <section>
+ <title>First Example</title>
+
+ <para>
+ Using the algorithms is straightforward. Let us have a look at the first example:
+ </para>
+ <programlisting>
+ #include &lt;boost/algorithm/string.hpp&gt;
+ 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!"
+ </programlisting>
+ <para>
+ 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:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para><emphasis role="bold">Container parameters:</emphasis>
+ 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 <emphasis>stack</emphasis> 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
+ <code>to_lower(str1)</code>, than <code>to_lower(str1.begin(), str1.end())</code>.
+ </para>
+ <para>
+ The magic of <ulink url="../../libs/range/index.html">Boost.Range</ulink>
+ provides a uniform way of handling different string types.
+ If there is a need to pass a pair of iterators,
+ <ulink url="../../libs/range/doc/html/range/reference/utilities/iterator_range.html"><code>boost::iterator_range</code></ulink>
+ can be used to package iterators into a structure with a compatible interface.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Copy vs. Mutable:</emphasis>
+ 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.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Algorithm stacking:</emphasis>
+ Copy versions return a transformed input as a result, thus allow a simple chaining of
+ transformations within one expression (i.e. one can write <code>trim_copy(to_upper_copy(s))</code>).
+ Mutable versions have <code>void</code> return, to avoid misuse.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis role="bold">Naming:</emphasis>
+ 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 <emphasis>_copy</emphasis>.
+ Some algorithms have the prefix <emphasis>i</emphasis>
+ (e.g. <functionname>ifind_first()</functionname>).
+ This prefix identifies that the algorithm works in a case-insensitive manner.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ To use the library, include the <headername>boost/algorithm/string.hpp</headername> header.
+ If the regex related functions are needed, include the
+ <headername>boost/algorithm/string_regex.hpp</headername> header.
+ </para>
+ </section>
+ <section>
+ <title>Case conversion</title>
+
+ <para>
+ STL has a nice way of converting character case. Unfortunately, it works only
+ for a single character and we want to convert a string,
+ </para>
+ <programlisting>
+ string str1("HeLlO WoRld!");
+ to_upper(str1); // str1=="HELLO WORLD!"
+ </programlisting>
+ <para>
+ <functionname>to_upper()</functionname> and <functionname>to_lower()</functionname> convert the case of
+ characters in a string using a specified locale.
+ </para>
+ <para>
+ For more information see the reference for <headername>boost/algorithm/string/case_conv.hpp</headername>.
+ </para>
+ </section>
+ <section>
+ <title>Predicates and Classification</title>
+ <para>
+ A part of the library deals with string related predicates. Consider this example:
+ </para>
+ <programlisting>
+ bool is_executable( string&amp; filename )
+ {
+ return
+ iends_with(filename, ".exe") ||
+ iends_with(filename, ".com");
+ }
+
+ // ...
+ string str1("command.com");
+ cout
+ &lt;&lt; str1
+ &lt;&lt; (is_executable(str1)? "is": "is not")
+ &lt;&lt; "an executable"
+ &lt;&lt; endl; // prints "command.com is an executable"
+
+ //..
+ char text1[]="hello";
+ cout
+ &lt;&lt; text1
+ &lt;&lt; (all( text1, is_lower() )? " is": " is not")
+ &lt;&lt; " written in the lower case"
+ &lt;&lt; endl; // prints "hello is written in the lower case"
+ </programlisting>
+ <para>
+ 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
+ <headername>boost/algorithm/string/predicate.hpp</headername> for more details.
+ </para>
+ <para>
+ Note that if we had used "hello world" as the input to the test, it would have
+ output "hello world is not written in the lower case" because the space in the
+ input string is not a lower case letter.
+ </para>
+ <para>
+ In addition the algorithm <functionname>all()</functionname> checks
+ all elements of a container to satisfy a condition specified by a predicate.
+ 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 <headername>boost/algorithm/string/classification.hpp</headername> header.
+ Classification predicates can be combined using logical combinators to form
+ a more complex expressions. For example: <code>is_from_range('a','z') || is_digit()</code>
+ </para>
+ </section>
+ <section>
+ <title>Trimming</title>
+
+ <para>
+ When parsing the input from a user, strings often have unwanted leading or trailing
+ characters. To get rid of them, we need trim functions:
+ </para>
+ <programlisting>
+ string str1=" hello world! ";
+ string str2=trim_left_copy(str1); // str2 == "hello world! "
+ string str3=trim_right_copy(str1); // 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"
+ </programlisting>
+ <para>
+ 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 <emphasis>_if</emphasis> variants. Using these, a user can specify a functor which will
+ select the <emphasis>space</emphasis> to be removed. It is possible to use classification
+ predicates like <functionname>is_digit()</functionname> mentioned in the previous paragraph.
+ See the reference for the <headername>boost/algorithm/string/trim.hpp</headername>.
+ </para>
+ </section>
+ <section>
+ <title>Find algorithms</title>
+
+ <para>
+ The library contains a set of find algorithms. Here is an example:
+ </para>
+ <programlisting>
+ char text[]="hello dolly!";
+ iterator_range&lt;char*&gt; result=find_last(text,"ll");
+
+ transform( result.begin(), result.end(), result.begin(), bind2nd(plus&lt;char&gt;(), 1) );
+ // text = "hello dommy!"
+
+ to_upper(result); // text == "hello doMMy!"
+
+ // iterator_range is convertible to bool
+ if(find_first(text, "dolly"))
+ {
+ cout &lt;&lt; "Dolly is there" &lt;&lt; endl;
+ }
+ </programlisting>
+ <para>
+ We have used <functionname>find_last()</functionname> to search the <code>text</code> for "ll".
+ The result is given in the <ulink url="../../libs/range/doc/html/range/reference/utilities/iterator_range.html"><code>boost::iterator_range</code></ulink>.
+ 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 <functionname>find_last()</functionname> algorithm can be also
+ char[] because this type is supported by
+ <ulink url="../../libs/range/index.html">Boost.Range</ulink>.
+
+ The following lines transform the result. Notice that
+ <ulink url="../../libs/range/doc/html/range/reference/utilities/iterator_range.html"><code>boost::iterator_range</code></ulink> has familiar
+ <code>begin()</code> and <code>end()</code> 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.
+ </para>
+ <para>
+ Find algorithms are located in <headername>boost/algorithm/string/find.hpp</headername>.
+ </para>
+ </section>
+ <section>
+ <title>Replace Algorithms</title>
+ <para>
+ 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.
+ </para>
+ <programlisting>
+ 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!"
+ </programlisting>
+ <para>
+ For the complete list of replace and erase functions see the
+ <link linkend="string_algo.reference">reference</link>.
+ There is a lot of predefined function for common usage, however, the library allows you to
+ define a custom <code>replace()</code> that suits a specific need. There is a generic <functionname>find_format()</functionname>
+ function which takes two parameters.
+ The first one is a <link linkend="string_algo.finder_concept">Finder</link> object, the second one is
+ a <link linkend="string_algo.formatter_concept">Formatter</link> 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.
+ </para>
+ <para>
+ Check <headername>boost/algorithm/string/replace.hpp</headername>, <headername>boost/algorithm/string/erase.hpp</headername> and
+ <headername>boost/algorithm/string/find_format.hpp</headername> for reference.
+ </para>
+ </section>
+ <section>
+ <title>Find Iterator</title>
+
+ <para>
+ 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 <link linkend="string_algo.finder_concept">Finder</link> to incrementally
+ search the string.
+ Dereferencing a find iterator yields an <ulink url="../../libs/range/doc/html/range/reference/utilities/iterator_range.html"><code>boost::iterator_range</code></ulink>
+ object, that delimits the current match.
+ </para>
+ <para>
+ There are two iterators provided <classname>find_iterator</classname> and
+ <classname>split_iterator</classname>. The former iterates over substrings that are found using the specified
+ Finder. The latter iterates over the gaps between these substrings.
+ </para>
+ <programlisting>
+ string str1("abc-*-ABC-*-aBc");
+ // Find all 'abc' substrings (ignoring the case)
+ // Create a find_iterator
+ typedef find_iterator&lt;string::iterator&gt; string_find_iterator;
+ for(string_find_iterator It=
+ make_find_iterator(str1, first_finder("abc", is_iequal()));
+ It!=string_find_iterator();
+ ++It)
+ {
+ cout &lt;&lt; copy_range&lt;std::string&gt;(*It) &lt;&lt; endl;
+ }
+
+ // Output will be:
+ // abc
+ // ABC
+ // aBC
+
+ typedef split_iterator&lt;string::iterator&gt; string_split_iterator;
+ for(string_split_iterator It=
+ make_split_iterator(str1, first_finder("-*-", is_iequal()));
+ It!=string_split_iterator();
+ ++It)
+ {
+ cout &lt;&lt; copy_range&lt;std::string&gt;(*It) &lt;&lt; endl;
+ }
+
+ // Output will be:
+ // abc
+ // ABC
+ // aBC
+ </programlisting>
+ <para>
+ 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.
+ </para>
+ <para>
+ See the reference in <headername>boost/algorithm/string/find_iterator.hpp</headername>.
+ </para>
+ </section>
+ <section>
+ <title>Split</title>
+
+ <para>
+ 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. <code>std::string</code>) or
+ references (e.g. <code>iterator_range</code>) of the extracted substrings.
+ </para>
+ <para>
+ Two algorithms are provided. <functionname>find_all()</functionname> finds all copies
+ of a string in the input. <functionname>split()</functionname> splits the input into parts.
+ </para>
+
+ <programlisting>
+ string str1("hello abc-*-ABC-*-aBc goodbye");
+
+ typedef vector&lt; iterator_range&lt;string::iterator&gt; &gt; find_vector_type;
+
+ find_vector_type FindVec; // #1: Search for separators
+ ifind_all( FindVec, str1, "abc" ); // FindVec == { [abc],[ABC],[aBc] }
+
+ typedef vector&lt; string &gt; split_vector_type;
+
+ split_vector_type SplitVec; // #2: Search for tokens
+ split( SplitVec, str1, is_any_of("-*"), token_compress_on ); // SplitVec == { "hello abc","ABC","aBc goodbye" }
+ </programlisting>
+ <para>
+ <code>[hello]</code> designates an <code>iterator_range</code> delimiting this substring.
+ </para>
+ <para>
+ First example show how to construct a container to hold references to all extracted
+ substrings. Algorithm <functionname>ifind_all()</functionname> puts into FindVec references
+ to all substrings that are in case-insensitive manner equal to "abc".
+ </para>
+ <para>
+ Second example uses <functionname>split()</functionname> 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.
+ </para>
+ <para>
+ More information can be found in the reference: <headername>boost/algorithm/string/split.hpp</headername>.
+ </para>
+ </section>
+</section>
diff --git a/libs/algorithm/string/example/Jamfile b/libs/algorithm/string/example/Jamfile
new file mode 100644
index 000000000..74c923f8b
--- /dev/null
+++ b/libs/algorithm/string/example/Jamfile
@@ -0,0 +1,18 @@
+# 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.
+
+
+exe conv_example : conv_example.cpp ;
+exe predicate_example : predicate_example.cpp ;
+exe find_example : find_example.cpp ;
+exe replace_example : replace_example.cpp ;
+exe rle_example : rle_example.cpp ;
+exe trim_example : trim_example.cpp ;
+exe regex_example : regex_example.cpp /boost/regex//boost_regex ;
+exe split_example : split_example.cpp ; \ No newline at end of file
diff --git a/libs/algorithm/string/example/conv_example.cpp b/libs/algorithm/string/example/conv_example.cpp
new file mode 100644
index 000000000..b6a08f9ca
--- /dev/null
+++ b/libs/algorithm/string/example/conv_example.cpp
@@ -0,0 +1,41 @@
+// 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 <string>
+#include <vector>
+#include <iostream>
+#include <iterator>
+#include <boost/algorithm/string/case_conv.hpp>
+
+using namespace std;
+using namespace boost;
+
+int main()
+{
+ cout << "* Case Conversion Example *" << endl << endl;
+
+ string str1("AbCdEfG");
+ vector<char> vec1( str1.begin(), str1.end() );
+
+ // Convert vector of chars to lower case
+ cout << "lower-cased copy of vec1: ";
+ to_lower_copy( ostream_iterator<char>(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/libs/algorithm/string/example/find_example.cpp b/libs/algorithm/string/example/find_example.cpp
new file mode 100644
index 000000000..7fd7e60a1
--- /dev/null
+++ b/libs/algorithm/string/example/find_example.cpp
@@ -0,0 +1,58 @@
+// 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 <string>
+#include <iostream>
+#include <algorithm>
+#include <functional>
+#include <boost/algorithm/string/case_conv.hpp>
+#include <boost/algorithm/string/find.hpp>
+
+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<string::iterator> 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<string::iterator> 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<char*> crange=find_last(text,"ll");
+
+ // transform the range ( add 1 )
+ transform( crange.begin(), crange.end(), crange.begin(), bind2nd( plus<char>(), 1 ) );
+ // uppercase the range
+ to_upper( crange );
+
+ cout << text << endl;
+
+ cout << endl;
+
+ return 0;
+}
diff --git a/libs/algorithm/string/example/predicate_example.cpp b/libs/algorithm/string/example/predicate_example.cpp
new file mode 100644
index 000000000..473ab8b57
--- /dev/null
+++ b/libs/algorithm/string/example/predicate_example.cpp
@@ -0,0 +1,61 @@
+// 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 <string>
+#include <iostream>
+#include <functional>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/bind.hpp>
+
+
+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 contains '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/libs/algorithm/string/example/regex_example.cpp b/libs/algorithm/string/example/regex_example.cpp
new file mode 100644
index 000000000..9eba1c73a
--- /dev/null
+++ b/libs/algorithm/string/example/regex_example.cpp
@@ -0,0 +1,42 @@
+// 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 <string>
+#include <iostream>
+#include <iterator>
+#include <boost/regex.hpp>
+#include <boost/algorithm/string/regex.hpp>
+
+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/libs/algorithm/string/example/replace_example.cpp b/libs/algorithm/string/example/replace_example.cpp
new file mode 100644
index 000000000..12089fa2d
--- /dev/null
+++ b/libs/algorithm/string/example/replace_example.cpp
@@ -0,0 +1,89 @@
+// 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 <string>
+#include <iostream>
+#include <iterator>
+//#include <boost/algorithm/string/replace.hpp>
+//#include <boost/algorithm/string/erase.hpp>
+//#include <boost/algorithm/string/case_conv.hpp>
+#include <boost/algorithm/string.hpp>
+
+//Following two includes contain second-layer function.
+//They are already included by first-layer header
+
+//#include <boost/algorithm/string/replace2.hpp>
+//#include <boost/algorithm/string/find2.hpp>
+
+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<string::const_iterator>& 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<char>(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/libs/algorithm/string/example/rle_example.cpp b/libs/algorithm/string/example/rle_example.cpp
new file mode 100644
index 000000000..9e52b96b3
--- /dev/null
+++ b/libs/algorithm/string/example/rle_example.cpp
@@ -0,0 +1,248 @@
+// 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 <string>
+#include <iostream>
+#include <limits>
+#include <boost/detail/iterator.hpp>
+#include <boost/algorithm/string/find_format.hpp>
+#include <boost/algorithm/string/finder.hpp>
+
+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<T>::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<typename ForwardIteratorT>
+ iterator_range<ForwardIteratorT> operator()(
+ ForwardIteratorT Begin,
+ ForwardIteratorT End ) const
+ {
+ typedef ForwardIteratorT input_iterator_type;
+ typedef typename boost::detail::iterator_traits<input_iterator_type>::value_type value_type;
+ typedef iterator_range<input_iterator_type> 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<value_type>::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<typename SeqT>
+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;
+ if(!Replace.empty())
+ {
+ r.push_back( repeat_mark<value_type>() );
+ 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<typename ForwardIteratorT>
+ iterator_range<ForwardIteratorT> operator()(
+ ForwardIteratorT Begin,
+ ForwardIteratorT End ) const
+ {
+ typedef ForwardIteratorT input_iterator_type;
+ typedef typename boost::detail::iterator_traits<input_iterator_type>::value_type value_type;
+ typedef iterator_range<input_iterator_type> result_type;
+
+ for(input_iterator_type It=Begin; It!=End; It++)
+ {
+ if( *It==repeat_mark<value_type>() )
+ {
+ // 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
+ {
+ SeqT r;
+
+ if(!Replace.empty())
+ {
+ // extract info
+ typename ReplaceT::const_iterator It=Replace.begin();
+
+ value_type Value=*(++It);
+ value_type Repeat=*(++It);
+
+ for( value_type Index=0; Index<Repeat; Index++ ) r.push_back( Value );
+ }
+
+ return r;
+ }
+};
+
+
+int main()
+{
+ cout << "* RLE Compression Example *" << endl << endl;
+
+ string original("123_AA_*ZZZZZZZZZZZZZZ*34");
+
+ // copy compression
+ string compress=find_format_all_copy(
+ original,
+ find_compressF(),
+ format_compressF<string>() );
+
+ cout << "Compressed string: " << compress << endl;
+
+ // Copy decompression
+ string decompress=find_format_all_copy(
+ compress,
+ find_decompressF(),
+ format_decompressF<string>() );
+
+ cout << "Decompressed string: " << decompress << endl;
+
+ // in-place compression
+ find_format_all(
+ original,
+ find_compressF(),
+ format_compressF<string>() );
+
+ cout << "Compressed string: " << original << endl;
+
+ // in-place decompression
+ find_format_all(
+ original,
+ find_decompressF(),
+ format_decompressF<string>() );
+
+ cout << "Decompressed string: " << original << endl;
+
+ cout << endl;
+
+ return 0;
+}
diff --git a/libs/algorithm/string/example/split_example.cpp b/libs/algorithm/string/example/split_example.cpp
new file mode 100644
index 000000000..27e261c93
--- /dev/null
+++ b/libs/algorithm/string/example/split_example.cpp
@@ -0,0 +1,62 @@
+// 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 <string>
+#include <vector>
+#include <iostream>
+#include <iterator>
+#include <functional>
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/find_iterator.hpp>
+
+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::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;
+ // shift all chars in the match by one
+ transform(
+ It->begin(), It->end(),
+ It->begin(),
+ bind2nd( plus<char>(), 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<std::string> ResultCopy;
+ split(ResultCopy, str1, is_any_of("-*"), token_compress_on);
+
+ for(unsigned int nIndex=0; nIndex<ResultCopy.size(); nIndex++)
+ {
+ cout << nIndex << ":" << ResultCopy[nIndex] << endl;
+ };
+
+ cout << endl;
+
+ return 0;
+}
diff --git a/libs/algorithm/string/example/trim_example.cpp b/libs/algorithm/string/example/trim_example.cpp
new file mode 100644
index 000000000..7b1a0bd1e
--- /dev/null
+++ b/libs/algorithm/string/example/trim_example.cpp
@@ -0,0 +1,47 @@
+// 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 <string>
+#include <iostream>
+#include <boost/algorithm/string/trim.hpp>
+#include <boost/algorithm/string/classification.hpp>
+
+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/libs/algorithm/string/index.html b/libs/algorithm/string/index.html
new file mode 100644
index 000000000..dc0e1b9c4
--- /dev/null
+++ b/libs/algorithm/string/index.html
@@ -0,0 +1,14 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=../../../doc/html/string_algo.html">
+</head>
+<body>
+Automatic redirection failed, please go to
+<a href="../../../doc/html/string_algo.html">../../doc/html/string_algo.html</a>
+&nbsp;<hr>
+<p>© Copyright Beman Dawes, 2001</p>
+<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
+file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
+at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
+</body>
+</html> \ No newline at end of file
diff --git a/libs/algorithm/string/test/Jamfile.v2 b/libs/algorithm/string/test/Jamfile.v2
new file mode 100644
index 000000000..7f60df703
--- /dev/null
+++ b/libs/algorithm/string/test/Jamfile.v2
@@ -0,0 +1,74 @@
+# 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 ;
+
+alias unit_test_framework
+ : # sources
+ /boost//unit_test_framework
+ ;
+
+test-suite algorithm/string
+ : [ run
+ trim_test.cpp unit_test_framework
+ : :
+ :
+ : trim
+ ]
+ [ run
+ conv_test.cpp unit_test_framework
+ : :
+ :
+ : conv
+ ]
+ [ run
+ predicate_test.cpp unit_test_framework
+ : :
+ :
+ : predicate
+ ]
+ [ run
+ find_test.cpp unit_test_framework
+ : :
+ :
+ : find
+ ]
+ [ run
+ split_test.cpp unit_test_framework
+ : :
+ :
+ : split
+ ]
+ [ run
+ join_test.cpp unit_test_framework
+ : :
+ :
+ : join
+ ]
+ [ run
+ replace_test.cpp unit_test_framework
+ : :
+ :
+ : replace
+ ]
+ [ run
+ regex_test.cpp unit_test_framework
+ ../../../regex/build//boost_regex
+ : :
+ :
+ : regex
+ ]
+ [ run
+ find_format_test.cpp unit_test_framework
+ : :
+ :
+ : find_format
+ ]
+ ;
+
diff --git a/libs/algorithm/string/test/conv_test.cpp b/libs/algorithm/string/test/conv_test.cpp
new file mode 100644
index 000000000..c583d3efe
--- /dev/null
+++ b/libs/algorithm/string/test/conv_test.cpp
@@ -0,0 +1,94 @@
+// 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 <boost/algorithm/string/case_conv.hpp>
+
+// Include unit test framework
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+#include <string>
+#include <iostream>
+#include <algorithm>
+#include <boost/test/test_tools.hpp>
+
+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
+BOOST_AUTO_TEST_CASE( test_main )
+{
+ conv_test();
+}
diff --git a/libs/algorithm/string/test/find_format_test.cpp b/libs/algorithm/string/test/find_format_test.cpp
new file mode 100644
index 000000000..645cdba3a
--- /dev/null
+++ b/libs/algorithm/string/test/find_format_test.cpp
@@ -0,0 +1,162 @@
+// Boost string_algo library find_format_test.cpp file ------------------//
+
+// Copyright (c) 2009 Steven Watanabe
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/algorithm/string/find_format.hpp>
+#include <boost/algorithm/string/finder.hpp>
+#include <boost/algorithm/string/formatter.hpp>
+
+// Include unit test framework
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+#include <boost/test/test_tools.hpp>
+
+// We're only using const_formatter.
+template<class Formatter>
+struct formatter_result {
+ typedef boost::iterator_range<const char*> type;
+};
+
+template<class Formatter>
+struct checked_formatter {
+public:
+ checked_formatter(const Formatter& formatter) : formatter_(formatter) {}
+ template< typename T >
+ typename formatter_result<Formatter>::type operator()( const T & s ) const {
+ BOOST_CHECK( !s.empty() );
+ return formatter_(s);
+ }
+private:
+ Formatter formatter_;
+};
+
+template<class Formatter>
+checked_formatter<Formatter>
+make_checked_formatter(const Formatter& formatter) {
+ return checked_formatter<Formatter>(formatter);
+}
+
+void find_format_test()
+{
+ const std::string source = "$replace $replace";
+ std::string expected = "ok $replace";
+ std::string output(80, '\0');
+
+ std::string::iterator pos =
+ boost::find_format_copy(
+ output.begin(),
+ source,
+ boost::first_finder("$replace"),
+ make_checked_formatter(boost::const_formatter("ok")));
+ BOOST_CHECK(pos == output.begin() + expected.size());
+ output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
+ BOOST_CHECK_EQUAL(output, expected);
+
+ output =
+ boost::find_format_copy(
+ source,
+ boost::first_finder("$replace"),
+ make_checked_formatter(boost::const_formatter("ok")));
+ BOOST_CHECK_EQUAL(output, expected);
+
+ // now try finding a string that doesn't exist
+ output.resize(80);
+ pos =
+ boost::find_format_copy(
+ output.begin(),
+ source,
+ boost::first_finder("$noreplace"),
+ make_checked_formatter(boost::const_formatter("bad")));
+ BOOST_CHECK(pos == output.begin() + source.size());
+ output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
+ BOOST_CHECK_EQUAL(output, source);
+
+ output =
+ boost::find_format_copy(
+ source,
+ boost::first_finder("$noreplace"),
+ make_checked_formatter(boost::const_formatter("bad")));
+ BOOST_CHECK_EQUAL(output, source);
+
+ // in place version
+ output = source;
+ boost::find_format(
+ output,
+ boost::first_finder("$replace"),
+ make_checked_formatter(boost::const_formatter("ok")));
+ BOOST_CHECK_EQUAL(output, expected);
+ output = source;
+ boost::find_format(
+ output,
+ boost::first_finder("$noreplace"),
+ make_checked_formatter(boost::const_formatter("bad")));
+ BOOST_CHECK_EQUAL(output, source);
+}
+
+void find_format_all_test()
+{
+ const std::string source = "$replace $replace";
+ std::string expected = "ok ok";
+ std::string output(80, '\0');
+
+ std::string::iterator pos =
+ boost::find_format_all_copy(output.begin(),
+ source,
+ boost::first_finder("$replace"),
+ boost::const_formatter("ok"));
+ BOOST_CHECK(pos == output.begin() + expected.size());
+ output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
+ BOOST_CHECK_EQUAL(output, expected);
+
+ output =
+ boost::find_format_all_copy(
+ source,
+ boost::first_finder("$replace"),
+ make_checked_formatter(boost::const_formatter("ok")));
+ BOOST_CHECK_EQUAL(output, expected);
+
+ // now try finding a string that doesn't exist
+ output.resize(80);
+ pos =
+ boost::find_format_all_copy(
+ output.begin(),
+ source,
+ boost::first_finder("$noreplace"),
+ make_checked_formatter(boost::const_formatter("bad")));
+ BOOST_CHECK(pos == output.begin() + source.size());
+ output.erase(std::remove(output.begin(), output.end(), '\0'), output.end());
+ BOOST_CHECK_EQUAL(output, source);
+
+ output =
+ boost::find_format_all_copy(
+ source,
+ boost::first_finder("$noreplace"),
+ make_checked_formatter(boost::const_formatter("bad")));
+ BOOST_CHECK_EQUAL(output, source);
+
+ // in place version
+ output = source;
+ boost::find_format_all(
+ output,
+ boost::first_finder("$replace"),
+ make_checked_formatter(boost::const_formatter("ok")));
+ BOOST_CHECK_EQUAL(output, expected);
+ output = source;
+ boost::find_format_all(
+ output,
+ boost::first_finder("$noreplace"),
+ make_checked_formatter(boost::const_formatter("bad")));
+ BOOST_CHECK_EQUAL(output, source);
+}
+
+BOOST_AUTO_TEST_CASE( test_main )
+{
+ find_format_test();
+ find_format_all_test();
+}
diff --git a/libs/algorithm/string/test/find_test.cpp b/libs/algorithm/string/test/find_test.cpp
new file mode 100644
index 000000000..85facb0a7
--- /dev/null
+++ b/libs/algorithm/string/test/find_test.cpp
@@ -0,0 +1,273 @@
+// 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 <boost/algorithm/string/find.hpp>
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
+
+// Include unit test framework
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+#include <string>
+#include <vector>
+#include <iostream>
+#include <iterator>
+#include <sstream>
+#include <boost/test/test_tools.hpp>
+
+using namespace std;
+using namespace boost;
+
+void find_test()
+{
+ string str1("123abcxXxabcXxXabc321");
+ string str2("abc");
+ string str3("");
+ const char* pch1="123abcxxxabcXXXabc321";
+ vector<int> vec1( str1.begin(), str1.end() );
+
+ // find results ------------------------------------------------------------//
+ iterator_range<string::iterator> nc_result;
+ iterator_range<string::const_iterator> cv_result;
+
+ iterator_range<vector<int>::iterator> nc_vresult;
+ iterator_range<vector<int>::const_iterator> cv_vresult;
+
+ iterator_range<const char*> ch_result;
+
+ // basic tests ------------------------------------------------------------//
+
+
+ // find_first
+ BOOST_TEST_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<const string&>(str1), str2 );
+ BOOST_CHECK(
+ ( (cv_result.begin()-str1.begin()) == 3) &&
+ ( (cv_result.end()-str1.begin()) == 6) );
+
+ cv_result=ifind_first( const_cast<const string&>(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_TEST_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<const string&>(str1), str2 );
+ BOOST_CHECK(
+ ( (cv_result.begin()-str1.begin()) == 15) &&
+ ( (cv_result.end()-str1.begin()) == 18) );
+
+ cv_result=ifind_last( const_cast<const string&>(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_TEST_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) );
+
+ nc_result=find_nth( str1, string("abc"), -1 );
+ BOOST_CHECK(
+ ( (nc_result.begin()-str1.begin()) == 15) &&
+ ( (nc_result.end()-str1.begin()) == 18) );
+
+
+ cv_result=find_nth( const_cast<const string&>(str1), str2, 1 );
+ BOOST_CHECK(
+ ( (cv_result.begin()-str1.begin()) == 9) &&
+ ( (cv_result.end()-str1.begin()) == 12) );
+
+ cv_result=find_nth( const_cast<const string&>(str1), str2, -1 );
+ BOOST_CHECK(
+ ( (cv_result.begin()-str1.begin()) == 15) &&
+ ( (cv_result.end()-str1.begin()) == 18) );
+
+ cv_result=ifind_nth( const_cast<const string&>(str1), "xxx", 1 );
+ BOOST_CHECK(
+ ( (cv_result.begin()-str1.begin()) == 12) &&
+ ( (cv_result.end()-str1.begin()) == 15) );
+
+ cv_result=ifind_nth( const_cast<const string&>(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_TEST_CHECKPOINT( "find_head" );
+
+ nc_result=find_head( str1, 6 );
+ BOOST_CHECK(
+ ( (nc_result.begin()-str1.begin()) == 0) &&
+ ( (nc_result.end()-str1.begin()) == 6) );
+
+ nc_result=find_head( str1, -6 );
+ BOOST_CHECK(
+ ( (nc_result.begin()-str1.begin()) == 0) &&
+ ( (str1.end()-nc_result.end()) == 6 ) );
+
+ cv_result=find_head( const_cast<const string&>(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_TEST_CHECKPOINT( "find_tail" );
+
+ nc_result=find_tail( str1, 6 );
+ BOOST_CHECK(
+ ( (nc_result.begin()-str1.begin()) == 15) &&
+ ( (nc_result.end()-str1.begin()) == 21) );
+
+ nc_result=find_tail( str1, -6 );
+ BOOST_CHECK(
+ ( (nc_result.begin()-str1.begin()) == 6) &&
+ ( (nc_result.end()-str1.begin()) == 21) );
+
+
+ cv_result=find_tail( const_cast<const string&>(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_TEST_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<const string&>(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<const string&>(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_TEST_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<const string&>(str1), first_finder(str2) );
+ BOOST_CHECK(
+ ( (cv_result.begin()-str1.begin()) == 3) &&
+ ( (cv_result.end()-str1.begin()) == 6) );
+
+ // multi-type comparison test
+ BOOST_TEST_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<const vector<int>&>(vec1), str2 );
+ BOOST_CHECK(
+ ( (cv_result.begin()-str1.begin()) == 3) &&
+ ( (cv_result.end()-str1.begin()) == 6) );
+
+ // overflow test
+ BOOST_TEST_CHECKPOINT( "overflow" );
+
+ nc_result=find_first( str2, string("abcd") );
+ BOOST_CHECK( nc_result.begin()==nc_result.end() );
+ cv_result=find_first( const_cast<const string&>(str2), string("abcd") );
+ BOOST_CHECK( cv_result.begin()==cv_result.end() );
+
+ cv_result=find_head( const_cast<const string&>(str2), 4 );
+ BOOST_CHECK( string( cv_result.begin(), cv_result.end() )== string("abc") );
+ cv_result=find_tail( const_cast<const string&>(str2), 4 );
+ BOOST_CHECK( string( cv_result.begin(), cv_result.end() )== string("abc") );
+
+ // Empty string test
+ BOOST_TEST_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<const string&>(str3), string("abcd") );
+ BOOST_CHECK( cv_result.begin()==cv_result.end() );
+ cv_result=find_first( const_cast<const string&>(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" );
+
+ // Empty string test
+ BOOST_TEST_CHECKPOINT( "overlapping" );
+
+ std::string overlap_target("aaaa");
+ std::vector<boost::iterator_range<std::string::iterator> > overlap_results;
+ boost::algorithm::find_all(overlap_results, overlap_target, string("aaa"));
+ BOOST_CHECK( overlap_results.size() == 2 );
+
+ std::string overlap_target2("aaaabbbbaaaa");
+ boost::algorithm::find_all(overlap_results, overlap_target2, string("bb"));
+ BOOST_CHECK( overlap_results.size() == 3 );
+ boost::algorithm::find_all(overlap_results, overlap_target2, string("aa"));
+ BOOST_CHECK( overlap_results.size() == 6 );
+}
+
+// test main
+BOOST_AUTO_TEST_CASE( test_main )
+{
+ find_test();
+}
diff --git a/libs/algorithm/string/test/join_test.cpp b/libs/algorithm/string/test/join_test.cpp
new file mode 100644
index 000000000..9c5150baf
--- /dev/null
+++ b/libs/algorithm/string/test/join_test.cpp
@@ -0,0 +1,78 @@
+// 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 <boost/algorithm/string/join.hpp>
+#include <boost/algorithm/string/classification.hpp>
+// equals predicate is used for result comparison
+#include <boost/algorithm/string/predicate.hpp>
+
+// Include unit test framework
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+#include <string>
+#include <vector>
+#include <iostream>
+
+#include <boost/test/test_tools.hpp>
+
+
+using namespace std;
+using namespace boost;
+
+bool is_not_empty(const std::string& str)
+{
+ return !str.empty();
+}
+
+void join_test()
+{
+ // Prepare inputs
+ vector<string> tokens1;
+ tokens1.push_back("xx");
+ tokens1.push_back("abc");
+ tokens1.push_back("xx");
+
+ vector<string> tokens2;
+ tokens2.push_back("");
+ tokens2.push_back("xx");
+ tokens2.push_back("abc");
+ tokens2.push_back("");
+ tokens2.push_back("abc");
+ tokens2.push_back("xx");
+ tokens2.push_back("");
+
+ vector<string> tokens3;
+ tokens3.push_back("");
+ tokens3.push_back("");
+ tokens3.push_back("");
+
+ vector<string> empty_tokens;
+
+ vector<vector<int> > vtokens;
+ for(unsigned int n=0; n<tokens2.size(); ++n)
+ {
+ vtokens.push_back(vector<int>(tokens2[n].begin(), tokens2[n].end()));
+ }
+
+ BOOST_CHECK( equals(join(tokens1, "-"), "xx-abc-xx") );
+ BOOST_CHECK( equals(join(tokens2, "-"), "-xx-abc--abc-xx-") );
+ BOOST_CHECK( equals(join(vtokens, "-"), "-xx-abc--abc-xx-") );
+ BOOST_CHECK( equals(join(empty_tokens, "-"), "") );
+
+ BOOST_CHECK( equals(join_if(tokens2, "-", is_not_empty), "xx-abc-abc-xx") );
+ BOOST_CHECK( equals(join_if(empty_tokens, "-", is_not_empty), "") );
+ BOOST_CHECK( equals(join_if(tokens3, "-", is_not_empty), "") );
+}
+
+
+BOOST_AUTO_TEST_CASE( test_main )
+{
+ join_test();
+}
diff --git a/libs/algorithm/string/test/predicate_test.cpp b/libs/algorithm/string/test/predicate_test.cpp
new file mode 100644
index 000000000..ba1564e53
--- /dev/null
+++ b/libs/algorithm/string/test/predicate_test.cpp
@@ -0,0 +1,160 @@
+// 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 <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/classification.hpp>
+
+// Include unit test framework
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+#include <string>
+#include <vector>
+#include <iostream>
+#include <functional>
+#include <boost/test/test_tools.hpp>
+
+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<int> 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" ) );
+
+ BOOST_CHECK( lexicographical_compare("abc", "abd") );
+ BOOST_CHECK( !lexicographical_compare("abc", "abc") );
+ BOOST_CHECK( lexicographical_compare("abc", "abd", is_less()) );
+
+ BOOST_CHECK( !ilexicographical_compare("aBD", "AbC") );
+ BOOST_CHECK( ilexicographical_compare("aBc", "AbD") );
+ BOOST_CHECK( lexicographical_compare("abC", "aBd", is_iless()) );
+
+ // 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" ) );
+
+}
+
+template<typename Pred, typename Input>
+void test_pred(const Pred& pred, const Input& input, bool bYes)
+{
+ // test assignment operator
+ Pred pred1=pred;
+ pred1=pred;
+ pred1=pred1;
+ if(bYes)
+ {
+ BOOST_CHECK( all( input, pred ) );
+ BOOST_CHECK( all( input, pred1 ) );
+ }
+ else
+ {
+ BOOST_CHECK( !all( input, pred ) );
+ BOOST_CHECK( !all( input, pred1 ) );
+ }
+}
+
+#define TEST_CLASS( Pred, YesInput, NoInput )\
+{\
+ test_pred(Pred, YesInput, true); \
+ test_pred(Pred, NoInput, false); \
+}
+
+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" );
+
+ // is_any_of test
+// TEST_CLASS( !is_any_of(""), "", "aaa" )
+ TEST_CLASS( is_any_of("a"), "a", "ab" )
+ TEST_CLASS( is_any_of("ba"), "ab", "abc" )
+ TEST_CLASS( is_any_of("cba"), "abc", "abcd" )
+ TEST_CLASS( is_any_of("hgfedcba"), "abcdefgh", "abcdefghi" )
+ TEST_CLASS( is_any_of("qponmlkjihgfedcba"), "abcdefghijklmnopq", "zzz" )
+}
+
+#undef TEST_CLASS
+
+BOOST_AUTO_TEST_CASE( test_main )
+{
+ predicate_test();
+ classification_test();
+}
diff --git a/libs/algorithm/string/test/regex_test.cpp b/libs/algorithm/string/test/regex_test.cpp
new file mode 100644
index 000000000..f93c1d9d3
--- /dev/null
+++ b/libs/algorithm/string/test/regex_test.cpp
@@ -0,0 +1,158 @@
+// 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 <boost/algorithm/string/regex.hpp>
+#include <boost/algorithm/string/join.hpp>
+#include <boost/algorithm/string/sequence_traits.hpp>
+// equals predicate is used for result comparison
+#include <boost/algorithm/string/predicate.hpp>
+
+
+// Include unit test framework
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+#include <string>
+#include <vector>
+#include <iostream>
+#include <boost/regex.hpp>
+#include <boost/test/test_tools.hpp>
+
+using namespace std;
+using namespace boost;
+
+static void find_test()
+{
+ string str1("123a1cxxxa23cXXXa456c321");
+ const char* pch1="123a1cxxxa23cXXXa456c321";
+ regex rx("a[0-9]+c");
+ vector<int> vec1( str1.begin(), str1.end() );
+ vector<string> tokens;
+
+ // find results
+ iterator_range<string::iterator> nc_result;
+ iterator_range<string::const_iterator> cv_result;
+
+ iterator_range<vector<int>::iterator> nc_vresult;
+ iterator_range<vector<int>::const_iterator> cv_vresult;
+
+ iterator_range<const char*> 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 join_test()
+{
+ // Prepare inputs
+ vector<string> tokens1;
+ tokens1.push_back("xx");
+ tokens1.push_back("abc");
+ tokens1.push_back("xx");
+
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+ BOOST_CHECK( equals(join_if(tokens1, "-", regex("x+")), "xx-xx") );
+ BOOST_CHECK( equals(join_if(tokens1, "-", regex("[abc]+")), "abc") );
+#else
+ BOOST_CHECK( equals(join_if_regex(tokens1, "-", regex("x+")), "xx-xx") );
+ BOOST_CHECK( equals(join_if_regex(tokens1, "-", regex("[abc]+")), "abc") );
+#endif
+}
+
+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<int> vec1( str1.begin(), str1.end() );
+
+ // immutable 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") );
+}
+
+BOOST_AUTO_TEST_CASE( test_main )
+{
+ find_test();
+ join_test();
+ replace_test();
+}
diff --git a/libs/algorithm/string/test/replace_test.cpp b/libs/algorithm/string/test/replace_test.cpp
new file mode 100644
index 000000000..789d8e482
--- /dev/null
+++ b/libs/algorithm/string/test/replace_test.cpp
@@ -0,0 +1,321 @@
+// 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 <boost/algorithm/string/replace.hpp>
+#include <boost/algorithm/string/erase.hpp>
+#include <boost/algorithm/string/std/list_traits.hpp>
+#include <boost/algorithm/string/std/string_traits.hpp>
+#include <boost/algorithm/string/finder.hpp>
+#include <boost/algorithm/string/formatter.hpp>
+#include <boost/algorithm/string/classification.hpp>
+
+// Include unit test framework
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+#include <string>
+#include <vector>
+#include <list>
+#include <iostream>
+
+// equals predicate is used for result comparison
+#include <boost/algorithm/string/predicate.hpp>
+
+#include <boost/test/test_tools.hpp>
+
+using namespace std;
+using namespace boost;
+
+void sequence_traits_test()
+{
+ // basic_string traits
+ BOOST_CHECK( boost::algorithm::has_native_replace<string>::value );
+ BOOST_CHECK( !boost::algorithm::has_stable_iterators<string>::value );
+ BOOST_CHECK( !boost::algorithm::has_const_time_insert<string>::value );
+ BOOST_CHECK( !boost::algorithm::has_const_time_erase<string>::value );
+
+ // vector traits
+ BOOST_CHECK( !boost::algorithm::has_native_replace< vector<char> >::value );
+ BOOST_CHECK( !boost::algorithm::has_stable_iterators< vector<char> >::value );
+ BOOST_CHECK( !boost::algorithm::has_const_time_insert< vector<char> >::value );
+ BOOST_CHECK( !boost::algorithm::has_const_time_erase< vector<char> >::value );
+
+ // list traits
+ BOOST_CHECK( !boost::algorithm::has_native_replace< list<char> >::value );
+ BOOST_CHECK( boost::algorithm::has_stable_iterators< list<char> >::value );
+ BOOST_CHECK( boost::algorithm::has_const_time_insert< list<char> >::value );
+ BOOST_CHECK( boost::algorithm::has_const_time_erase< list<char> >::value );
+}
+
+// Combine tests for all variants of the algorithm
+#define C_ ,
+#define TEST_ALGO( Algo, Input, Params, Output ) \
+{\
+ BOOST_TEST_CHECKPOINT( #Algo " - Copy" );\
+\
+ string str1(Input);\
+\
+ /* Copy test */ \
+ BOOST_CHECK( Algo##_copy( str1, Params )==Output );\
+\
+ BOOST_TEST_CHECKPOINT( #Algo " - Iterator" );\
+ /* Iterator test */\
+ string strout;\
+ Algo##_copy( back_inserter(strout), str1, Params );\
+ BOOST_CHECK( strout==Output ); \
+\
+ /* In-place test */\
+ vector<char> vec1( str1.begin(), str1.end() );\
+ list<char> list1( str1.begin(), str1.end() );\
+\
+ BOOST_TEST_CHECKPOINT( #Algo " - Inplace(string)" );\
+ Algo( str1, Params ); \
+ BOOST_CHECK( equals( str1, Output ) ); \
+\
+ BOOST_TEST_CHECKPOINT( #Algo " - Inplace(vector)" );\
+ Algo( vec1, Params ); \
+ BOOST_CHECK( equals( vec1, Output ) );\
+\
+ BOOST_TEST_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( replace_all, string("1abc3abc2"), "/" C_ "\\", string("1abc3abc2") );
+ 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( replace_nth, "1abc3abc2", string("abc") C_ -1 C_ string("YYY"), string("1abc3YYY2") );
+ TEST_ALGO( ireplace_nth, "1AbC3abc2", "aBc" C_ 0 C_ "YYY", string("1YYY3abc2") );
+ TEST_ALGO( ireplace_nth, "1AbC3abc2", "aBc" C_ -1 C_ "YYY", string("1AbC3YYY2") );
+ 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", "abc" C_ 3 C_ "XXXX", string("1abc3abc2") );
+ TEST_ALGO( replace_nth, "1abc3abc2", "abc" C_ -3 C_ "XXXX", string("1abc3abc2") );
+ 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( replace_nth, "", string("") C_ -1 C_ string("XXXX"), string("") );
+ TEST_ALGO( erase_nth, "1abc3abc2", string("abc") C_ 0, string("13abc2") );
+ TEST_ALGO( erase_nth, "1abc3abc2", string("abc") C_ -1, string("1abc32") );
+ TEST_ALGO( erase_nth, "1abc3abc2", string("abc") C_ -3, string("1abc3abc2") );
+ TEST_ALGO( ierase_nth, "1aBc3aBc2", "ABC" C_ 0, string("13aBc2") );
+ TEST_ALGO( ierase_nth, "1aBc3aBc2", "ABC" C_ -1, string("1aBc32") );
+ TEST_ALGO( ierase_nth, "1aBc3aBc2", "ABC" C_ -3, string("1aBc3aBc2") );
+ 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( erase_nth, "", string("abc") C_ -1, 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_ string("YYY"), string("YYYbc2") );
+ 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, "abc", -6 C_ string("XXXX"), string("abc") );
+ TEST_ALGO( replace_head, "abc3abc2", 0 C_ string("XXXX"), string("abc3abc2") );
+ TEST_ALGO( replace_head, "", 4 C_ string("XXXX"), string("") );
+ TEST_ALGO( replace_head, "", -4 C_ string("XXXX"), string("") );
+ TEST_ALGO( erase_head, "abc3abc2", 3, string("3abc2") );
+ TEST_ALGO( erase_head, "abc3abc2", -3, string("bc2") );
+ TEST_ALGO( erase_head, "abc3abc2", 0, string("abc3abc2") );
+ TEST_ALGO( erase_head, "", 4, string("") );
+ 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("abcYYY") );
+ 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, "abc", -6 C_ string("XXXX"), string("abc") );
+ TEST_ALGO( replace_tail, "abc3abc", 0 C_ string("XXXX"), string("abc3abc") );
+ TEST_ALGO( replace_tail, "", 4 C_ string("XXXX"), string("") );
+ TEST_ALGO( replace_tail, "", -4 C_ string("XXXX"), string("") );
+ TEST_ALGO( erase_tail, "abc3abc", 3, string("abc3") );
+ TEST_ALGO( erase_tail, "abc3abc", -3, string("abc") );
+ TEST_ALGO( erase_tail, "abc3abc", 0, string("abc3abc") );
+ TEST_ALGO( erase_tail, "", 4, string("") );
+ TEST_ALGO( erase_tail, "", -4, string("") );
+}
+
+void replace_range_test()
+{
+ // replace_range
+ {
+ BOOST_TEST_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_TEST_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") );
+ }
+}
+
+void dissect_format_test()
+{
+ BOOST_CHECK(
+ find_format_all_copy(
+ string("aBc123Abc"),
+ first_finder("abc", is_iequal()),
+ dissect_formatter(token_finder(is_upper())))=="B123A");
+
+
+ BOOST_CHECK(
+ find_format_all_copy(
+ string("abc 123 abc"),
+ token_finder(is_space(), token_compress_on),
+ dissect_formatter(head_finder(1)))=="abc 123 abc");
+
+}
+
+BOOST_AUTO_TEST_CASE( test_main )
+{
+ 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();
+ dissect_format_test();
+}
diff --git a/libs/algorithm/string/test/split_test.cpp b/libs/algorithm/string/test/split_test.cpp
new file mode 100644
index 000000000..429f3c4f6
--- /dev/null
+++ b/libs/algorithm/string/test/split_test.cpp
@@ -0,0 +1,193 @@
+// 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 <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/classification.hpp>
+// equals predicate is used for result comparison
+#include <boost/algorithm/string/predicate.hpp>
+
+// Include unit test framework
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+#include <string>
+#include <vector>
+#include <list>
+#include <iostream>
+
+#include <boost/test/test_tools.hpp>
+
+
+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<X.size(); ++nIndex )
+ {
+ BOOST_CHECK( equals( X[nIndex], Y[nIndex] ) );
+ }
+}
+
+void iterator_test()
+{
+ string str1("xx-abc--xx-abb");
+ string str2("Xx-abc--xX-abb-xx");
+ string str3("xx");
+ string strempty("");
+ const char* pch1="xx-abc--xx-abb";
+ vector<string> tokens;
+ vector< vector<int> > 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") );
+
+ split(
+ tokens,
+ str3,
+ is_any_of(","),
+ token_compress_off);
+
+ BOOST_REQUIRE( tokens.size()==1 );
+ BOOST_CHECK( tokens[0]==string("xx") );
+
+ split(
+ tokens,
+ strempty,
+ is_punct(),
+ token_compress_off);
+
+ BOOST_REQUIRE( tokens.size()==1 );
+ BOOST_CHECK( tokens[0]==string("") );
+
+
+ find_iterator<string::iterator> fiter=make_find_iterator(str1, first_finder("xx"));
+ find_iterator<string::iterator> fiter2;
+
+ BOOST_CHECK(equals(*fiter, "xx"));
+ ++fiter;
+
+ fiter2 = fiter;
+ BOOST_CHECK(equals(*fiter, "xx"));
+ BOOST_CHECK(equals(*fiter2, "xx"));
+
+ ++fiter;
+ BOOST_CHECK(fiter==find_iterator<string::iterator>());
+ BOOST_CHECK(equals(*fiter2, "xx"));
+
+ ++fiter2;
+ BOOST_CHECK(fiter2==find_iterator<string::iterator>());
+
+ split_iterator<string::iterator> siter=make_split_iterator(str1, token_finder(is_any_of("-"), token_compress_on));
+ split_iterator<string::iterator> siter2;
+ BOOST_CHECK(equals(*siter, "xx"));
+ ++siter;
+
+ siter2 = siter;
+ BOOST_CHECK(equals(*siter, "abc"));
+ BOOST_CHECK(equals(*siter2, "abc"));
+
+ ++siter;
+ BOOST_CHECK(equals(*siter, "xx"));
+ BOOST_CHECK(equals(*siter2, "abc"));
+
+ ++siter;
+ BOOST_CHECK(equals(*siter, "abb"));
+ ++siter;
+ BOOST_CHECK(siter==split_iterator<string::iterator>(siter));
+ BOOST_CHECK(siter==split_iterator<string::iterator>());
+
+// Make sure we work with forward iterators
+// See bug #7989
+ list<char> l1;
+ find_iterator<list<char>::iterator> liter=make_find_iterator(l1, first_finder("xx"));
+}
+
+BOOST_AUTO_TEST_CASE( test_main )
+{
+ iterator_test();
+}
diff --git a/libs/algorithm/string/test/trim_test.cpp b/libs/algorithm/string/test/trim_test.cpp
new file mode 100644
index 000000000..b254caaa4
--- /dev/null
+++ b/libs/algorithm/string/test/trim_test.cpp
@@ -0,0 +1,202 @@
+// 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 <boost/algorithm/string/trim.hpp>
+#include <boost/algorithm/string/trim_all.hpp>
+
+// Include unit test framework
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+#include <string>
+#include <iostream>
+#include <boost/test/test_tools.hpp>
+
+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" );
+}
+
+void trim_all_test()
+{
+ string str1(" 1x x x x1 ");
+ string str2("+---...2x+--x--+x-+-x2...---+");
+ string str3(" ");
+
+ // *** value passing tests *** //
+
+ // general string test
+ BOOST_CHECK( trim_all_copy( str1 )=="1x x x x1" ) ;
+ BOOST_CHECK( trim_all_copy_if( str2, is_punct() )=="2x+x-x-x2" ) ;
+
+ // spaces-only string test
+ BOOST_CHECK( trim_all_copy( str3 )=="" );
+
+ // empty string check
+ BOOST_CHECK( trim_all_copy( string("") )=="" );
+
+ // general string test
+ trim_all( str1 );
+ BOOST_CHECK( str1=="1x x x x1" ) ;
+ trim_all_if( str2, is_punct() );
+ BOOST_CHECK( str2=="2x+x-x-x2" ) ;
+
+ // spaces-only string test
+ str3 = " "; trim_all( str3 );
+ BOOST_CHECK( str3=="" );
+
+ // empty string check
+ str3 = ""; trim_all( str3 );
+ BOOST_CHECK( str3=="" );
+ BOOST_CHECK( str3=="" );
+
+ // *** non-standard predicate tests *** //
+ BOOST_CHECK(
+ trim_all_copy_if(
+ string("123abc127deb456"),
+ is_classified(std::ctype_base::digit) )=="abc1deb" );
+ BOOST_CHECK( trim_all_copy_if( string("<>abc<>def<>"), is_any_of( "<<>>" ) )=="abc<def" );
+}
+
+void trim_fill_test()
+{
+ string str1(" 1x x x x1 ");
+ string str2("+---...2x+--x--+x-+-x2...---+");
+ string str3(" ");
+
+ // *** value passing tests *** //
+
+ // general string test
+ BOOST_CHECK( trim_fill_copy( str1, "-" )=="1x-x-x-x1" ) ;
+ BOOST_CHECK( trim_fill_copy_if( str2, " ", is_punct() )=="2x x x x2" ) ;
+
+ // spaces-only string test
+ BOOST_CHECK( trim_fill_copy( str3, " " )=="" );
+
+ // empty string check
+ BOOST_CHECK( trim_fill_copy( string(""), " " )=="" );
+
+ // general string test
+ trim_fill( str1, "-" );
+ BOOST_CHECK( str1=="1x-x-x-x1" ) ;
+ trim_fill_if( str2, "", is_punct() );
+ BOOST_CHECK( str2=="2xxxx2" ) ;
+
+ // spaces-only string test
+ str3 = " "; trim_fill( str3, "" );
+ BOOST_CHECK( str3=="" );
+
+ // empty string check
+ str3 = ""; trim_fill( str3, "" );
+ BOOST_CHECK( str3=="" );
+ BOOST_CHECK( str3=="" );
+
+ // *** non-standard predicate tests *** //
+ BOOST_CHECK(
+ trim_fill_copy_if(
+ string("123abc127deb456"),
+ "+",
+ is_classified(std::ctype_base::digit) )=="abc+deb" );
+ BOOST_CHECK( trim_fill_copy_if( string("<>abc<>def<>"), "-", is_any_of( "<<>>" ) )=="abc-def" );
+}
+
+BOOST_AUTO_TEST_CASE( test_main )
+{
+ trim_test();
+ trim_all_test();
+ trim_fill_test();
+}