diff --git a/include/boost/algorithm/string.hpp b/include/boost/algorithm/string.hpp new file mode 100644 index 0000000..dd8de34 --- /dev/null +++ b/include/boost/algorithm/string.hpp @@ -0,0 +1,30 @@ +// Boost string_algo library string_algo.hpp header file ---------------------------// + +// (C) Copyright Pavol Droba 2002-2003. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_STRING_ALGO_HPP +#define BOOST_STRING_ALGO_HPP + +/*! \file + Cumulative include for string_algo library +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#endif // BOOST_STRING_ALGO_HPP diff --git a/include/boost/algorithm/string/case_conv.hpp b/include/boost/algorithm/string/case_conv.hpp new file mode 100644 index 0000000..c381d40 --- /dev/null +++ b/include/boost/algorithm/string/case_conv.hpp @@ -0,0 +1,186 @@ +// Boost string_algo library case_conv.hpp header 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. + +#ifndef BOOST_STRING_CASE_CONV_HPP +#define BOOST_STRING_CASE_CONV_HPP + +#include +#include +#include +#include +#include +#include + +/*! \file + Defines sequence case-conversion algorithms. + Algorithms convert each element in the input sequence to the + desired case using provided locales. +*/ + +namespace boost { + namespace algorithm { + +// to_lower -----------------------------------------------// + + //! Convert to lower case + /*! + Each element of the input sequence is converted to lower + case. The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input collection + \param Loc A locale used for conversion + \return An output iterator pointing just after last inserted character + */ + template + inline OutputIteratorT + to_lower_copy( + OutputIteratorT Output, + const CollectionT& Input, + const std::locale& Loc=std::locale()) + { + return std::transform( + begin(Input), + end(Input), + Output, + detail::to_lowerF< + typename value_type_of::type >(Loc)); + } + + //! Convert to lower case + /*! + Each element of the input sequence is converted to lower + case. The result is a copy of the input converted to lower case. + + \param Input An input sequence + \param Loc a locale used for conversion + \return A copy of the input converted to lower case + */ + template + inline SequenceT to_lower_copy( + const SequenceT& Input, + const std::locale& Loc=std::locale()) + { + return SequenceT( + make_transform_iterator( + begin(Input), + detail::to_lowerF< + typename value_type_of::type >(Loc)), + make_transform_iterator( + end(Input), + detail::to_lowerF< + typename value_type_of::type >(Loc))); + } + + //! Convert to lower case + /*! + Each element of the input sequence is converted to lower + case. The input sequence is modified in-place. + + \param Input A collection + \param Loc a locale used for conversion + */ + template + inline void to_lower( + MutableCollectionT& Input, + const std::locale& Loc=std::locale()) + { + std::transform( + begin(Input), + end(Input), + begin(Input), + detail::to_lowerF< + typename value_type_of::type >(Loc)); + } + +// to_upper -----------------------------------------------// + + //! Convert to upper case + /*! + Each element of the input sequence is converted to upper + case. The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input collection + \param Loc a locale used for conversion + \return An output iterator pointing just after last inserted character + */ + template + inline OutputIteratorT + to_upper_copy( + OutputIteratorT Output, + const CollectionT& Input, + const std::locale& Loc=std::locale()) + { + return std::transform( + begin(Input), + end(Input), + Output, + detail::to_upperF< + typename value_type_of::type >(Loc)); + } + + //! Convert to upper case + /*! + Each element of the input sequence is converted to upper + case. The result is a copy if the input converted to upper case. + + \param Input An input sequence + \param Loc a locale used for conversion + \return A copy of the input converted to upper case + */ + template + inline SequenceT to_upper_copy( + const SequenceT& Input, + const std::locale& Loc=std::locale()) + { + return SequenceT( + make_transform_iterator( + begin(Input), + detail::to_upperF< + typename value_type_of::type >(Loc)), + make_transform_iterator( + end(Input), + detail::to_upperF< + typename value_type_of::type >(Loc))); + + } + + //! Convert to upper case + /*! + Each element of the input sequence is converted to upper + case. The input sequence is modified in-place. + + \param Input An input collection + \param Loc a locale used for conversion + */ + template + inline void to_upper( + MutableCollectionT& Input, + const std::locale& Loc=std::locale()) + { + std::transform( + begin(Input), + end(Input), + begin(Input), + detail::to_upperF< + typename value_type_of::type >(Loc)); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::to_lower; + using algorithm::to_lower_copy; + using algorithm::to_upper; + using algorithm::to_upper_copy; + +} // namespace boost + +#endif // BOOST_STRING_CASE_CONV_HPP diff --git a/include/boost/algorithm/string/classification.hpp b/include/boost/algorithm/string/classification.hpp new file mode 100644 index 0000000..a6724ae --- /dev/null +++ b/include/boost/algorithm/string/classification.hpp @@ -0,0 +1,304 @@ +// Boost string_algo library classification.hpp header 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. + +#ifndef BOOST_STRING_CLASSIFICATION_HPP +#define BOOST_STRING_CLASSIFICATION_HPP + +#include +#include +#include + +/*! \file + Classification predicates are included in the library to give + some more convenience when using algorithms like \c trim() and \c all(). + They wrap functionality of STL classification functions ( e.g. \c std::isspace() ) + into generic functors. +*/ + +namespace boost { + namespace algorithm { + +// classification functor generator -------------------------------------// + + //! is_classified predicate + /*! + Construct the \c is_classified predicate. This predicate holds, if an input is + of specified \c std::ctype category. + + \param Type A \c std::ctype category + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_classified(std::ctype_base::mask Type, const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(Type, Loc); + } + + //! is_space predicate + /*! + Construct the \c is_classified predicate for \c ctype_base::space category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_space(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::space, Loc); + } + + //! is_alnum predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::alnum category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_alnum(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::alnum, Loc); + } + + //! is_alpha predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::alpha category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_alpha(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::alpha, Loc); + } + + //! is_cntrl predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::cntrl category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_cntrl(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::cntrl, Loc); + } + + //! is_digit predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::digit category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_digit(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::digit, Loc); + } + + //! is_graph predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::graph category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_graph(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::graph, Loc); + } + + //! is_lower predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::lower category. + + \param Loc A locale used for classification + \return An instance of \c is_classified predicate + */ + inline detail::is_classifiedF + is_lower(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::lower, Loc); + } + + //! is_print predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::print category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_print(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::print, Loc); + } + + //! is_punct predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::punct category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_punct(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::punct, Loc); + } + + //! is_upper predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::upper category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_upper(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::upper, Loc); + } + + //! is_xdigit predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::xdigit category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_xdigit(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::xdigit, Loc); + } + + //! is_any_of predicate + /*! + Construct the \c is_any_of predicate. The predicate holds, if an input + is included in the specified set of characters. + + \param Set A set of characters to be recognized + \return An instance of the \c is_any_of predicate + */ + template + inline detail::is_any_ofF< + BOOST_STRING_TYPENAME value_type_of::type> + is_any_of( const ContainerT& Set ) + { + return detail::is_any_ofF< + BOOST_STRING_TYPENAME value_type_of::type>(Set); + } + + //! is_from_range predicate + /*! + Construct the \c is_from_range predicate. The predicate holds, if an input + is included in the specified range. (i.e. From <= Ch <= To ) + + \param From The start of the range + \param To The end of the range + \return An instance of the \c is_from_range predicate + */ + template + inline detail::is_from_rangeF is_from_range(CharT From, CharT To) + { + return detail::is_from_rangeF(From,To); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::is_classified; + using algorithm::is_space; + using algorithm::is_alnum; + using algorithm::is_alpha; + using algorithm::is_cntrl; + using algorithm::is_digit; + using algorithm::is_graph; + using algorithm::is_lower; + using algorithm::is_upper; + using algorithm::is_print; + using algorithm::is_punct; + using algorithm::is_xdigit; + using algorithm::is_any_of; + using algorithm::is_from_range; + +} // namespace boost + + +// predicate combinators ---------------------------------------------------// +/* + * These operators must be declared in the global namespace, otherwise + * they are not resolved correctly. There will not a problem with a name-clash, + * since they are define only for internal types + */ + +//! predicate 'and' composition predicate +/*! + Construct the \c class_and predicate. This predicate can be used + to logically combine two classification predicates. \c class_and holds, + if both predicates return true. + + \param Pred1 The first predicate + \param Pred2 The second predicate + \return An instance of the \c class_and predicate +*/ +template +inline boost::algorithm::detail::pred_andF +operator&&( + const boost::algorithm::detail::predicate_facade& Pred1, + const boost::algorithm::detail::predicate_facade& Pred2 ) +{ + return boost::algorithm::detail::pred_andF( + static_cast(Pred1), + static_cast(Pred2) ); +} + +//! predicate 'or' composition predicate +/*! + Construct the \c class_or predicate. This predicate can be used + to logically combine two classification predicates. \c class_or holds, + if one of the predicates return true. + + \param Pred1 The first predicate + \param Pred2 The second predicate + \return An instance of the \c class_or predicate +*/ +template +inline boost::algorithm::detail::pred_orF +operator||( + const boost::algorithm::detail::predicate_facade& Pred1, + const boost::algorithm::detail::predicate_facade& Pred2 ) +{ + return boost::algorithm::detail::pred_orF( + static_cast(Pred1), + static_cast(Pred2)); +} + +//! predicate negation operator +/*! + Construct the \c class_not predicate. This predicate represents a negation. + \c class_or holds, if of the predicates return false. + + \param Pred The predicate to be negated + \return An instance of the \c class_not predicate +*/ +template +inline boost::algorithm::detail::pred_notF +operator!( const boost::algorithm::detail::predicate_facade& Pred ) +{ + return boost::algorithm::detail::pred_notF(static_cast(Pred)); +} + +#endif // BOOST_STRING_PREDICATE_HPP diff --git a/include/boost/algorithm/string/collection_traits.hpp b/include/boost/algorithm/string/collection_traits.hpp new file mode 100644 index 0000000..3a780bb --- /dev/null +++ b/include/boost/algorithm/string/collection_traits.hpp @@ -0,0 +1,268 @@ +// Boost string_algo library collection_traits.hpp header 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) + +// (C) Copyright Thorsten Ottosen 2002-2003. Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +// (C) Copyright Jeremy Siek 2001. Permission to copy, use, modify, +// sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +// Orignal idea of container traits was proposed by Jeremy Siek and +// Thorsten Ottosen. This implemenetation is lightweighted version +// of container_traits adapter for usage with string_algo library + +#ifndef BOOST_STRING_COLLECTION_TRAITS_HPP +#define BOOST_STRING_COLLECTION_TRAITS_HPP + +#include +#include +#include +#include + +// Implementation +#include + +/*! \file + Defines collection_traits class and related free-standing functions. + This facility is used to unify the access to different types of collections. + It allows the algorithms in the library to work with STL collections, c-style + array, null-terminated c-strings (and more) using the same interface. +*/ + +namespace boost { + namespace algorithm { + +// collection_traits template class -----------------------------------------// + + //! collection_traits class + /*! + Collection traits provides uniform access to different types of + collections. This functionality allows to write generic algorithms + which work with several different kinds of collections. + + Currently following collection types are supported: + - containers with STL compatible container interface ( see ContainerConcept ) + ( i.e. \c std::vector<>, \c std::list<>, \c std::string<> ... ) + - c-style array + ( \c char[10], \c int[15] ... ) + - null-terminated c-strings + ( \c char*, \c wchar_T* ) + - std::pair of iterators + ( i.e \c std::pair::iterator,vector::iterator> ) + + Collection traits provide a external collection interface operations. + All are accessible using free-standing functions. + + Following operations are supported: + - \c size() + - \c empty() + - \c begin() + - \c end() + + Container traits have somewhat limited functionality on compilers not + supporting partial template specialization and partial template ordering. + */ + template< typename T > + struct collection_traits + { + private: + typedef BOOST_STRING_TYPENAME ::boost::mpl::apply_if< + ::boost::algorithm::detail::is_pair, + detail::pair_container_traits_selector, + BOOST_STRING_TYPENAME ::boost::mpl::apply_if< + ::boost::is_array, + detail::array_container_traits_selector, + BOOST_STRING_TYPENAME ::boost::mpl::apply_if< + ::boost::is_pointer, + detail::pointer_container_traits_selector, + detail::default_container_traits_selector + > + > + >::type container_helper_type; + public: + //! Function type + typedef container_helper_type function_type; + //! Value type + typedef BOOST_STRING_TYPENAME + container_helper_type::value_type value_type; + //! Size type + typedef BOOST_STRING_TYPENAME + container_helper_type::size_type size_type; + //! Iterator type + typedef BOOST_STRING_TYPENAME + container_helper_type::iterator iterator; + //! Const iterator type + typedef BOOST_STRING_TYPENAME + container_helper_type::const_iterator const_iterator; + //! Result iterator type ( iterator of const_iterator, depending on the constness of the conainer ) + typedef BOOST_STRING_TYPENAME + container_helper_type::result_iterator result_iterator; + //! Difference type + typedef BOOST_STRING_TYPENAME + container_helper_type::difference_type difference_type; + + }; // 'collection_traits' + +// collection_traits metafunctions -----------------------------------------// + + //! Container value_type trait + /*! + Extract the type of elements conained in a container + */ + template< typename C > + struct value_type_of + { + typedef BOOST_STRING_TYPENAME collection_traits::value_type type; + }; + + //! Container difference trait + /*! + Extract the container's difference type + */ + template< typename C > + struct difference_type_of + { + typedef BOOST_STRING_TYPENAME collection_traits::difference_type type; + }; + + //! Container iterator trait + /*! + Extract the container's iterator type + */ + template< typename C > + struct iterator_of + { + typedef BOOST_STRING_TYPENAME collection_traits::iterator type; + }; + + //! Container const_iterator trait + /*! + Extract the container's const_iterator type + */ + template< typename C > + struct const_iterator_of + { + typedef BOOST_STRING_TYPENAME collection_traits::const_iterator type; + }; + + + //! Container result_iterator + /*! + Extract the container's result_iterator type. This type maps to \c C::iterator + for mutable container and \c C::const_iterator for const containers. + */ + template< typename C > + struct result_iterator_of + { + typedef BOOST_STRING_TYPENAME collection_traits::result_iterator type; + }; + +// collection_traits related functions -----------------------------------------// + + //! Free-standing size() function + /*! + Get the size of the container. Uses collection_traits. + */ + template< typename C > + inline BOOST_STRING_TYPENAME collection_traits::size_type + size( const C& c ) + { + return collection_traits::function_type::size( c ); + } + + //! Free-standing empty() function + /*! + Check whenever the container is empty. Uses container traits. + */ + template< typename C > + inline bool empty( const C& c ) + { + return collection_traits::function_type::empty( c ); + } + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + //! Free-standing begin() function + /*! + Get the begin iterator of the container. Uses collection_traits. + */ + template< typename C > + inline BOOST_STRING_TYPENAME collection_traits::iterator + begin( C& c ) + { + return collection_traits::function_type::begin( c ); + } + + //! Free-standing begin() function + /*! + \overload + */ + template< typename C > + inline BOOST_STRING_TYPENAME collection_traits::const_iterator + begin( const C& c ) + { + return collection_traits::function_type::begin( c ); + } + + //! Free-standing end() function + /*! + Get the begin iterator of the container. Uses collection_traits. + */ + template< typename C > + inline BOOST_STRING_TYPENAME collection_traits::iterator + end( C& c ) + { + return collection_traits::function_type::end( c ); + } + + //! Free-standing end() function + /*! + \overload + */ + template< typename C > + inline BOOST_STRING_TYPENAME collection_traits::const_iterator + end( const C& c ) + { + return collection_traits::function_type::end( c ); + } + +#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + //! Free-standing begin() function + /*! + \overload + */ + template< typename C > + inline BOOST_STRING_TYPENAME collection_traits::result_iterator + begin( C& c ) + { + return collection_traits::function_type::begin( c ); + } + + //! Free-standing end() function + /*! + \overload + */ + template< typename C > + inline BOOST_STRING_TYPENAME collection_traits::result_iterator + end( C& c ) + { + return collection_traits::function_type::end( c ); + } + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_COLLECTION_TRAITS_HPP diff --git a/include/boost/algorithm/string/compare.hpp b/include/boost/algorithm/string/compare.hpp new file mode 100644 index 0000000..81774ca --- /dev/null +++ b/include/boost/algorithm/string/compare.hpp @@ -0,0 +1,83 @@ +// Boost string_algo library compare.hpp header 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. + +#ifndef BOOST_STRING_COMPARE_HPP +#define BOOST_STRING_COMPARE_HPP + +#include +#include + +/*! \file + Defines element comparison predicates. Many algorithms in this library can + take an additional argument with a predicate used to compare elements. + This makes it possible, for instance, to have case insensitive versions + of the algorithms. +*/ + +namespace boost { + namespace algorithm { + + // is_equal functor -----------------------------------------------// + + //! is_equal functor + /*! + Standard STL equal_to does handle only comparison between arguments + of the same type. This is less restrictive version which wraps == operator. + */ + struct is_equal + { + //! Function operator + /*! + Compare two operands for equality + */ + template< typename T1, typename T2 > + bool operator ()( const T1& Arg1, const T2& Arg2 ) const + { + return Arg1==Arg2; + } + }; + + //! case insensitive version of is_equal + /*! + Case insensitive comparison predicate. Comparison is done using + specified locales. + */ + struct is_iequal + { + //! Constructor + /*! + \param Loc locales used for comparison + */ + is_iequal( const std::locale& Loc=std::locale() ) : + m_Loc( Loc ) {} + + //! Function operator + /*! + Compare two operands. Case is ignored. + */ + template< typename T1, typename T2 > + bool operator ()( const T1& Arg1, const T2& Arg2 ) const + { + return std::toupper(Arg1,m_Loc)==std::toupper(Arg2,m_Loc); + } + + private: + std::locale m_Loc; + }; + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::is_equal; + using algorithm::is_iequal; + +} // namespace boost + + +#endif // BOOST_STRING_COMPARE_HPP diff --git a/include/boost/algorithm/string/concept.hpp b/include/boost/algorithm/string/concept.hpp new file mode 100644 index 0000000..993fdd4 --- /dev/null +++ b/include/boost/algorithm/string/concept.hpp @@ -0,0 +1,81 @@ +// Boost string_algo library concept.hpp header 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. + +#ifndef BOOST_STRING_CONCEPT_HPP +#define BOOST_STRING_CONCEPT_HPP + +#include +#include +#include + +/*! \file + Defines concepts used in string_algo library +*/ + +namespace boost { + namespace algorithm { + + //! Finder concept + /*! + Defines finder concept. Finder is a functor which selects + an arbitraty part of a container. Search is performed on + the range specified by starting and ending iterators. + + Result of the find operation must be convertible to iterator_range. + */ + template + struct FinderConcept + { + private: + typedef iterator_range range; + public: + void constraints() + { + // Operation + r=(*pF)(i,i); + } + private: + range r; + IteratorT i; + FinderT* pF; + }; // Finder_concept + + + //! Formatter concept + /*! + Defines formatter concept. Formatter is a functor, which + takes a result from a finder operation and transforms it + in a specific way. + + Result must be a container supported by container_traits, + or a reference to it. + */ + template + struct FormatterConcept + { + public: + void constraints() + { + // Operation + begin((*pFo)( (*pF)(i,i) )); + end((*pFo)( (*pF)(i,i) )); + } + private: + IteratorT i; + FinderT* pF; + FormatterT *pFo; + }; // FormatterConcept; + + } // namespace algorithm +} // namespace boost + + + + +#endif // BOOST_STRING_CONCEPT_HPP diff --git a/include/boost/algorithm/string/config.hpp b/include/boost/algorithm/string/config.hpp new file mode 100644 index 0000000..8c73036 --- /dev/null +++ b/include/boost/algorithm/string/config.hpp @@ -0,0 +1,21 @@ +// Boost string_algo library config.hpp header 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. + +#ifndef BOOST_STRING_CONFIG_HPP +#define BOOST_STRING_CONFIG_HPP + +#include + +#ifdef BOOST_STRING_DEDUCED_TYPENAME +# error "macro already defined!" +#endif + +#define BOOST_STRING_TYPENAME BOOST_DEDUCED_TYPENAME + +#endif // BOOST_STRING_CONFIG_HPP diff --git a/include/boost/algorithm/string/constants.hpp b/include/boost/algorithm/string/constants.hpp new file mode 100644 index 0000000..d9dbe0d --- /dev/null +++ b/include/boost/algorithm/string/constants.hpp @@ -0,0 +1,35 @@ +// Boost string_algo library constants.hpp header 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. + +#ifndef BOOST_STRING_CONSTANTS_HPP +#define BOOST_STRING_CONSTANTS_HPP + +namespace boost { + namespace algorithm { + + //! Token compression mode + /*! + Specifies token compression mode for the token_finder. + */ + enum token_compress_mode_type + { + token_compress_on, //!< Compress adjacent tokens + token_compress_off //!< Do not compress adjacent tokens + }; + + } // namespace algorithm + + // pull the names to the boost namespace + using algorithm::token_compress_on; + using algorithm::token_compress_off; + +} // namespace boost + +#endif // BOOST_STRING_CONSTANTS_HPP + diff --git a/include/boost/algorithm/string/detail/case_conv.hpp b/include/boost/algorithm/string/detail/case_conv.hpp new file mode 100644 index 0000000..a6f24d7 --- /dev/null +++ b/include/boost/algorithm/string/detail/case_conv.hpp @@ -0,0 +1,60 @@ +// Boost string_algo library string_funct.hpp header 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. + +#ifndef BOOST_STRING_CASE_CONV_DETAIL_HPP +#define BOOST_STRING_CASE_CONV_DETAIL_HPP + +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// case conversion functors -----------------------------------------------// + + // a tolower functor + template + struct to_lowerF : public std::unary_function + { + // Constructor + to_lowerF( const std::locale& Loc ) : m_Loc( Loc ) {} + + // Operation + CharT operator ()( CharT Ch ) const + { + return std::tolower( Ch, m_Loc ); + } + private: + const std::locale& m_Loc; + }; + + // a toupper functor + template + struct to_upperF : public std::unary_function + { + // Constructor + to_upperF( const std::locale& Loc ) : m_Loc( Loc ) {} + + // Operation + CharT operator ()( CharT Ch ) const + { + return std::toupper( Ch, m_Loc ); + } + private: + const std::locale& m_Loc; + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_CASE_CONV_DETAIL_HPP diff --git a/include/boost/algorithm/string/detail/classification.hpp b/include/boost/algorithm/string/detail/classification.hpp new file mode 100644 index 0000000..f32b9ab --- /dev/null +++ b/include/boost/algorithm/string/detail/classification.hpp @@ -0,0 +1,193 @@ +// Boost string_algo library classification.hpp header 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. + +#ifndef BOOST_STRING_CLASSIFICATION_DETAIL_HPP +#define BOOST_STRING_CLASSIFICATION_DETAIL_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// predicate facade ------------------------------------------------------// + + // Predicate facade + /* + This class allows to recognize classification + predicates, so that they can be combined using + composition operators. + */ + template + struct predicate_facade {}; + +// classification functors -----------------------------------------------// + + // is_classified functor + struct is_classifiedF : + public predicate_facade + { + // Boost.Lambda support + template struct sig { typedef bool type; }; + + // Constructor from a locale + is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) : + m_Type(Type), m_Locale(Loc) {} + + // Operation + template + bool operator()( CharT Ch ) const + { + return std::use_facet< std::ctype >(m_Locale).is( m_Type, Ch ); + } + + private: + const std::ctype_base::mask m_Type; + const std::locale m_Locale; + }; + + // is_any_of functor + /* + returns true if the value is from the specified set + */ + template + struct is_any_ofF : + public predicate_facade > + { + // Boost.Lambda support + template struct sig { typedef bool type; }; + + // Constructor + template< typename SeqT > + is_any_ofF( const SeqT& Seq ) : + m_Set( begin(Seq), end(Seq) ) {} + + // Operation + template + bool operator()( Char2T Ch ) const + { + return m_Set.find(Ch)!=m_Set.end(); + } + + private: + std::set m_Set; + }; + + // is_from_range functor + /* + returns true if the value is from the specified range. + (i.e. x>=From && x>=To) + */ + template + struct is_from_rangeF : + public predicate_facade< is_from_rangeF > + { + // Boost.Lambda support + template struct sig { typedef bool type; }; + + // Constructor + is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {} + + // Operation + template + bool operator()( Char2T Ch ) const + { + return ( m_From <= Ch ) && ( Ch <= m_To ); + } + + private: + CharT m_From; + CharT m_To; + }; + + // class_and composition predicate + template + struct pred_andF : + public predicate_facade< pred_andF > + { + public: + + // Boost.Lambda support + template struct sig { typedef bool type; }; + + // Constructor + pred_andF( Pred1T Pred1, Pred2T Pred2 ) : + m_Pred1(Pred1), m_Pred2(Pred2) {} + + // Operation + template + bool operator()( CharT Ch ) const + { + return m_Pred1(Ch) && m_Pred2(Ch); + } + + private: + Pred1T m_Pred1; + Pred2T m_Pred2; + }; + + // class_or composition predicate + template + struct pred_orF : + public predicate_facade< pred_orF > + { + public: + // Boost.Lambda support + template struct sig { typedef bool type; }; + + // Constructor + pred_orF( Pred1T Pred1, Pred2T Pred2 ) : + m_Pred1(Pred1), m_Pred2(Pred2) {} + + // Operation + template + bool operator()( CharT Ch ) const + { + return m_Pred1(Ch) || m_Pred2(Ch); + } + + private: + Pred1T m_Pred1; + Pred2T m_Pred2; + }; + + // class_not composition predicate + template< typename PredT > + struct pred_notF : + public predicate_facade< pred_notF > + { + public: + // Boost.Lambda support + template struct sig { typedef bool type; }; + + // Constructor + pred_notF( PredT Pred ) : m_Pred(Pred) {} + + // Operation + template + bool operator()( CharT Ch ) const + { + return !m_Pred(Ch); + } + + private: + PredT m_Pred; + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP diff --git a/include/boost/algorithm/string/detail/collection_traits.hpp b/include/boost/algorithm/string/detail/collection_traits.hpp new file mode 100644 index 0000000..9435753 --- /dev/null +++ b/include/boost/algorithm/string/detail/collection_traits.hpp @@ -0,0 +1,620 @@ +// Boost string_algo library collection_traits.hpp header 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. + +#ifndef BOOST_STRING_DETAIL_COLLECTION_TRAITS_HPP +#define BOOST_STRING_DETAIL_COLLECTION_TRAITS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Container traits implementation --------------------------------------------------------- + +namespace boost { + namespace algorithm { + namespace detail { + +// Default collection traits ----------------------------------------------------------------- + + // Default collection helper + /* + Wraps std::container compliant containers + */ + template< typename ContainerT > + struct default_container_traits + { + typedef BOOST_STRING_TYPENAME ContainerT::value_type value_type; + typedef BOOST_STRING_TYPENAME ContainerT::iterator iterator; + typedef BOOST_STRING_TYPENAME ContainerT::const_iterator const_iterator; + typedef BOOST_STRING_TYPENAME + ::boost::mpl::if_< ::boost::is_const, + const_iterator, + iterator + >::type result_iterator; + typedef BOOST_STRING_TYPENAME ContainerT::difference_type difference_type; + typedef BOOST_STRING_TYPENAME ContainerT::size_type size_type; + + // static operations + template< typename C > + static size_type size( const C& c ) + { + return c.size(); + } + + template< typename C > + static bool empty( const C& c ) + { + return c.empty(); + } + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< typename C > + static iterator begin( C& c ) + { + return c.begin(); + } + + template< typename C > + static const_iterator begin( const C& c ) + { + return c.begin(); + } + + template< typename C > + static iterator end( C& c ) + { + return c.end(); + } + + template< typename C > + static const_iterator end( const C& c ) + { + return c.end(); + } + +#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< typename C > + static result_iterator begin( C& c ) + { + return c.begin(); + } + + template< typename C > + static result_iterator end( C& c ) + { + return c.end(); + } + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + }; + + template + struct default_container_traits_selector + { + typedef default_container_traits type; + }; + +// Pair container traits --------------------------------------------------------------------- + + // pair selector + template< typename T, typename U > + yes_type is_pair_impl( const std::pair* ); + no_type is_pair_impl( ... ); + + template struct is_pair + { + private: + static T* t; + public: + BOOST_STATIC_CONSTANT( bool, value= + sizeof(is_pair_impl(t))==sizeof(yes_type) ); + }; + + // pair helper + template< typename PairT > + struct pair_container_traits + { + typedef BOOST_STRING_TYPENAME PairT::first_type element_type; + + typedef BOOST_STRING_TYPENAME ::boost::detail:: + iterator_traits::value_type value_type; + typedef std::size_t size_type; + typedef BOOST_STRING_TYPENAME ::boost::detail:: + iterator_traits::difference_type difference_type; + + typedef element_type iterator; + typedef element_type const_iterator; + typedef element_type result_iterator; + + // static operations + template< typename P > + static size_type size( const P& p ) + { + difference_type diff = std::distance( p.first, p.second ); + if ( diff < 0 ) + return 0; + else + return diff; + } + + template< typename P > + static bool empty( const P& p ) + { + return p.first==p.second; + } + + template< typename P > + static const_iterator begin( const P& p ) + { + return p.first; + } + + template< typename P > + static const_iterator end( const P& p ) + { + return p.second; + } + }; // 'pair_container_helper' + + template + struct pair_container_traits_selector + { + typedef pair_container_traits type; + }; + +// Array container traits --------------------------------------------------------------- + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // array traits ( partial specialization ) + template< typename T > + struct array_traits; + + template< typename T, std::size_t sz > + struct array_traits + { + // typedef + typedef T* iterator; + typedef const T* const_iterator; + typedef T value_type; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + // size of the array ( static ); + BOOST_STATIC_CONSTANT( size_type, array_size = sz ); + }; + +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // array traits ( no partial specialization ) + /* + without parial specialization we are able to + provide support only for a limited number of + types. Currently the primitive numeric types + are supported + */ + template< typename T, typename BaseT > + struct array_traits_impl + { + typedef BaseT value_type; + typedef BaseT* iterator; + typedef const BaseT* const_iterator; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + // size of the array + BOOST_STATIC_CONSTANT( size_type, array_size = sizeof(T)/sizeof(BaseT) ); + }; + + template< typename T, typename BaseT > + struct array_traits_impl_selector + { + typedef array_traits_impl type; + }; + + struct array_traits_void + { + typedef void type; + }; + + template< typename T, typename BaseT > + struct array_traits_cv_selector + { + typedef BOOST_STRING_TYPENAME + ::boost::mpl::apply_if< + ::boost::is_convertible, + array_traits_impl_selector, + ::boost::mpl::apply_if< + ::boost::is_convertible, + array_traits_impl_selector, + ::boost::mpl::apply_if< + ::boost::is_convertible, + array_traits_impl_selector, + array_traits_impl_selector + > + > + >::type type; + }; + + template< typename T > + struct array_traits_select + { + template< typename T1, typename T2 > + struct apply + { + typedef BOOST_STRING_TYPENAME + ::boost::mpl::apply_if< + ::boost::is_convertible, + array_traits_cv_selector, + ::boost::mpl::identity >::type type; + }; + }; + + template< typename T > + struct array_traits_selector + { + private: + // supported array base types +#ifndef BOOST_NO_INTRINSIC_WCHAR_T + typedef BOOST_STRING_TYPENAME + ::boost::mpl::vector10< + wchar_t, +#else // BOOST_NO_INTRINSIC_WCHAR_T + typedef BOOST_STRING_TYPENAME + ::boost::mpl::vector9< +#endif // BOOST_NO_INTRINSIC_WCHAR_T + char, + signed char, + unsigned char, + signed short, + unsigned short, + signed int, + unsigned int, + signed long, + unsigned long + >::type array_base_types; + + public: + typedef BOOST_STRING_TYPENAME + ::boost::mpl::fold< + array_base_types, + ::boost::string_algo::detail::array_traits_void, + ::boost::string_algo::detail::array_traits_select >::type type; + }; + + template< typename T > + struct array_traits + { + typedef BOOST_STRING_TYPENAME + array_traits_selector::type traits_type; + + typedef BOOST_STRING_TYPENAME + traits_type::value_type value_type; + typedef BOOST_STRING_TYPENAME + traits_type::iterator iterator; + typedef BOOST_STRING_TYPENAME + traits_type::const_iterator const_iterator; + typedef BOOST_STRING_TYPENAME + traits_type::size_type size_type; + typedef BOOST_STRING_TYPENAME + traits_type::difference_type difference_type; + + BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size ); + }; + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // array lenght resolving + /* + Lenght of string contained in a static array could + be different from the size of the array. + For string processing we need the lenght without + terminating 0. + + Therefore, the lenght is calulated for char and wchar_t + using char_traits, rather then simply returning + the array size. + */ + template< typename T > + struct array_length_selector + { + template< typename TraitsT > + struct array_length + { + typedef BOOST_STRING_TYPENAME + TraitsT::size_type size_type; + + BOOST_STATIC_CONSTANT( + size_type, + array_size=TraitsT::array_size ); + + template< typename A > + static size_type length( const A& ) + { + return array_size; + } + + template< typename A > + static bool empty( const A& ) + { + return array_size==0; + } + }; + }; + + // specialization for char + template<> + struct array_length_selector + { + template< typename TraitsT > + struct array_length + { + typedef BOOST_STRING_TYPENAME + TraitsT::size_type size_type; + + template< typename A > + static size_type length( const A& a ) + { + if ( a==0 ) + return 0; + else + return std::char_traits::length(a); + } + + template< typename A > + static bool empty( const A& a ) + { + return a==0 || a[0]==0; + } + }; + }; + + // specialization for wchar_t + template<> + struct array_length_selector + { + template< typename TraitsT > + struct array_length + { + typedef BOOST_STRING_TYPENAME + TraitsT::size_type size_type; + + template< typename A > + static size_type length( const A& a ) + { + if ( a==0 ) + return 0; + else + return std::char_traits::length(a); + } + + template< typename A > + static bool empty( const A& a ) + { + return a==0 || a[0]==0; + } + }; + }; + + template< typename T > + struct array_container_traits + { + private: + // resolve array traits + typedef array_traits traits_type; + + public: + typedef BOOST_STRING_TYPENAME + traits_type::value_type value_type; + typedef BOOST_STRING_TYPENAME + traits_type::iterator iterator; + typedef BOOST_STRING_TYPENAME + traits_type::const_iterator const_iterator; + typedef BOOST_STRING_TYPENAME + traits_type::size_type size_type; + typedef BOOST_STRING_TYPENAME + traits_type::difference_type difference_type; + + typedef BOOST_STRING_TYPENAME + ::boost::mpl::if_< ::boost::is_const, + const_iterator, + iterator + >::type result_iterator; + + private: + // resolve array size + typedef BOOST_STRING_TYPENAME + ::boost::remove_cv::type char_type; + typedef BOOST_STRING_TYPENAME + array_length_selector:: + BOOST_NESTED_TEMPLATE array_length array_length_type; + + public: + BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size ); + + // static operations + template< typename A > + static size_type size( const A& a ) + { + return array_length_type::length(a); + } + + template< typename A > + static bool empty( const A& a ) + { + return array_length_type::empty(a); + } + + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< typename A > + static iterator begin( A& a ) + { + return a; + } + + template< typename A > + static const_iterator begin( const A& a ) + { + return a; + } + + template< typename A > + static iterator end( A& a ) + { + return a+array_length_type::length(a); + } + + template< typename A > + static const_iterator end( const A& a ) + { + return a+array_length_type::length(a); + } + +#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< typename A > + static result_iterator begin( A& a ) + { + return a; + } + + template< typename A > + static result_iterator end( A& a ) + { + return a+array_length_type::length(a); + } + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + }; + + template + struct array_container_traits_selector + { + typedef array_container_traits type; + }; + +// Pointer container traits --------------------------------------------------------------- + + template + struct pointer_container_traits + { + typedef BOOST_STRING_TYPENAME + ::boost::remove_pointer::type value_type; + + typedef BOOST_STRING_TYPENAME + ::boost::remove_cv::type char_type; + typedef ::std::char_traits char_traits; + + typedef value_type* iterator; + typedef const value_type* const_iterator; + typedef BOOST_STRING_TYPENAME std::ptrdiff_t difference_type; + typedef BOOST_STRING_TYPENAME std::size_t size_type; + + typedef BOOST_STRING_TYPENAME + ::boost::mpl::if_< ::boost::is_const, + const_iterator, + iterator + >::type result_iterator; + + // static operations + template< typename P > + static size_type size( const P& p ) + { + if ( p==0 ) + return 0; + else + return char_traits::length(p); + } + + template< typename P > + static bool empty( const P& p ) + { + return p==0 || p[0]==0; + } + +#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< typename P > + static iterator begin( P& p ) + { + return p; + } + + template< typename P > + static const_iterator begin( const P& p ) + { + return p; + } + + template< typename P > + static iterator end( P& p ) + { + if ( p==0 ) + return p; + else + return p+char_traits::length(p); + } + + template< typename P > + static const_iterator end( const P& p ) + { + if ( p==0 ) + return p; + else + return p+char_traits::length(p); + } + +#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + + template< typename P > + static result_iterator begin( P& p ) + { + return p; + } + + template< typename P > + static result_iterator end( P& p ) + { + if ( p==0 ) + return p; + else + return p+char_traits::length(p); + } + +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + }; + + template + struct pointer_container_traits_selector + { + typedef pointer_container_traits type; + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_DETAIL_COLLECTION_HPP diff --git a/include/boost/algorithm/string/detail/find_format.hpp b/include/boost/algorithm/string/detail/find_format.hpp new file mode 100644 index 0000000..ca0dfd1 --- /dev/null +++ b/include/boost/algorithm/string/detail/find_format.hpp @@ -0,0 +1,205 @@ +// Boost string_algo library find_format.hpp header 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. + +#ifndef BOOST_STRING_FIND_FORMAT_DETAIL_HPP +#define BOOST_STRING_FIND_FORMAT_DETAIL_HPP + +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// find_format_copy (iterator variant) implementation -------------------------------// + + template< + typename OutputIteratorT, + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT > + inline OutputIteratorT find_format_copy_impl( + OutputIteratorT Output, + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult ) + { + return find_format_copy_impl2( + Output, + Input, + Finder, + Formatter, + FindResult, + Formatter(FindResult) ); + } + + template< + typename OutputIteratorT, + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline OutputIteratorT find_format_copy_impl2( + OutputIteratorT Output, + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult, + const FormatResultT& FormatResult ) + { + typedef find_format_store< + BOOST_STRING_TYPENAME + const_iterator_of::type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + if ( !M ) + { + // Match not found - return original sequence + std::copy( begin(Input), end(Input), Output ); + return Output; + } + + // Copy the beginning of the sequence + std::copy( begin(Input), begin(M), Output ); + // Format find result + // Copy formated result + std::copy( begin(M.format_result()), end(M.format_result()), Output ); + // Copy the rest of the sequence + std::copy( M.end(), end(Input), Output ); + + return Output; + } + +// find_format_copy implementation --------------------------------------------------// + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT > + inline InputT find_format_copy_impl( + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult) + { + return find_format_copy_impl2( + Input, + Finder, + Formatter, + FindResult, + Formatter(FindResult) ); + } + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline InputT find_format_copy_impl2( + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult, + const FormatResultT& FormatResult) + { + typedef find_format_store< + BOOST_STRING_TYPENAME + const_iterator_of::type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + if ( !M ) + { + // Match not found - return original sequence + return InputT( Input ); + } + + InputT Output; + // Copy the beginning of the sequence + insert( Output, end(Output), begin(Input), M.begin() ); + // Copy formated result + insert( Output, end(Output), M.format_result() ); + // Copy the rest of the sequence + insert( Output, end(Output), M.end(), end(Input) ); + + return Output; + } + +// replace implementation ----------------------------------------------------// + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT > + inline void find_format_impl( + InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult) + { + find_format_impl2( + Input, + Finder, + Formatter, + FindResult, + Formatter(FindResult) ); + } + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline void find_format_impl2( + InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult, + const FormatResultT& FormatResult) + { + typedef find_format_store< + BOOST_STRING_TYPENAME + iterator_of::type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + if ( !M ) + { + // Search not found - return original sequence + return; + } + + // Replace match + replace( Input, M.begin(), M.end(), M.format_result() ); + } + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FIND_FORMAT_DETAIL_HPP diff --git a/include/boost/algorithm/string/detail/find_format_all.hpp b/include/boost/algorithm/string/detail/find_format_all.hpp new file mode 100644 index 0000000..36a4847 --- /dev/null +++ b/include/boost/algorithm/string/detail/find_format_all.hpp @@ -0,0 +1,260 @@ +// Boost string_algo library find_format_all.hpp header 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. + +#ifndef BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP +#define BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP + +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// find_format_all_copy (iterator variant) implementation ---------------------------// + + template< + typename OutputIteratorT, + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT > + inline OutputIteratorT find_format_all_copy_impl( + OutputIteratorT Output, + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult ) + { + return find_format_all_copy_impl2( + Output, + Input, + Finder, + Formatter, + FindResult, + Formatter(FindResult) ); + } + + template< + typename OutputIteratorT, + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline OutputIteratorT find_format_all_copy_impl2( + OutputIteratorT Output, + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult, + const FormatResultT& FormatResult ) + { + typedef BOOST_STRING_TYPENAME + const_iterator_of::type input_iterator_type; + + typedef find_format_store< + input_iterator_type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + // Initialize last match + input_iterator_type LastMatch=begin(Input); + + // Iterate throug all matches + while( M ) + { + // Copy the beginning of the sequence + std::copy( LastMatch, M.begin(), Output ); + // Copy formated result + std::copy( begin(M.format_result()), end(M.format_result()), Output ); + + // Proceed to the next match + LastMatch=M.end(); + M=Finder( LastMatch, end(Input) ); + } + + // Copy the rest of the sequence + std::copy( LastMatch, end(Input), Output ); + + return Output; + } + +// find_format_all_copy implementation ----------------------------------------------// + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT > + inline InputT find_format_all_copy_impl( + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult) + { + return find_format_all_copy_impl2( + Input, + Finder, + Formatter, + FindResult, + Formatter(FindResult) ); + } + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline InputT find_format_all_copy_impl2( + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult, + const FormatResultT& FormatResult) + { + typedef BOOST_STRING_TYPENAME + const_iterator_of::type input_iterator_type; + + typedef find_format_store< + input_iterator_type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + // Initialize last match + input_iterator_type LastMatch=begin(Input); + + // Output temporary + InputT Output; + + // Iterate throug all matches + while( M ) + { + // Copy the beginning of the sequence + insert( Output, end(Output), LastMatch, M.begin() ); + // Copy formated result + insert( Output, end(Output), M.format_result() ); + + // Proceed to the next match + LastMatch=M.end(); + M=Finder( LastMatch, end(Input) ); + } + + // Copy the rest of the sequence + insert( Output, end(Output), LastMatch, end(Input) ); + + return Output; + } + +// find_format_all implementation ------------------------------------------------// + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT > + inline void find_format_all_impl( + InputT& Input, + FinderT Finder, + FormatterT Formatter, + FindResultT FindResult) + { + find_format_all_impl2( + Input, + Finder, + Formatter, + FindResult, + Formatter(FindResult) ); + } + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline void find_format_all_impl2( + InputT& Input, + FinderT Finder, + FormatterT Formatter, + FindResultT FindResult, + FormatResultT FormatResult) + { + typedef BOOST_STRING_TYPENAME + iterator_of::type input_iterator_type; + typedef find_format_store< + input_iterator_type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + // Instantiate replacement storage + std::deque< + BOOST_STRING_TYPENAME value_type_of::type> Storage; + + // Initialize replacement iterators + input_iterator_type InsertIt=begin(Input); + input_iterator_type SearchIt=begin(Input); + + while( M ) + { + // process the segment + InsertIt=process_segment( + Storage, + Input, + InsertIt, + SearchIt, + M.begin() ); + + // Adjust search iterator + SearchIt=M.end(); + + // Copy formated replace to the storage + copy_to_storage( Storage, M.format_result() ); + + // Find range for a next match + M=Finder( SearchIt, end(Input) ); + } + + // process the last segment + InsertIt=process_segment( + Storage, + Input, + InsertIt, + SearchIt, + end(Input) ); + + if ( Storage.empty() ) + { + // Truncate input + erase( Input, InsertIt, end(Input) ); + } + else + { + // Copy remaining data to the end of input + insert( Input, end(Input), Storage.begin(), Storage.end() ); + } + } + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP diff --git a/include/boost/algorithm/string/detail/find_format_store.hpp b/include/boost/algorithm/string/detail/find_format_store.hpp new file mode 100644 index 0000000..c67d395 --- /dev/null +++ b/include/boost/algorithm/string/detail/find_format_store.hpp @@ -0,0 +1,71 @@ +// Boost string_algo library find_format_store.hpp header 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. + +#ifndef BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP +#define BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP + +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// temporary format and find result storage --------------------------------// + + template< + typename ForwardIteratorT, + typename FormatterT, + typename FormatResultT > + class find_format_store : + public iterator_range + { + public: + // typedefs + typedef iterator_range base_type; + typedef FormatterT formatter_type; + typedef FormatResultT format_result_type; + + public: + // Construction + find_format_store( + const base_type FindResult, + const format_result_type& FormatResult, + const formatter_type& Formatter ) : + base_type(FindResult), + m_FormatResult(FormatResult), + m_Formatter(Formatter) {} + + // Assignment + template< typename FindResultT > + find_format_store& operator=( FindResultT FindResult ) + { + iterator_range::operator=(FindResult); + m_FormatResult=m_Formatter(FindResult); + + return *this; + } + + // Retrieve format result + const format_result_type& format_result() + { + return m_FormatResult; + } + + private: + format_result_type m_FormatResult; + const formatter_type& m_Formatter; + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP diff --git a/include/boost/algorithm/string/detail/find_iterator.hpp b/include/boost/algorithm/string/detail/find_iterator.hpp new file mode 100644 index 0000000..1a02bc4 --- /dev/null +++ b/include/boost/algorithm/string/detail/find_iterator.hpp @@ -0,0 +1,144 @@ +// Boost string_algo library find_iterator.hpp header 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. + +#ifndef BOOST_STRING_FIND_ITERATOR_DETAIL_HPP +#define BOOST_STRING_FIND_ITERATOR_DETAIL_HPP + + +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// finder virtualizer -----------------------------------------------// + + template + struct virtual_finder + { + // typedefs + typedef IteratorT input_iterator_type; + typedef iterator_range match_type; + + // virtual destructor + virtual ~virtual_finder() {} + + // clone + virtual virtual_finder* clone() const=0; + + // operation + virtual match_type do_find( + input_iterator_type Begin, + input_iterator_type End ) const=0; + }; + + template + struct virtual_finder_typed : public virtual_finder + { + // typedefs + typedef virtual_finder base_type; + typedef BOOST_STRING_TYPENAME + base_type::input_iterator_type input_iterator_type; + typedef BOOST_STRING_TYPENAME + base_type::match_type match_type; + + // constuction + virtual_finder_typed( FinderT Finder ) : m_Finder(Finder) {} + + // clone + virtual_finder_typed* clone() const + { + return new virtual_finder_typed(m_Finder); + } + + // operation + virtual match_type do_find( + input_iterator_type Begin, + input_iterator_type End ) const + { + return m_Finder(Begin,End); + } + + private: + // Finder + FinderT m_Finder; + }; + + +// find_iterator base -----------------------------------------------// + + // Find iterator base + template + class find_iterator_base + { + protected: + // typedefs + typedef IteratorT input_iterator_type; + typedef iterator_range match_type; + + protected: + // Protected construction/destruction + + // Default constructor + find_iterator_base() : m_pFinder(0) {}; + // Copy construction + find_iterator_base( const find_iterator_base& Other ) : + m_pFinder(0) + { + if ( Other.m_pFinder ) + { + m_pFinder=Other.m_pFinder->clone(); + } + } + // Constructor + template + find_iterator_base( FinderT Finder, int ) : + m_pFinder( new virtual_finder_typed(Finder) ) {} + + // Destructor + ~find_iterator_base() + { + if (m_pFinder) delete m_pFinder; + } + + // Find operation + match_type do_find( + input_iterator_type Begin, + input_iterator_type End ) const + { + if (m_pFinder) + { + return m_pFinder->do_find(Begin,End); + } + else + { + return match_type(End,End); + } + } + + // Check + bool is_null() const + { + return !m_pFinder; + } + + private: + // Finder + virtual_finder* m_pFinder; + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_FIND_ITERATOR_DETAIL_HPP diff --git a/include/boost/algorithm/string/detail/finder.hpp b/include/boost/algorithm/string/detail/finder.hpp new file mode 100644 index 0000000..7f68de5 --- /dev/null +++ b/include/boost/algorithm/string/detail/finder.hpp @@ -0,0 +1,528 @@ +// Boost string_algo library finder.hpp header 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. + +#ifndef BOOST_STRING_FINDER_DETAIL_HPP +#define BOOST_STRING_FINDER_DETAIL_HPP + +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + + +// find first functor -----------------------------------------------// + + // find a subsequence in the sequence ( functor ) + /* + Returns a pair marking the subsequence in the sequence. + If the find fails, functor returns + */ + template + struct first_finderF + { + typedef SearchIteratorT search_iterator_type; + + // Construction + template< typename SearchT > + first_finderF( const SearchT& Search, PredicateT Comp ) : + m_Search(begin(Search), end(Search)), m_Comp(Comp) {} + first_finderF( + search_iterator_type SearchBegin, + search_iterator_type SearchEnd, + PredicateT Comp ) : + m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef iterator_range result_type; + typedef ForwardIteratorT input_iterator_type; + + // Outer loop + for(input_iterator_type OuterIt=Begin; + OuterIt!=End; + ++OuterIt) + { + // Sanity check + if( empty(m_Search) ) + return result_type( End, End ); + + input_iterator_type InnerIt=OuterIt; + search_iterator_type SubstrIt=m_Search.begin(); + for(; + InnerIt!=End && SubstrIt!=m_Search.end(); + ++InnerIt,++SubstrIt) + { + if( !( m_Comp(*InnerIt,*SubstrIt) ) ) + break; + } + + // Substring matching succeeded + if ( SubstrIt==m_Search.end() ) + return result_type( OuterIt, InnerIt ); + } + + return result_type( End, End ); + } + + private: + iterator_range m_Search; + PredicateT m_Comp; + }; + +// find last functor -----------------------------------------------// + + // find the last match a subsequnce in the sequence ( functor ) + /* + Returns a pair marking the subsequence in the sequence. + If the find fails, returns + */ + template + struct last_finderF + { + typedef SearchIteratorT search_iterator_type; + typedef first_finderF< + search_iterator_type, + PredicateT> first_finder_type; + + // Construction + template< typename SearchT > + last_finderF( const SearchT& Search, PredicateT Comp ) : + m_Search(begin(Search), end(Search)), m_Comp(Comp) {} + last_finderF( + search_iterator_type SearchBegin, + search_iterator_type SearchEnd, + PredicateT Comp ) : + m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef iterator_range result_type; + + if( empty(m_Search) ) + return result_type( End, End ); + + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return findit( Begin, End, category() ); + } + + private: + // forward iterator + template< typename ForwardIteratorT > + iterator_range + findit( + ForwardIteratorT Begin, + ForwardIteratorT End, + std::forward_iterator_tag ) const + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + first_finder_type first_finder( + m_Search.begin(), m_Search.end(), m_Comp ); + + result_type M=first_finder( Begin, End ); + result_type Last=M; + + while( M ) + { + Last=M; + M=first_finder( end(M), End ); + } + + return Last; + } + + // bidirectional iterator + template< typename ForwardIteratorT > + iterator_range + findit( + ForwardIteratorT Begin, + ForwardIteratorT End, + std::bidirectional_iterator_tag ) const + { + typedef iterator_range result_type; + typedef ForwardIteratorT input_iterator_type; + + // Outer loop + for(input_iterator_type OuterIt=End; + OuterIt!=Begin; ) + { + input_iterator_type OuterIt2=--OuterIt; + + input_iterator_type InnerIt=OuterIt2; + search_iterator_type SubstrIt=m_Search.begin(); + for(; + InnerIt!=End && SubstrIt!=m_Search.end(); + ++InnerIt,++SubstrIt) + { + if( !( m_Comp(*InnerIt,*SubstrIt) ) ) + break; + } + + // Substring matching succeeded + if( SubstrIt==m_Search.end() ) + return result_type( OuterIt2, InnerIt ); + } + + return result_type( End, End ); + } + + private: + iterator_range m_Search; + PredicateT m_Comp; + }; + +// find n-th functor -----------------------------------------------// + + // find the n-th match of a subsequnce in the sequence ( functor ) + /* + Returns a pair marking the subsequence in the sequence. + If the find fails, returns + */ + template + struct nth_finderF + { + typedef SearchIteratorT search_iterator_type; + typedef first_finderF< + search_iterator_type, + PredicateT> first_finder_type; + + // Construction + template< typename SearchT > + nth_finderF( + const SearchT& Search, + unsigned int Nth, + PredicateT Comp) : + m_Search(begin(Search), end(Search)), + m_Nth(Nth), + m_Comp(Comp) {} + nth_finderF( + search_iterator_type SearchBegin, + search_iterator_type SearchEnd, + unsigned int Nth, + PredicateT Comp) : + m_Search(SearchBegin, SearchEnd), + m_Nth(Nth), + m_Comp(Comp) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + // Sanity check + if( empty(m_Search) ) + return result_type( End, End ); + + // Instantiate find funtor + first_finder_type first_finder( + m_Search.begin(), m_Search.end(), m_Comp ); + + result_type M( Begin, Begin ); + + for( unsigned int n=0; n<=m_Nth; ++n ) + { + // find next match + M=first_finder( end(M), End ); + + if ( !M ) + { + // Subsequence not found, return + return M; + } + } + + return M; + } + + private: + iterator_range m_Search; + unsigned int m_Nth; + PredicateT m_Comp; + }; + +// find head functor -----------------------------------------------// + + // find a head in the sequence ( functor ) + /* + This functor find a head of the specified range. For + a specified N, the head is a subsequence of N starting + elements of the range. + */ + struct head_finderF + { + // Construction + head_finderF( unsigned int N ) : m_N(N) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return findit( Begin, End, category() ); + } + + private: + // Find operation implementation + template< typename ForwardIteratorT > + iterator_range + findit( + ForwardIteratorT Begin, + ForwardIteratorT End, + std::forward_iterator_tag ) const + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + input_iterator_type It=Begin; + for( + unsigned int Index=0; + Index + iterator_range + findit( + ForwardIteratorT Begin, + ForwardIteratorT End, + std::random_access_iterator_tag ) const + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + input_iterator_type It=Begin+m_N; + if ( It >= End ) It=End; + + return result_type( Begin, It ); + } + + private: + unsigned int m_N; + }; + +// find tail functor -----------------------------------------------// + + // find a tail in the sequence ( functor ) + /* + This functor find a tail of the specified range. For + a specified N, the head is a subsequence of N starting + elements of the range. + */ + struct tail_finderF + { + // Construction + tail_finderF( unsigned int N ) : m_N(N) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return findit( Begin, End, category() ); + } + + private: + // Find operation implementation + template< typename ForwardIteratorT > + iterator_range + findit( + ForwardIteratorT Begin, + ForwardIteratorT End, + std::forward_iterator_tag ) const + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + unsigned int Index=0; + input_iterator_type It=Begin; + input_iterator_type It2=Begin; + + // Advance It2 by N incremets + for( Index=0; Index + iterator_range + findit( + ForwardIteratorT Begin, + ForwardIteratorT End, + std::bidirectional_iterator_tag ) const + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + input_iterator_type It=End; + for( + unsigned int Index=0; + Index + iterator_range + findit( + ForwardIteratorT Begin, + ForwardIteratorT End, + std::random_access_iterator_tag ) const + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + if ( (End<=Begin) || (End < (Begin+m_N) ) ) + return result_type( Begin, End ); + + return result_type( End-m_N, End ); + } + + + private: + unsigned int m_N; + }; + +// find token functor -----------------------------------------------// + + // find a token in a sequence ( functor ) + /* + This find functor finds a token specified be a predicate + in a sequence. It is equivalent of std::find algorithm, + with an exception that it return range instead of a single + iterator. + + If bCompress is set to true, adjacent matching tokens are + concatenated into one match. + */ + template< typename PredicateT > + struct token_finderF + { + // Construction + token_finderF( + PredicateT Pred, + token_compress_mode_type eCompress=token_compress_off ) : + m_Pred(Pred), m_eCompress(eCompress) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef iterator_range result_type; + + ForwardIteratorT It=std::find_if( Begin, End, m_Pred ); + + if( It==End ) + { + return result_type( End, End ); + } + else + { + ForwardIteratorT It2=It; + + if( m_eCompress==token_compress_on ) + { + // Find first non-matching character + while( m_Pred(*It2) && It2!=End ) ++It2; + } + else + { + // Advance by one possition + ++It2; + } + + return result_type( It, It2 ); + } + } + + private: + PredicateT m_Pred; + token_compress_mode_type m_eCompress; + }; + +// find range functor -----------------------------------------------// + + // find a range in the sequence ( functor ) + /* + This functor actually does not perform any find operation. + It always returns given iterator range as a result. + */ + template + struct range_finderF + { + typedef ForwardIterator1T input_iterator_type; + typedef iterator_range result_type; + + // Construction + range_finderF( + input_iterator_type Begin, + input_iterator_type End ) : m_Range(Begin, End) {} + + range_finderF(const iterator_range& Range) : + m_Range(Range) {} + + // Operation + template< typename ForwardIterator2T > + iterator_range + operator()( + ForwardIterator2T, + ForwardIterator2T ) const + { + return m_Range; + } + + private: + iterator_range m_Range; + }; + + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FINDER_DETAIL_HPP diff --git a/include/boost/algorithm/string/detail/finder_regex.hpp b/include/boost/algorithm/string/detail/finder_regex.hpp new file mode 100644 index 0000000..9006151 --- /dev/null +++ b/include/boost/algorithm/string/detail/finder_regex.hpp @@ -0,0 +1,120 @@ +// Boost string_algo library find_regex.hpp header 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. + +#ifndef BOOST_STRING_FINDER_REGEX_DETAIL_HPP +#define BOOST_STRING_FINDER_REGEX_DETAIL_HPP + +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// regex find functor -----------------------------------------------// + + // regex search result + template + struct regex_search_result : + public iterator_range + { + typedef regex_search_result type; + typedef iterator_range base_type; + typedef BOOST_STRING_TYPENAME base_type::value_type value_type; + typedef BOOST_STRING_TYPENAME base_type::reference reference; + typedef BOOST_STRING_TYPENAME base_type::difference_type difference_type; + typedef BOOST_STRING_TYPENAME base_type::const_iterator const_iterator; + typedef BOOST_STRING_TYPENAME base_type::iterator iterator; + typedef match_results match_results_type; + + // Contruction + + // Construction from the match result + regex_search_result( const match_results_type& MatchResults ) : + base_type( MatchResults[0].first, MatchResults[0].second ), + m_MatchResults( MatchResults ) {} + + // Construction of empty match. End iterator has to be specified + regex_search_result( IteratorT End ) : + base_type( End, End ) {} + + regex_search_result( const regex_search_result& Other ) : + base_type( Other.begin(), Other.end() ), + m_MatchResults( Other.m_MatchResults ) {} + + // Assignment + regex_search_result& operator=( const regex_search_result& Other ) + { + base_type::operator=( Other ); + m_MatchResults=Other.m_MatchResults; + return *this; + } + + // Match result retrival + const match_results_type& match_results() const + { + return m_MatchResults; + } + + private: + // Saved matchresult + match_results_type m_MatchResults; + }; + + // find_regex + /* + Regex based search functor + */ + template + struct find_regexF + { + typedef RegExT regex_type; + typedef const RegExT& regex_reference_type; + + // Construction + find_regexF( regex_reference_type Rx, match_flag_type MatchFlags = match_default ) : + m_Rx(Rx), m_MatchFlags(MatchFlags) {} + + // Operation + template< typename ForwardIteratorT > + regex_search_result + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef ForwardIteratorT input_iterator_type; + typedef regex_search_result result_type; + + // instantiate match result + match_results result; + // search for a match + if ( regex_search( Begin, End, result, m_Rx, m_MatchFlags ) ) + { + // construct a result + return result_type( result ); + } + else + { + // empty result + return result_type( End ); + } + } + + private: + regex_reference_type m_Rx; // Regexp + match_flag_type m_MatchFlags; // match flags + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FIND_DETAIL_HPP diff --git a/include/boost/algorithm/string/detail/formatter.hpp b/include/boost/algorithm/string/detail/formatter.hpp new file mode 100644 index 0000000..18dd0fd --- /dev/null +++ b/include/boost/algorithm/string/detail/formatter.hpp @@ -0,0 +1,81 @@ +// Boost string_algo library formatter.hpp header 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. + +#ifndef BOOST_STRING_FORMATTER_DETAIL_HPP +#define BOOST_STRING_FORMATTER_DETAIL_HPP + +#include +#include +#include + +// generic replace functors -----------------------------------------------// + +namespace boost { + namespace algorithm { + namespace detail { + +// const format functor ----------------------------------------------------// + + // constant format functor + template + struct const_formatF + { + private: + typedef BOOST_STRING_TYPENAME + const_iterator_of::type format_iterator; + typedef iterator_range result_type; + + public: + // Construction + const_formatF(const CollectionT& Format) : + m_Format(begin(Format), end(Format)) {} + + // Operation + template + const result_type& operator()(const Collection2T&) const + { + return m_Format; + } + + private: + result_type m_Format; + }; + +// identity format functor ----------------------------------------------------// + + // identity format functor + template + struct identity_formatF + { + // Operation + template< typename Collection2T > + const CollectionT& operator()(const Collection2T& Replace) const + { + return CollectionT(begin(Replace), end(Replace)); + } + }; + +// empty format functor ( used by erase ) ------------------------------------// + + // empty format functor + template< typename CharT > + struct empty_formatF + { + template< typename ReplaceT > + empty_container operator()(const ReplaceT&) const + { + return empty_container(); + } + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FORMATTER_DETAIL_HPP diff --git a/include/boost/algorithm/string/detail/formatter_regex.hpp b/include/boost/algorithm/string/detail/formatter_regex.hpp new file mode 100644 index 0000000..0f28fd2 --- /dev/null +++ b/include/boost/algorithm/string/detail/formatter_regex.hpp @@ -0,0 +1,60 @@ +// Boost string_algo library formatter_regex.hpp header 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. + +#ifndef BOOST_STRING_FORMATTER_REGEX_DETAIL_HPP +#define BOOST_STRING_FORMATTER_REGEX_DETAIL_HPP + +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// regex format functor -----------------------------------------// + + // regex format functor + template + struct regex_formatF + { + private: + typedef StringT result_type; + typedef BOOST_STRING_TYPENAME StringT::value_type char_type; + + public: + // Construction + regex_formatF( const StringT& Fmt, match_flag_type Flags=format_default ) : + m_Fmt(Fmt), m_Flags( Flags ) {} + + template + result_type operator()( + const regex_search_result& Replace ) const + { + if ( Replace.empty() ) + { + return result_type(); + } + else + { + return Replace.match_results().format( m_Fmt, m_Flags ); + } + } + private: + const StringT& m_Fmt; + match_flag_type m_Flags; + }; + + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FORMATTER_DETAIL_HPP diff --git a/include/boost/algorithm/string/detail/predicate.hpp b/include/boost/algorithm/string/detail/predicate.hpp new file mode 100644 index 0000000..ea1794d --- /dev/null +++ b/include/boost/algorithm/string/detail/predicate.hpp @@ -0,0 +1,76 @@ +// Boost string_algo library predicate.hpp header 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. + +#ifndef BOOST_STRING_PREDICATE_DETAIL_HPP +#define BOOST_STRING_PREDICATE_DETAIL_HPP + +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// ends_with predicate implementation ----------------------------------// + + template< + typename ForwardIterator1T, + typename ForwardIterator2T, + typename PredicateT> + inline bool ends_with_iter_select( + ForwardIterator1T Begin, + ForwardIterator1T End, + ForwardIterator2T SubBegin, + ForwardIterator2T SubEnd, + PredicateT Comp, + std::bidirectional_iterator_tag) + { + ForwardIterator1T it=End; + ForwardIterator2T pit=SubEnd; + for(;it!=Begin && pit!=SubBegin;) + { + if( !(Comp(*(--it),*(--pit))) ) + return false; + } + + return pit==SubBegin; + } + + template< + typename ForwardIterator1T, + typename ForwardIterator2T, + typename PredicateT> + inline bool ends_with_iter_select( + ForwardIterator1T Begin, + ForwardIterator1T End, + ForwardIterator2T SubBegin, + ForwardIterator2T SubEnd, + PredicateT Comp, + std::forward_iterator_tag) + { + if ( SubBegin==SubEnd ) + { + // empty subsequence check + return true; + } + + iterator_range Result + =last_finder( + make_iterator_range(SubBegin, SubEnd), + Comp)(Begin, End); + + return !Result.empty() && Result.end()==End; + } + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_PREDICATE_DETAIL_HPP diff --git a/include/boost/algorithm/string/detail/replace_storage.hpp b/include/boost/algorithm/string/detail/replace_storage.hpp new file mode 100644 index 0000000..3e7726d --- /dev/null +++ b/include/boost/algorithm/string/detail/replace_storage.hpp @@ -0,0 +1,159 @@ +// Boost string_algo library replace_storage.hpp header 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. + +#ifndef BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP +#define BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// storage handling routines -----------------------------------------------// + + template< typename StorageT, typename OutputIteratorT > + inline OutputIteratorT move_from_storage( + StorageT& Storage, + OutputIteratorT DestBegin, + OutputIteratorT DestEnd ) + { + OutputIteratorT OutputIt=DestBegin; + + while( !Storage.empty() && OutputIt!=DestEnd ) + { + *OutputIt=Storage.front(); + Storage.pop_front(); + ++OutputIt; + } + + return OutputIt; + } + + template< typename StorageT, typename WhatT > + inline void copy_to_storage( + StorageT& Storage, + const WhatT& What ) + { + Storage.insert( Storage.end(), begin(What), end(What) ); + } + + +// process segment routine -----------------------------------------------// + + template< bool HasStableIterators > + struct process_segment_helper + { + // Optimized version of process_segment for generic sequence + template< + typename StorageT, + typename InputT, + typename ForwardIteratorT > + ForwardIteratorT operator()( + StorageT& Storage, + InputT& /*Input*/, + ForwardIteratorT InsertIt, + ForwardIteratorT SegmentBegin, + ForwardIteratorT SegmentEnd ) + { + // Copy data from the storage until the beginning of the segment + ForwardIteratorT It=move_from_storage( Storage, InsertIt, SegmentBegin ); + + // 3 cases are possible : + // a) Storage is empty, It==SegmentBegin + // b) Storage is empty, It!=SegmentBegin + // c) Storage is not empty + + if( Storage.empty() ) + { + if( It==SegmentBegin ) + { + // Case a) everything is grand, just return end of segment + return SegmentEnd; + } + else + { + // Case b) move the segment backwards + return std::copy( SegmentBegin, SegmentEnd, It ); + } + } + else + { + // Case c) -> shift the segment to the left and keep the overlap in the storage + while( It!=SegmentEnd ) + { + // Store value into storage + Storage.push_back( *It ); + // Get the top from the storage and put it here + *It=Storage.front(); + Storage.pop_front(); + + // Advance + ++It; + } + + return It; + } + } + }; + + template<> + struct process_segment_helper< true > + { + // Optimized version of process_segment for list-like sequence + template< + typename StorageT, + typename InputT, + typename ForwardIteratorT > + ForwardIteratorT operator()( + StorageT& Storage, + InputT& Input, + ForwardIteratorT InsertIt, + ForwardIteratorT SegmentBegin, + ForwardIteratorT SegmentEnd ) + { + // Call replace to do the job + replace( Input, InsertIt, SegmentBegin, Storage ); + // Empty the storage + Storage.clear(); + // Iterators were not changed, simply return the end of segment + return SegmentEnd; + } + }; + + // Process one segment in the replace_all algorithm + template< + typename StorageT, + typename InputT, + typename ForwardIteratorT > + inline ForwardIteratorT process_segment( + StorageT& Storage, + InputT& Input, + ForwardIteratorT InsertIt, + ForwardIteratorT SegmentBegin, + ForwardIteratorT SegmentEnd ) + { + return + process_segment_helper< + has_stable_iterators::value>()( + Storage, Input, InsertIt, SegmentBegin, SegmentEnd ); + } + + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP diff --git a/include/boost/algorithm/string/detail/sequence.hpp b/include/boost/algorithm/string/detail/sequence.hpp new file mode 100644 index 0000000..dbce9c9 --- /dev/null +++ b/include/boost/algorithm/string/detail/sequence.hpp @@ -0,0 +1,183 @@ +// Boost string_algo library sequence.hpp header 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. + +#ifndef BOOST_STRING_DETAIL_SEQUENCE_HPP +#define BOOST_STRING_DETAIL_SEQUENCE_HPP + +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// insert helpers -------------------------------------------------// + + template< typename InputT, typename InsertT > + inline void insert( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator At, + const InsertT& Insert ) + { + insert( Input, At, begin(Insert), end(Insert) ); + } + + template< typename InputT, typename ForwardIteratorT > + inline void insert( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator At, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + Input.insert( At, Begin, End ); + } + +// erase helper ---------------------------------------------------// + + // Erase a range in the sequence + /* + Returns the iterator pointing just after the erase subrange + */ + template< typename InputT > + inline typename InputT::iterator erase( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To ) + { + return Input.erase( From, To ); + } + +// replace helper implementation ----------------------------------// + + // Optimized version of replace for generic sequence containers + // Assumption: insert and erase are expensive + template< bool HasConstTimeOperations > + struct replace_const_time_helper + { + template< typename InputT, typename ForwardIteratorT > + void operator()( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + // Copy data to the container ( as much as possible ) + ForwardIteratorT InsertIt=Begin; + BOOST_STRING_TYPENAME InputT::iterator InputIt=From; + for(; InsertIt!=End && InputIt!=To; InsertIt++, InputIt++ ) + { + *InputIt=*InsertIt; + } + + if ( InsertIt!=End ) + { + // Replace sequence is longer, insert it + Input.insert( InputIt, InsertIt, End ); + } + else + { + if ( InputIt!=To ) + { + // Replace sequence is shorter, erase the rest + Input.erase( InputIt, To ); + } + } + } + }; + + template<> + struct replace_const_time_helper< true > + { + // Const-time erase and insert methods -> use them + template< typename InputT, typename ForwardIteratorT > + void operator()( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + BOOST_STRING_TYPENAME InputT::iterator At=Input.erase( From, To ); + if ( Begin!=End ) + { + Input.insert( At, Begin, End ); + } + } + }; + + // No native replace method + template< bool HasNative > + struct replace_native_helper + { + template< typename InputT, typename ForwardIteratorT > + void operator()( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + replace_const_time_helper< + boost::mpl::and_< + has_const_time_insert, + has_const_time_erase >::value >()( + Input, From, To, Begin, End ); + } + }; + + // Container has native replace method + template<> + struct replace_native_helper< true > + { + template< typename InputT, typename ForwardIteratorT > + void operator()( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + Input.replace( From, To, Begin, End ); + } + }; + +// replace helper -------------------------------------------------// + + template< typename InputT, typename InsertT > + inline void replace( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + const InsertT& Insert ) + { + replace( Input, From, To, begin(Insert), end(Insert) ); + } + + template< typename InputT, typename ForwardIteratorT > + inline void replace( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + replace_native_helper< has_native_replace::value >()( + Input, From, To, Begin, End ); + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_DETAIL_SEQUENCE_HPP diff --git a/include/boost/algorithm/string/detail/trim.hpp b/include/boost/algorithm/string/detail/trim.hpp new file mode 100644 index 0000000..502eca3 --- /dev/null +++ b/include/boost/algorithm/string/detail/trim.hpp @@ -0,0 +1,94 @@ +// Boost string_algo library trim.hpp header 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. + +#ifndef BOOST_STRING_TRIM_DETAIL_HPP +#define BOOST_STRING_TRIM_DETAIL_HPP + +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// trim iterator helper -----------------------------------------------// + + // Search for first non matching character from the beginning of the sequence + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_begin( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace ) + { + ForwardIteratorT It=InBegin; + for(; It!=InEnd; ++It ) + { + if (!IsSpace(*It)) + return It; + } + + return It; + } + + // Search for first non matching character from the end of the sequence + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_end( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace ) + { + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return trim_end_iter_select( InBegin, InEnd, IsSpace, category() ); + } + + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_end_iter_select( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace, + std::forward_iterator_tag ) + { + ForwardIteratorT TrimIt=InBegin; + + for( ForwardIteratorT It=InBegin; It!=InEnd; ++It ) + { + if ( !IsSpace(*It) ) + { + TrimIt=It; + ++TrimIt; + } + } + + return TrimIt; + } + + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_end_iter_select( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace, + std::bidirectional_iterator_tag ) + { + for( ForwardIteratorT It=InEnd; It!=InBegin; ) + { + if ( !IsSpace(*(--It)) ) + return ++It; + } + + return InBegin; + } + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_TRIM_DETAIL_HPP diff --git a/include/boost/algorithm/string/detail/util.hpp b/include/boost/algorithm/string/detail/util.hpp new file mode 100644 index 0000000..7656fbe --- /dev/null +++ b/include/boost/algorithm/string/detail/util.hpp @@ -0,0 +1,104 @@ +// Boost string_algo library util.hpp header 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. + +#ifndef BOOST_STRING_UTIL_DETAIL_HPP +#define BOOST_STRING_UTIL_DETAIL_HPP + +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// empty container -----------------------------------------------// + + // empty_container + /* + This class represents always empty container, + containing elemets of type CharT. + + It is supposed to be used in a const version only + */ + template< typename CharT > + struct empty_container + { + typedef empty_container type; + typedef CharT value_type; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef const value_type& reference; + typedef const value_type& const_reference; + typedef const value_type* iterator; + typedef const value_type* const_iterator; + + + // Operations + const_iterator begin() const + { + return reinterpret_cast(0); + } + + const_iterator end() const + { + return reinterpret_cast(0); + } + + bool empty() const + { + return false; + } + + size_type size() const + { + return 0; + } + }; + +// bounded copy algorithm -----------------------------------------------// + + // Bounded version of the std::copy algorithm + template + inline OutputIteratorT bounded_copy( + InputIteratorT First, + InputIteratorT Last, + OutputIteratorT DestFirst, + OutputIteratorT DestLast ) + { + InputIteratorT InputIt=First; + OutputIteratorT OutputIt=DestFirst; + for(; InputIt!=Last && OutputIt!=DestLast; InputIt++, OutputIt++ ) + { + *OutputIt=*InputIt; + } + + return OutputIt; + } + +// iterator range utilities -----------------------------------------// + + // copy range functor + template< + typename SeqT, + typename IteratorT=BOOST_STRING_TYPENAME SeqT::const_iterator > + struct copy_iterator_rangeF : + public std::unary_function< iterator_range, SeqT > + { + SeqT operator()( const iterator_range& Range ) const + { + return copy_iterator_range(Range); + } + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_UTIL_DETAIL_HPP diff --git a/include/boost/algorithm/string/erase.hpp b/include/boost/algorithm/string/erase.hpp new file mode 100644 index 0000000..029562a --- /dev/null +++ b/include/boost/algorithm/string/erase.hpp @@ -0,0 +1,838 @@ +// Boost string_algo library erase.hpp header 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. + +#ifndef BOOST_STRING_ERASE_HPP +#define BOOST_STRING_ERASE_HPP + +#include +#include +#include +#include +#include +#include + +/*! \file + Defines various erase algorithms. Each algorithm removes + a part(s) of the input according to a searching criterium. +*/ + +namespace boost { + namespace algorithm { + +// erase_range -------------------------------------------------------// + + //! Erase range algorithm + /*! + Remove the given range from the input sequence. + The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param SearchRange A range in the input to be substituted + \return An output iterator pointing just after last inserted character + */ + template + inline OutputIteratorT erase_range_copy( + OutputIteratorT Output, + const CollectionT& Input, + const iterator_range< + BOOST_STRING_TYPENAME + const_iterator_of::type>& SearchRange ) + { + return find_format_copy( + Output, + Input, + range_finder(SearchRange), + empty_formatter(Input) ); + } + + //! Erase range algorithm + /*! + Remove the given range from the input sequence. + The result is a modified copy of the input. + + \param Input An input sequence + \param SearchRange A range in the input to be substituted + \return A modified copy of the input + */ + template + inline SequenceT erase_range_copy( + const SequenceT& Input, + const iterator_range< + BOOST_STRING_TYPENAME + const_iterator_of::type>& SearchRange ) + { + return find_format_copy( + Input, + range_finder(SearchRange), + empty_formatter(Input) ); + } + + //! Erase range algorithm + /*! + Remove the given range from the input sequence. + The input sequence is modified in-place. + + \param Input An input sequence + \param SearchRange A range in the input to be substituted + */ + template + inline void erase_range( + SequenceT& Input, + const iterator_range< + BOOST_STRING_TYPENAME + iterator_of::type>& SearchRange ) + { + find_format( + Input, + range_finder(SearchRange), + empty_formatter(Input) ); + } + +// erase_first --------------------------------------------------------// + + //! Erase first algorithm + /*! + Remove the first match of the search sequence from the input. + The result is copied to the given output iterator. + +H \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T> + inline OutputIteratorT erase_first_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search ) + { + return find_format_copy( + Output, + Input, + first_finder(Search), + empty_formatter(Input) ); + } + + //! Erase first algorithm + /*! + Remove the first match of the search sequence from the input. + The result is a modified copy of the input. + + \param Input An input sequence + \param Search A string to be searched for. + \return A modified copy of the input + */ + template + inline SequenceT erase_first_copy( + const SequenceT& Input, + const CollectionT& Search ) + { + return find_format_copy( + Input, + first_finder(Search), + empty_formatter(Input) ); + } + + //! Erase first algorithm + /*! + Remove the first match of the search sequence from the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param Search A string to be searched for. + */ + template + inline void erase_first( + SequenceT& Input, + const CollectionT& Search ) + { + find_format( + Input, + first_finder(Search), + empty_formatter(Input) ); + } + +// erase_first ( case insensitive ) ------------------------------------// + + //! Erase first algorithm ( case insensitive ) + /*! + Remove the first match of the search sequence from the input. + The result is copied to the given output iterator. Searching is case insensitive. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \param Loc a locale used for case insensitive comparison + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T> + inline OutputIteratorT ierase_first_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Output, + Input, + first_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase first algorithm ( case insensitive ) + /*! + Remove the first match of the search sequence from the input. + The result is a modified copy of the input. Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Loc a locale used for case insensitive comparison + \return A modified copy of the input + */ + template + inline SequenceT ierase_first_copy( + const SequenceT& Input, + const CollectionT& Search, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Input, + first_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase first algorithm ( case insensitive ) + /*! + Remove the first match of the search sequence from the input. + The input sequence is modified in-place. Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Loc a locale used for case insensitive comparison + */ + template + inline void ierase_first( + SequenceT& Input, + const CollectionT& Search, + const std::locale& Loc=std::locale() ) + { + find_format( + Input, + first_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + +// erase_last --------------------------------------------------------// + + //! Erase last algorithm + /*! + Remove the last match of the search sequence from the input. + The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T> + inline OutputIteratorT erase_last_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search ) + { + return find_format_copy( + Output, + Input, + last_finder(Search), + empty_formatter(Input) ); + } + + //! Erase last algorithm + /*! + Remove the last match of the search sequence from the input. + The result is a modified copy of the input. + + \param Input An input sequence + \param Search A string to be searched for. + \return A modified copy of the input + */ + template + inline SequenceT erase_last_copy( + const SequenceT& Input, + const CollectionT& Search ) + { + return find_format_copy( + Input, + last_finder(Search), + empty_formatter(Input) ); + } + + //! Erase last algorithm + /*! + Remove the last match of the search sequence from the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param Search A string to be searched for. + */ + template + inline void erase_last( + SequenceT& Input, + const CollectionT& Search ) + { + find_format( + Input, + last_finder(Search), + empty_formatter(Input) ); + } + +// erase_last ( case insensitive ) ------------------------------------// + + //! Erase last algorithm ( case insensitive ) + /*! + Remove the last match of the search sequence from the input. + The result is copied to the given output iterator. Searching is case insensitive. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \param Loc a locale used for case insensitive comparison + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T> + inline OutputIteratorT ierase_last_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Output, + Input, + last_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase last algorithm ( case insensitive ) + /*! + Remove the last match of the search sequence from the input. + The result is a modified copy of the input. Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Loc a locale used for case insensitive comparison + \return A modified copy of the input + */ + template + inline SequenceT ierase_last_copy( + const SequenceT& Input, + const CollectionT& Search, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Input, + last_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase last algorithm ( case insensitive ) + /*! + Remove the last match of the search sequence from the input. + The input sequence is modified in-place. Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Loc a locale used for case insensitive comparison + */ + template + inline void ierase_last( + SequenceT& Input, + const CollectionT& Search, + const std::locale& Loc=std::locale() ) + { + find_format( + Input, + last_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + +// erase_nth --------------------------------------------------------------------// + + //! Erase nth algorithm + /*! + Remove the Nth match of the search sequence in the input. + The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T> + inline OutputIteratorT erase_nth_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search, + unsigned int Nth ) + { + return find_format_copy( + Output, + Input, + nth_finder(Search, Nth), + empty_formatter(Input) ); + } + + //! Erase nth algorithm + /*! + Remove the Nth match of the search sequence in the input. + The result is a modified copy of the input. + + \param Input An input sequence + \param Search A string to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + \return A modified copy of the input + */ + template + inline SequenceT erase_nth_copy( + const SequenceT& Input, + const CollectionT& Search, + unsigned int Nth ) + { + return find_format_copy( + Input, + nth_finder(Search, Nth), + empty_formatter(Input) ); + } + + //! Erase nth algorithm + /*! + Remove the Nth match of the search sequence in the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param Search A string to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + */ + template + inline void erase_nth( + SequenceT& Input, + const CollectionT& Search, + unsigned int Nth ) + { + find_format( + Input, + nth_finder(Search, Nth), + empty_formatter(Input) ); + } + +// erase_nth ( case insensitive ) ---------------------------------------------// + + //! Erase nth algorithm ( case insensitive ) + /*! + Remove the Nth match of the search sequence in the input. + The result is copied to the given output iterator. Searching is case insensitive. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + \param Loc a locale used for case insensitive comparison + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T> + inline OutputIteratorT ierase_nth_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search, + unsigned int Nth, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Output, + Input, + nth_finder(Search, Nth, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase nth algorithm + /*! + Remove the Nth match of the search sequence in the input. + The result is a modified copy of the input. Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + \param Loc a locale used for case insensitive comparison + \return A modified copy of the input + */ + template + inline SequenceT ierase_nth_copy( + const SequenceT& Input, + const CollectionT& Search, + unsigned int Nth, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Input, + nth_finder(Search, Nth, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase nth algorithm + /*! + Remove the Nth match of the search sequence in the input. + The input sequence is modified in-place. Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + \param Loc a locale used for case insensitive comparison + */ + template + inline void ierase_nth( + SequenceT& Input, + const CollectionT& Search, + unsigned int Nth, + const std::locale& Loc=std::locale() ) + { + find_format( + Input, + nth_finder(Search, Nth, is_iequal(Loc)), + empty_formatter(Input) ); + } + + +// erase_all --------------------------------------------------------// + + //! Erase all algorithm + /*! + Remove all the occurrences of the search sequence from the input. + The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T> + inline OutputIteratorT erase_all_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search ) + { + return find_format_all_copy( + Output, + Input, + first_finder(Search), + empty_formatter(Input) ); + } + + //! Erase all algorithm + /*! + Remove all the occurrences of the search sequence from the input. + The result is a modified copy of the input. + + \param Input An input sequence + \param Search A string to be searched for. + \return A modified copy of the input + */ + template + inline SequenceT erase_all_copy( + const SequenceT& Input, + const CollectionT& Search ) + { + return find_format_all_copy( + Input, + first_finder(Search), + empty_formatter(Input) ); + } + + //! Erase all algorithm + /*! + Remove all the occurrences of the search sequence from the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param Search A string to be searched for. + */ + template + inline void erase_all( + SequenceT& Input, + const CollectionT& Search ) + { + find_format_all( + Input, + first_finder(Search), + empty_formatter(Input) ); + } + +// erase_all ( case insensitive ) ------------------------------------// + + //! Erase all algorithm ( case insensitive ) + /*! + Remove all the occurrences of the search sequence from the input. + The result is copied to the given output iterator. Searching is case insensitive. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \param Loc a locale used for case insensitive comparison + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T> + inline OutputIteratorT ierase_all_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search, + const std::locale& Loc=std::locale() ) + { + return find_format_all_copy( + Output, + Input, + first_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase all algorithm ( case insensitive ) + /*! + Remove all the occurrences of the search sequence from the input. + The result is a modified copy of the input. Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Loc a locale used for case insensitive comparison + \return A modified copy of the input + */ + template + inline SequenceT ierase_all_copy( + const SequenceT& Input, + const CollectionT& Search, + const std::locale& Loc=std::locale() ) + { + return find_format_all_copy( + Input, + first_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase all algorithm ( case insensitive ) + /*! + Remove all the occurrences of the search sequence from the input. + The input sequence is modified in-place. Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Loc a locale used for case insensitive comparison + */ + template + inline void ierase_all( + SequenceT& Input, + const CollectionT& Search, + const std::locale& Loc=std::locale() ) + { + find_format_all( + Input, + first_finder(Search, is_iequal(Loc)), + empty_formatter(Input) ); + } + +// erase_head --------------------------------------------------------------------// + + //! Erase head algorithm + /*! + Remove the head from the input. Head is a prefix of a seqence of given size. + If the sequence is shorter then required, whole sequence if + considered to be the head. The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param N A length of the head + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename CollectionT> + inline OutputIteratorT erase_head_copy( + OutputIteratorT Output, + const CollectionT& Input, + unsigned int N ) + { + return find_format_copy( + Output, + Input, + head_finder(N), + empty_formatter( Input ) ); + } + + //! Erase head algorithm + /*! + Remove the head from the input. Head is a prefix of a seqence of given size. + If the sequence is shorter then required, whole sequence if + considered to be the head. The result is a modified copy of the input. + + \param Input An input sequence + \param N A length of the head + \return A modified copy of the input + */ + template + inline SequenceT erase_head_copy( + const SequenceT& Input, + unsigned int N ) + { + return find_format_copy( + Input, + head_finder(N), + empty_formatter( Input ) ); + } + + //! Erase head algorithm + /*! + Remove the head from the input. Head is a prefix of a seqence of given size. + If the sequence is shorter then required, whole sequence if + considered to be the head. The input sequence is modified in-place. + + \param Input An input sequence + \param N A length of the head + */ + template + inline void erase_head( + SequenceT& Input, + unsigned int N ) + { + find_format( + Input, + head_finder(N), + empty_formatter( Input ) ); + } + +// erase_tail --------------------------------------------------------------------// + + //! Erase tail algorithm + /*! + Remove the tail from the input. Tail is a suffix of a seqence of given size. + If the sequence is shorter then required, whole sequence if + considered to be the tail. The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param N A length of the head + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename CollectionT> + inline OutputIteratorT erase_tail_copy( + OutputIteratorT Output, + const CollectionT& Input, + unsigned int N ) + { + return find_format_copy( + Output, + Input, + tail_finder(N), + empty_formatter( Input ) ); + } + + //! Erase tail algorithm + /*! + Remove the tail from the input. Tail is a suffix of a seqence of given size. + If the sequence is shorter then required, whole sequence is + considered to be the tail. The result is a modified copy of the input. + + \param Input An input sequence + \param N A length of the head + \return A modified copy of the input + */ + template + inline SequenceT erase_tail_copy( + const SequenceT& Input, + unsigned int N ) + { + return find_format_copy( + Input, + tail_finder(N), + empty_formatter( Input ) ); + } + + //! Erase tail algorithm + /*! + Remove the tail from the input. Tail is a suffix of a seqence of given size. + If the sequence is shorter then required, whole sequence is + considered to be the tail. The input sequence is modified in-place. + + \param Input An input sequence + \param N A length of the head + */ + template + inline void erase_tail( + SequenceT& Input, + unsigned int N ) + { + find_format( + Input, + tail_finder(N), + empty_formatter( Input ) ); + } + + } // namespace algorithm + + // pull names into the boost namespace + using algorithm::erase_range_copy; + using algorithm::erase_range; + using algorithm::erase_first_copy; + using algorithm::erase_first; + using algorithm::ierase_first_copy; + using algorithm::ierase_first; + using algorithm::erase_last_copy; + using algorithm::erase_last; + using algorithm::ierase_last_copy; + using algorithm::ierase_last; + using algorithm::erase_nth_copy; + using algorithm::erase_nth; + using algorithm::ierase_nth_copy; + using algorithm::ierase_nth; + using algorithm::erase_all_copy; + using algorithm::erase_all; + using algorithm::ierase_all_copy; + using algorithm::ierase_all; + using algorithm::erase_head_copy; + using algorithm::erase_head; + using algorithm::erase_tail_copy; + using algorithm::erase_tail; + +} // namespace boost + + +#endif // BOOST_ERASE_HPP diff --git a/include/boost/algorithm/string/find.hpp b/include/boost/algorithm/string/find.hpp new file mode 100644 index 0000000..5b707b2 --- /dev/null +++ b/include/boost/algorithm/string/find.hpp @@ -0,0 +1,312 @@ +// Boost string_algo library find.hpp header 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. + +#ifndef BOOST_STRING_FIND_HPP +#define BOOST_STRING_FIND_HPP + +#include +#include +#include +#include +#include +#include + +/*! \file + Defines a set of find algorithms. The algorithms are searching + for a subsequence of the input. The result is given as an \c iterator_range + delimiting the substring. +*/ + +namespace boost { + namespace algorithm { + +// Generic find -----------------------------------------------// + + //! Generic find algorithm + /*! + Search the input using the given finder. + + \param Input A collection which will be searched. + \param Finder Finder object used for searching. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c CollectionT::iterator or + \c CollectionT::const_iterator, depending on the constness of + the input parameter. + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME result_iterator_of::type> + find( + CollectionT& Input, + FinderT Finder) + { + return Finder(begin(Input),end(Input)); + } + +// find_first -----------------------------------------------// + + //! Find first algorithm + /*! + Search for a first match of search sequence in the + input collection. + + \param Input A container which will be searched. + \param Search A string to be searched for. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c CollectionT::iterator or + \c CollectionT::const_iterator, depending on the constness of + the input parameter. + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME result_iterator_of::type> + find_first( + Collection1T& Input, + const Collection2T& Search) + { + return first_finder(Search)( + begin(Input),end(Input)); + } + + //! Find first algorithm ( case insensitive ) + /*! + Search for a first match of search sequence in the + input collection. Searching is case insensitive. + + \param Input A container which will be searched. + \param Search A string to be searched for. + \param Loc a locale used for case insensitive comparison + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Collection1T::iterator or + \c Collection1T::const_iterator, depending on the constness of + the input parameter. + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME result_iterator_of::type> + ifind_first( + Collection1T& Input, + const Collection2T& Search, + const std::locale& Loc=std::locale()) + { + return first_finder(Search,is_iequal(Loc))( + begin(Input),end(Input)); + } + +// find_last -----------------------------------------------// + + //! Find last algorithm + /*! + Search for a last match of search sequence in the + input collection. + + \param Input A container which will be searched. + \param Search A string to be searched for. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Collection1T::iterator or + \c Collection1T::const_iterator, depending on the constness of + the input parameter. + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME result_iterator_of::type> + find_last( + Collection1T& Input, + const Collection2T& Search) + { + return last_finder(Search)( + begin(Input),end(Input)); + } + + //! Find last algorithm ( case insensitive ) + /*! + Search for a last match of search sequence in the + input collection. Searching is case insensitive. + + \param Input A container which will be searched. + \param Search A string to be searched for. + \param Loc a locale used for case insensitive comparison + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Collection1T::iterator or + \c Collection1T::const_iterator, depending on the constness of + the input parameter. + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME result_iterator_of::type> + ifind_last( + Collection1T& Input, + const Collection2T& Search, + const std::locale& Loc=std::locale()) + { + return last_finder(Search, is_iequal(Loc))( + begin(Input),end(Input)); + } + +// find_nth ----------------------------------------------------------------------// + + //! Find n-th algorithm + /*! + Search for an n-th match of search sequence in the + input collection. + + \param Input A container which will be searched. + \param Search A string to be searched for. + \param Nth An index of the match to be found. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Collection1T::iterator or + \c Collection1T::const_iterator, depending on the constness of + the input parameter. + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME result_iterator_of::type> + find_nth( + Collection1T& Input, + const Collection2T& Search, + unsigned int Nth) + { + return nth_finder(Search,Nth)( + begin(Input),end(Input)); + } + + //! Find n-th algorithm ( case insensitive ). + /*! + Search for an n-th match of search sequence in the + input collection. Searching is case insensitive. + + \param Input A container which will be searched. + \param Search A string to be searched for. + \param Nth An index of the match to be found. + \param Loc a locale used for case insensitive comparison + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Collection1T::iterator or + \c Collection1T::const_iterator, depending on the constness of + the input parameter. + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME result_iterator_of::type> + ifind_nth( + Collection1T& Input, + const Collection2T& Search, + unsigned int Nth, + const std::locale& Loc=std::locale()) + { + return nth_finder(Search,Nth,is_iequal(Loc))( + begin(Input),end(Input)); + } + +// find_head ----------------------------------------------------------------------// + + //! Find head algorithm + /*! + Get the head of the input. Head is a prefix of + a seqence of given size. If the sequence is shorter then required, + whole sequence if considered to be the head. + + \param Input A container which will be searched. + \param N A length of the head + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Collection1T::iterator or + \c Collection1T::const_iterator, depending on the constness of + the input parameter. + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME result_iterator_of::type> + find_head( + CollectionT& Input, + unsigned int N) + { + return head_finder(N)( + begin(Input),end(Input)); + } + +// find_tail ----------------------------------------------------------------------// + + //! Find tail algorithm + /*! + Get the tail of the input. Head is a suffix of + a seqence of given size. If the sequence is shorter then required, + whole sequence if considered to be the tail. + + \param Input A container which will be searched. + \param N A length of the tail + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c CollectionT::iterator or + \c CollectionT::const_iterator, depending on the constness of + the input parameter. + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME result_iterator_of::type> + find_tail( + CollectionT& Input, + unsigned int N) + { + return tail_finder(N)( + begin(Input),end(Input)); + } + +// find_token --------------------------------------------------------------------// + + //! Find token algorithm + /*! + Look for a given token in the collection. Token is specified by a predicate. + If bCompressed is given, adjacent tokens are considered to be one match. + + \param Input A container which will be searched. + \param Pred An unary predicate to identify a token + \param eCompress Enable/Disable compressing of adjacent tokens + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c CollectionT::iterator or + \c CollectionT::const_iterator, depending on the constness of + the input parameter. + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME result_iterator_of::type> + find_token( + CollectionT& Input, + PredicateT Pred, + token_compress_mode_type eCompress=token_compress_off) + { + return token_finder(Pred, eCompress)( + begin(Input),end(Input)); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::find; + using algorithm::find_first; + using algorithm::ifind_first; + using algorithm::find_last; + using algorithm::ifind_last; + using algorithm::find_nth; + using algorithm::ifind_nth; + using algorithm::find_head; + using algorithm::find_tail; + using algorithm::find_token; + +} // namespace boost + + +#endif // BOOST_STRING_FIND_HPP diff --git a/include/boost/algorithm/string/find_format.hpp b/include/boost/algorithm/string/find_format.hpp new file mode 100644 index 0000000..9ba3a93 --- /dev/null +++ b/include/boost/algorithm/string/find_format.hpp @@ -0,0 +1,270 @@ +// Boost string_algo library find_format.hpp header 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. + +#ifndef BOOST_STRING_FIND_FORMAT_HPP +#define BOOST_STRING_FIND_FORMAT_HPP + +#include +#include +#include +#include +#include +#include +#include + +/*! \file + Defines generic replace algorithms. Each algorithm replaces + a part(s) of the input. The part to be replaced is looked up using a Finder object. + Result of finding is then used by a Formatter object to generate the replacement. +*/ + +namespace boost { + namespace algorithm { + +// generic replace -----------------------------------------------------------------// + + //! Generic replace algorithm + /*! + Use the Finder to search for a substring. Use the Formatter to format + this substring and replace it in the input. + The resulting sequence is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Finder A Finder object used to search for a match to be replaced + \param Formatter A Formatter object used to format a match + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename CollectionT, + typename FinderT, + typename FormatterT> + inline OutputIteratorT find_format_copy( + OutputIteratorT Output, + const CollectionT& Input, + FinderT Finder, + FormatterT Formatter ) + { + // Concept check + function_requires< + FinderConcept::type> >(); + function_requires< + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME const_iterator_of::type> >(); + + return detail::find_format_copy_impl( + Output, + Input, + Finder, + Formatter, + Finder( begin(Input), end(Input) ) ); + } + + //! Generic replace algorithm + /*! + Use the Finder to search for a substring. Use the Formatter to format + this substring and replace it in the input. + The result is the modified copy of the input. + + \param Input An input sequence + \param Finder A Finder object used to search for a match to be replaced + \param Formatter A Formatter object used to format a match + \return A modified copy of the input + */ + template< + typename SequenceT, + typename FinderT, + typename FormatterT> + inline SequenceT find_format_copy( + const SequenceT& Input, + FinderT Finder, + FormatterT Formatter ) + { + // Concept check + function_requires< + FinderConcept::type> >(); + function_requires< + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME const_iterator_of::type> >(); + + return detail::find_format_copy_impl( + Input, + Finder, + Formatter, + Finder(begin(Input), end(Input))); + } + + //! Generic replace algorithm + /*! + Use the Finder to search for a substring. Use the Formatter to format + this substring and replace it in the input. The input is modified in-place. + + \param Input An input sequence + \param Finder A Finder object used to search for a match to be replaced + \param Formatter A Formatter object used to format a match + */ + template< + typename SequenceT, + typename FinderT, + typename FormatterT> + inline void find_format( + SequenceT& Input, + FinderT Finder, + FormatterT Formatter) + { + // Concept check + function_requires< + FinderConcept::type> >(); + function_requires< + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME const_iterator_of::type> >(); + + detail::find_format_impl( + Input, + Finder, + Formatter, + Finder(begin(Input), end(Input))); + } + + +// find_format_all generic ----------------------------------------------------------------// + + //! Generic replace all algorithm + /*! + Use the Finder to search for a substring. Use the Formatter to format + this substring and replace it in the input. Repeat this for all matching + substrings. + The resulting sequence is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Finder A Finder object used to search for a match to be replaced + \param Formatter A Formatter object used to format a match + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename CollectionT, + typename FinderT, + typename FormatterT> + inline OutputIteratorT find_format_all_copy( + OutputIteratorT Output, + const CollectionT& Input, + FinderT Finder, + FormatterT Formatter) + { + // Concept check + function_requires< + FinderConcept::type> >(); + function_requires< + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME const_iterator_of::type> >(); + + return detail::find_format_all_copy_impl( + Output, + Input, + Finder, + Formatter, + Finder(begin(Input), end(Input))); + } + + //! Generic replace all algorithm + /*! + Use the Finder to search for a substring. Use the Formatter to format + this substring and replace it in the input. Repeat this for all matching + substrings. + The result is the modified copy of the input. + + \param Input An input sequence + \param Finder A Finder object used to search for a match to be replaced + \param Formatter A Formatter object used to format a match + \return A modified copy of the input + */ + template< + typename SequenceT, + typename FinderT, + typename FormatterT > + inline SequenceT find_format_all_copy( + const SequenceT& Input, + FinderT Finder, + FormatterT Formatter ) + { + // Concept check + function_requires< + FinderConcept::type> >(); + function_requires< + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME const_iterator_of::type> >(); + + return detail::find_format_all_copy_impl( + Input, + Finder, + Formatter, + Finder( begin(Input), end(Input) ) ); + } + + //! Generic replace all algorithm + /*! + Use the Finder to search for a substring. Use the Formatter to format + this substring and replace it in the input. Repeat this for all matching + substrings.The input is modified in-place. + + \param Input An input sequence + \param Finder A Finder object used to search for a match to be replaced + \param Formatter A Formatter object used to format a match + */ + template< + typename SequenceT, + typename FinderT, + typename FormatterT > + inline void find_format_all( + SequenceT& Input, + FinderT Finder, + FormatterT Formatter ) + { + // Concept check + function_requires< + FinderConcept::type> >(); + function_requires< + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME const_iterator_of::type> >(); + + detail::find_format_all_impl( + Input, + Finder, + Formatter, + Finder(begin(Input), end(Input))); + + } + + } // namespace algorithm + + // pull the names to the boost namespace + using algorithm::find_format_copy; + using algorithm::find_format; + using algorithm::find_format_all_copy; + using algorithm::find_format_all; + +} // namespace boost + + +#endif // BOOST_STRING_FIND_FORMAT_HPP diff --git a/include/boost/algorithm/string/find_iterator.hpp b/include/boost/algorithm/string/find_iterator.hpp new file mode 100644 index 0000000..b06fb60 --- /dev/null +++ b/include/boost/algorithm/string/find_iterator.hpp @@ -0,0 +1,330 @@ +// Boost string_algo library find_iterator.hpp header 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. + +#ifndef BOOST_STRING_FIND_ITERATOR_HPP +#define BOOST_STRING_FIND_ITERATOR_HPP + + +#include +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + +// find_iterator -----------------------------------------------// + + //! find_iterator + /*! + Find iterator encapsulates a Finder and allows + an incremental searching in the sequence. + Each increment moves the iterator to the next match. + + Find iterator is readable forward traversal iterator. + + Dereferencing the iterator yields an iterator_range delimiting + the current match. + */ + template + class find_iterator : + public iterator_facade< + find_iterator, + const iterator_range, + forward_traversal_tag >, + private detail::find_iterator_base + { + private: + // facade support + friend class iterator_core_access; + + // base type + typedef iterator_facade< + find_iterator, + const iterator_range, + forward_traversal_tag> facade_type; + + private: + // typedefs + + typedef detail::find_iterator_base base_type; + typedef BOOST_STRING_TYPENAME + base_type::input_iterator_type input_iterator_type; + typedef BOOST_STRING_TYPENAME + base_type::match_type match_type; + + public: + //! Default constructor + /*! + Construct null iterator. All null iterators are equal. + + \post eof()==true + */ + find_iterator() {} + + //! Copy constructor + /*! + Construct a copy of the find_iterator + */ + find_iterator( const find_iterator& Other ) : + base_type(Other), + m_Match(Other.m_Match), + m_End(Other.m_End) {} + + //! Constructor + /*! + Construct new find_iterator for a given finder + and a range. + */ + template + find_iterator( + IteratorT Begin, + IteratorT End, + FinderT Finder ) : + detail::find_iterator_base(Finder,0), + m_Match(Begin,Begin), + m_End(End) + { + increment(); + } + + private: + // iterator operations + + // dereference + const match_type& dereference() const + { + return m_Match; + } + + // increment + void increment() + { + m_Match=do_find(m_Match.end(),m_End); + } + + // comparison + bool equal( const find_iterator& Other ) const + { + return + ( + m_Match==Other.m_Match && + m_End==Other.m_End + ) + || + ( + eof() && Other.eof() + ); + } + + public: + // operations + + //! Eof check + /*! + Check the eof condition. Eof condition means, that + there is nothing more to be searched i.e. find_iterator + is after the last match. + */ + bool eof() const + { + return + is_null() || + ( + m_Match.begin() == m_End && + m_Match.end() == m_End + ); + } + + private: + // Attributes + match_type m_Match; + input_iterator_type m_End; + }; + + //! find iterator construction helper + /*! + * Construct a find iterator to iterate through the specified collection + */ + template + inline find_iterator< + BOOST_STRING_TYPENAME result_iterator_of::type> + make_find_iterator( + CollectionT& Collection, + FinderT Finder) + { + return find_iterator::type>( + Collection.begin(), Collection.end(), Finder); + } + +// split iterator -----------------------------------------------// + + //! split_iterator + /*! + Split iterator encapsulates a Finder and allows + an incremental searching in the sequence. + Unlike the find iterator, split iterator iterates + through gasps between matches. + + Find iterator is readable forward traversal iterator. + + Dereferencing the iterator yields an iterator_range delimiting + the current match. + */ + template + class split_iterator : + public iterator_facade< + split_iterator, + const iterator_range, + forward_traversal_tag >, + private detail::find_iterator_base + { + private: + // facade support + friend class iterator_core_access; + + // base type + typedef iterator_facade< + find_iterator, + iterator_range, + forward_traversal_tag> facade_type; + + private: + // typedefs + + typedef detail::find_iterator_base base_type; + typedef BOOST_STRING_TYPENAME + base_type::input_iterator_type input_iterator_type; + typedef BOOST_STRING_TYPENAME + base_type::match_type match_type; + + public: + //! Default constructor + /*! + Construct null iterator. All null iterators are equal. + + \post eof()==true + */ + split_iterator() {} + //! Copy constructor + /*! + Construct a copy of the find_iterator + */ + split_iterator( const split_iterator& Other ) : + base_type(Other), + m_Match(Other.m_Match), + m_Next(Other.m_Next), + m_End(Other.m_End) {} + + //! Constructor + /*! + Construct new find_iterator for a given finder + and a range. + */ + template + split_iterator( + IteratorT Begin, + IteratorT End, + FinderT Finder ) : + detail::find_iterator_base(Finder,0), + m_Match(Begin,Begin), + m_Next(Begin), + m_End(End) + { + increment(); + } + + private: + // iterator operations + + // dereference + const match_type& dereference() const + { + return m_Match; + } + + // increment + void increment() + { + match_type FindMatch=do_find( m_Next, m_End ); + m_Match=match_type( m_Next, FindMatch.begin() ); + m_Next=FindMatch.end(); + } + + // comparison + bool equal( const split_iterator& Other ) const + { + return + ( + m_Match==Other.m_Match && + m_Next==Other.m_Next && + m_End==Other.m_End + ) + || + ( + eof() && Other.eof() + ); + } + + public: + // operations + + //! Eof check + /*! + Check the eof condition. Eof condition means, that + there is nothing more to be searched i.e. find_iterator + is after the last match. + */ + bool eof() const + { + return + is_null() || + ( + m_Match.begin() == m_End && + m_Match.end() == m_End + ); + } + + private: + // Attributes + match_type m_Match; + input_iterator_type m_Next; + input_iterator_type m_End; + }; + + //! split iterator construction helper + /*! + * Construct a split iterator to iterate through the specified collection + */ + template + inline split_iterator< + BOOST_STRING_TYPENAME result_iterator_of::type> + make_split_iterator( + CollectionT& Collection, + FinderT Finder) + { + return split_iterator::type>( + Collection.begin(), Collection.end(), Finder); + } + + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::find_iterator; + using algorithm::make_find_iterator; + using algorithm::split_iterator; + using algorithm::make_split_iterator; + +} // namespace boost + + +#endif // BOOST_STRING_FIND_ITERATOR_HPP diff --git a/include/boost/algorithm/string/finder.hpp b/include/boost/algorithm/string/finder.hpp new file mode 100644 index 0000000..a7d35fe --- /dev/null +++ b/include/boost/algorithm/string/finder.hpp @@ -0,0 +1,288 @@ +// Boost string_algo library finder.hpp header 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. + +#ifndef BOOST_STRING_FINDER_HPP +#define BOOST_STRING_FINDER_HPP + +#include +#include +#include +#include +#include +#include + +/*! \file + Defines Finder generators. Finder object is a functor which is able to + find a subsequence matching a specific criterium in an input + sequence. + Finders are used as a pluggable components for replace, find + and split facilities. This header contains generator functions + for finders provided in this library. +*/ + +namespace boost { + namespace algorithm { + +// Finder generators ------------------------------------------// + + //! "First" finder + /*! + Construct the \c first_finder. The finder searches for the first + occurrence of the search sequence in a given input. + The result is given as a \c iterator_range delimiting the match. + + \param Search A sequence to be searched for. + \return An instance of the \c first_finder object + */ + template + inline detail::first_finderF< + BOOST_STRING_TYPENAME const_iterator_of::type, + is_equal> + first_finder( const ContainerT& Search ) + { + return + detail::first_finderF< + BOOST_STRING_TYPENAME + const_iterator_of::type, + is_equal>( Search, is_equal() ) ; + } + + //! "First" finder + /*! + Construct the \c first_finder. The finder searches for the first + occurrence of the search sequence in a given input. + The result is given as a \c iterator_range delimiting the match. + + Elements are compared using the given predicate. + + \param Search A sequence to be searched for. + \param Comp An element comparison predicate + \return An instance of the \c first_finder object + */ + template + inline detail::first_finderF< + BOOST_STRING_TYPENAME const_iterator_of::type, + PredicateT> + first_finder( + const ContainerT& Search, PredicateT Comp ) + { + return + detail::first_finderF< + BOOST_STRING_TYPENAME + const_iterator_of::type, + PredicateT>( Search, Comp ); + } + + //! "Last" finder + /*! + Construct the \c last_finder. The finder searches for the last + occurrence of the search sequence in a given input. + The result is given as a \c iterator_range delimiting the match. + + \param Search A sequence to be searched for. + \return An instance of the \c last_finder object + */ + template + inline detail::last_finderF< + BOOST_STRING_TYPENAME const_iterator_of::type, + is_equal> + last_finder( const ContainerT& Search ) + { + return + detail::last_finderF< + BOOST_STRING_TYPENAME + const_iterator_of::type, + is_equal>( Search, is_equal() ); + } + //! "Last" finder + /*! + Construct the \c last_finder. The finder searches for the last + occurrence of the search sequence in a given input. + The result is given as a \c iterator_range delimiting the match. + + Elements are compared using the given predicate. + + \param Search A sequence to be searched for. + \param Comp An element comparison predicate + \return An instance of the \c last_finder object + */ + template + inline detail::last_finderF< + BOOST_STRING_TYPENAME const_iterator_of::type, + PredicateT> + last_finder( const ContainerT& Search, PredicateT Comp ) + { + return + detail::last_finderF< + BOOST_STRING_TYPENAME + const_iterator_of::type, + PredicateT>( Search, Comp ) ; + } + + //! "Nth" finder + /*! + Construct the \c nth_finder. The finder searches for the n-th + occurrence of the search sequence in a given input. + The result is given as a \c iterator_range delimiting the match. + + \param Search A sequence to be searched for. + \param Nth An index of the match to be find + \return An instance of the \c nth_finder object + */ + template + inline detail::nth_finderF< + BOOST_STRING_TYPENAME const_iterator_of::type, + is_equal> + nth_finder( + const ContainerT& Search, + unsigned int Nth) + { + return + detail::nth_finderF< + BOOST_STRING_TYPENAME + const_iterator_of::type, + is_equal>( Search, Nth, is_equal() ) ; + } + //! "Nth" finder + /*! + Construct the \c nth_finder. The finder searches for the n-th + occurrence of the search sequence in a given input. + The result is given as a \c iterator_range delimiting the match. + + Elements are compared using the given predicate. + + \param Search A sequence to be searched for. + \param Nth An index of the match to be find + \param Comp An element comparison predicate + \return An instance of the \c nth_finder object + */ + template + inline detail::nth_finderF< + BOOST_STRING_TYPENAME const_iterator_of::type, + PredicateT> + nth_finder( + const ContainerT& Search, + unsigned int Nth, + PredicateT Comp ) + { + return + detail::nth_finderF< + BOOST_STRING_TYPENAME + const_iterator_of::type, + PredicateT>( Search, Nth, Comp ); + } + + //! "Head" finder + /*! + Construct the \c head_finder. The finder returns a head of a given + input. Head is a prefix of a sequence up to n elements in + size. If an input has less then n elements, whole input is + considered a head. + The result is given as a \c iterator_range delimiting the match. + + \param N The size of the head + \return An instance of the \c head_finder object + */ + inline detail::head_finderF + head_finder( unsigned int N ) + { + return detail::head_finderF(N); + } + + //! "Tail" finder + /*! + Construct the \c tail_finder. The finder returns a tail of a given + input. Tail is a suffix of the sequence up to n elements in + size. If an input has less then n elements, whole input is + considered a head. + The result is given as a \c iterator_range delimiting the match. + + \param N The size of the head + \return An instance of the \c tail_finder object + */ + inline detail::tail_finderF + tail_finder( unsigned int N ) + { + return detail::tail_finderF(N); + } + + //! "Token" finder + /*! + Construct the \c token_finder. The finder searches for a token + specified by a predicate. It is similar to std::find_if + algorithm, with an exception that it return a range of + instead of a single iterator. + + If bCompress is set to true, adjacent matching tokens are + concatenated into one match. Thus the finder can be used to + search for continuous segments of elements satisfying the + given predicate. + + The result is given as a \c iterator_range delimiting the match. + + \param Pred An element selection predicate + \param eCompress Compress flag + \return An instance of the \c token_finder object + */ + template< typename PredicateT > + inline detail::token_finderF + token_finder( + PredicateT Pred, + token_compress_mode_type eCompress=token_compress_off ) + { + return detail::token_finderF( Pred, eCompress ); + } + + //! "Range" finder + /*! + Construct the \c range_finder. The finder does not perform + any operation. It simply returns the given range for + any input. + + \param Begin Beginning of the range + \param End End of the range + \return An instance of the \c range_finger object + */ + template< typename ForwardIteratorT > + inline detail::range_finderF + range_finder( + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + return detail::range_finderF( Begin, End ); + } + + //! "Range" finder + /*! + \param Range The range. + + \overload + */ + template< typename ForwardIteratorT > + inline detail::range_finderF + range_finder( iterator_range Range ) + { + return detail::range_finderF( Range ); + } + + } // namespace algorithm + + // pull the names to the boost namespace + using algorithm::first_finder; + using algorithm::last_finder; + using algorithm::nth_finder; + using algorithm::head_finder; + using algorithm::tail_finder; + using algorithm::token_finder; + using algorithm::range_finder; + +} // namespace boost + + +#endif // BOOST_STRING_FINDER_HPP diff --git a/include/boost/algorithm/string/formatter.hpp b/include/boost/algorithm/string/formatter.hpp new file mode 100644 index 0000000..d6ea9a8 --- /dev/null +++ b/include/boost/algorithm/string/formatter.hpp @@ -0,0 +1,92 @@ +// Boost string_algo library formatter.hpp header 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. + +#ifndef BOOST_STRING_FORMATTER_HPP +#define BOOST_STRING_FORMATTER_HPP + +#include +#include +#include +#include + +/*! \file + Defines formatter generators. Formatter is a functor which formats + a string according to give parameters. A Formatter works + in conjunction with a Finder. A Finder can provide additional information + for a specific Formatter. An example of such a cooperation is reger_finder + and regex_formatter. + + Formatters are used by as a pluggable components for replace facilities. + This header contains generator functions for the Formatters provided in this library. +*/ + +namespace boost { + namespace algorithm { + +// generic formaters ---------------------------------------------------------------// + + //! Constant formatter + /*! + Construct the \c const_formatter. Const formatter always returns + the same value, regardless of the parameter. + + \param Format A predefined value used as a result for formating + \return An instance of the \c const_formatter object. + */ + template + inline detail::const_formatF + const_formatter(const CollectionT& Format) + { + return detail::const_formatF(Format); + } + + //! Identity formatter + /*! + Construct the \c identity_formatter. Identity formatter always returns + the parameter. + + \return An instance of the \c identity_formatter object. + */ + template + inline detail::identity_formatF + identity_formatter() + { + return detail::identity_formatF(); + } + + //! Empty formatter + /*! + Construct the \c empty_formatter. Empty formater always returns an empty + sequence. + + \param Input container used to select a correct value_type for the + resulting empty_container<>. + \return An instance of the \c empty_formatter object. + */ + template + inline detail::empty_formatF< + BOOST_STRING_TYPENAME value_type_of::type> + empty_formatter(const CollectionT& Input) + { + return detail::empty_formatF< + BOOST_STRING_TYPENAME value_type_of::type>(); + } + + + } // namespace algorithm + + // pull the names to the boost namespace + using algorithm::const_formatter; + using algorithm::identity_formatter; + using algorithm::empty_formatter; + +} // namespace boost + + +#endif // BOOST_FORMATTER_HPP diff --git a/include/boost/algorithm/string/iter_find.hpp b/include/boost/algorithm/string/iter_find.hpp new file mode 100644 index 0000000..2bcbd0f --- /dev/null +++ b/include/boost/algorithm/string/iter_find.hpp @@ -0,0 +1,165 @@ +// Boost string_algo library iter_find.hpp header 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. + +#ifndef BOOST_STRING_ITER_FIND_HPP +#define BOOST_STRING_ITER_FIND_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*! \file + Defines generic split algorithms. Split algorithms can be + used to divide a sequence into several part according + to a given criterium. Result is given as a 'container + of containers' where elements are copies or references + to extracted parts. + + There are two algorithms provided. One iterates over matching + substrings, the other one over the gasps between these matches. +*/ + +namespace boost { + namespace algorithm { + +// iterate find ---------------------------------------------------// + + //! Iter find algorithm + /*! + This algorithm executes a given finder in iteration on the input, + until the end of input is reached, or no match is found. + Iteration is done using built-in find_iterator, so the real + searching is performed only when needed. + In each iteration new match is found and added to the result. + + \param Result A 'container container' to contain the result of search. + Both outer and inner container must have constructor taking a pair + of iterators as an argument. + Typical type of the result is + \c std::vector> + (each element of such a vector will container a range delimiting + a match). + \param Input A container which will be searched. + \param Finder A Finder object used for searching + \return A reference the result + + \note Prior content of the result will be overridden. + */ + template< + typename SequenceSequenceT, + typename CollectionT, + typename FinderT > + inline SequenceSequenceT& + iter_find( + SequenceSequenceT& Result, + CollectionT& Input, + FinderT Finder ) + { + function_requires< + FinderConcept::type> >(); + + typedef BOOST_STRING_TYPENAME + result_iterator_of::type input_iterator_type; + typedef find_iterator find_iterator_type; + typedef detail::copy_iterator_rangeF< + BOOST_STRING_TYPENAME + value_type_of::type, + input_iterator_type> copy_range_type; + + input_iterator_type InputEnd=end(Input); + + SequenceSequenceT Tmp( + make_transform_iterator( + find_iterator_type( begin(Input), InputEnd, Finder ), + copy_range_type() ), + make_transform_iterator( + find_iterator_type(), + copy_range_type() ) ); + + Result.swap(Tmp); + return Result; + }; + +// iterate split ---------------------------------------------------// + + //! Split find algorithm + /*! + This algorithm executes a given finder in iteration on the input, + until the end of input is reached, or no match is found. + Iteration is done using built-in find_iterator, so the real + searching is performed only when needed. + Each match is used as a separator of segments. These segments are then + returned in the result. + + \param Result A 'container container' to container the result of search. + Both outer and inner container must have constructor taking a pair + of iterators as an argument. + Typical type of the result is + \c std::vector> + (each element of such a vector will container a range delimiting + a match). + \param Input A container which will be searched. + \param Finder A finder object used for searching + \return A reference the result + + \note Prior content of the result will be overridden. + */ + template< + typename SequenceSequenceT, + typename CollectionT, + typename FinderT > + inline SequenceSequenceT& + iter_split( + SequenceSequenceT& Result, + CollectionT& Input, + FinderT Finder ) + { + function_requires< + FinderConcept::type> >(); + + typedef BOOST_STRING_TYPENAME + result_iterator_of::type input_iterator_type; + typedef split_iterator find_iterator_type; + typedef detail::copy_iterator_rangeF< + BOOST_STRING_TYPENAME + value_type_of::type, + input_iterator_type> copy_range_type; + + input_iterator_type InputEnd=end(Input); + + SequenceSequenceT Tmp( + make_transform_iterator( + find_iterator_type( begin(Input), InputEnd, Finder ), + copy_range_type() ), + make_transform_iterator( + find_iterator_type(), + copy_range_type() ) ); + + Result.swap(Tmp); + return Result; + }; + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::iter_find; + using algorithm::iter_split; + +} // namespace boost + + +#endif // BOOST_STRING_ITER_FIND_HPP diff --git a/include/boost/algorithm/string/iterator_range.hpp b/include/boost/algorithm/string/iterator_range.hpp new file mode 100644 index 0000000..3e27661 --- /dev/null +++ b/include/boost/algorithm/string/iterator_range.hpp @@ -0,0 +1,295 @@ +// Boost string_algo library iterator_range.hpp header 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. + +#ifndef BOOST_STRING_ITERATOR_RANGE_HPP +#define BOOST_STRING_ITERATOR_RANGE_HPP + +#include +#include +#include +#include +#include +#include + +/*! \file + Defines the \c iterator_class and related functions. + \c iterator_range is a simple wrapper of iterator pair idiom. It provides + a rich subset of Container interface. +*/ + +namespace boost { + namespace algorithm { + +// iterator range template class -----------------------------------------// + + //! iterator_range class + /*! + An \c iterator_range delimits a range in a sequence by beginning and ending iterators. + An iterator_range can be passed to an algorithm which requires a sequence as an input. + For example, the \c toupper() function may be used most frequently on strings, + but can also be used on iterator_ranges: + + \code + boost::tolower( find( s, "UPPERCASE STRING" ) ); + \endcode + + Many algorithms working with sequences take a pair of iterators, + delimiting a working range, as an arguments. The \c iterator_range class is an + encapsulation of a range identified by a pair of iterators. + It provides a collection interface, + so it is possible to pass an instance to an algorithm requiring a collection as an input. + */ + template + class iterator_range + { + public: + //! this type + typedef iterator_range type; + //! Encapsulated value type + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::value_type value_type; + //! Reference type + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::reference reference; + //! Difference type + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::difference_type difference_type; + //! Size type + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::difference_type size_type; + + //! const_iterator type + /*! + There is no distinction between const_iterator and iterator. + These typedefs are provides to fulfill container interface + */ + typedef IteratorT const_iterator; + //! iterator type + typedef IteratorT iterator; + + //! Default constructor + iterator_range() {} + + //! Constructor from a pair of iterators + iterator_range( iterator Begin, iterator End ) : + m_Begin(Begin), m_End(End) {} + + //! Constructor from a std::pair + iterator_range( const std::pair& Range ) : + m_Begin(Range.first), m_End(Range.second) {} + + //! Copy constructor + iterator_range( const iterator_range& Other ) : + m_Begin(Other.begin()), m_End(Other.end()) {} + + //! Templated copy constructor + /*! + This constructor is provided to allow conversion between + const and mutable iterator instances of this class template + */ + template< typename OtherItT > + iterator_range( const iterator_range& Other ) : + m_Begin(Other.begin()), m_End(Other.end()) {} + + //! Assignment operator + iterator_range& operator=( const iterator_range& Other ) + { + m_Begin=Other.begin(); m_End=Other.end(); + return *this; + } + + //! Assignment operator ( templated version ) + template< typename OtherItT > + iterator_range& operator=( const iterator_range& Other ) + { + m_Begin=Other.begin(); m_End=Other.end(); + return *this; + } + + //! Comparison operator ( equal ) + /*! + Compare operands for equality + */ + template< typename OtherItT > + bool operator==( const iterator_range& Other ) const + { + return m_Begin==Other.begin() && m_End==Other.end(); + } + + //! Comparison operator ( not-equal ) + /*! + Compare operands for non-equality + */ + template< typename OtherItT > + bool operator!=( const iterator_range& Other ) const + { + return m_Begin!=Other.begin() || m_End!=Other.end(); + } + + //! begin access + /*! + Retrieve the begin iterator + */ + IteratorT begin() const + { + return m_Begin; + } + + //! end access + /*! + Retrieve the end iterator + */ + IteratorT end() const + { + return m_End; + } + + //! Empty container test + /*! + Test whenever the range is empty + */ + bool empty() const + { + return m_Begin==m_End; + } + + //! Size of the range + /*! + Retrieve the size of the range + */ + difference_type size() const + { + return std::distance( m_Begin, m_End ); + } + + //! Swap + /*! + Swap two ranges + */ + void swap( iterator_range& Other ) + { + std::swap( m_Begin, Other.begin() ); + std::swap( m_End, Other.end() ); + } + + //! Safe bool conversion + /*! + Check whenever the range is empty. + Allows to use construction like this: + \code + iterator_range r; + if (!r) + { + ... + } + \endcode + */ + typedef iterator (iterator_range::*unspecified_bool_type) () const; + operator unspecified_bool_type() const + { + return empty()? 0: &iterator_range::end; + } + + private: + // begin and end iterators + IteratorT m_Begin; + IteratorT m_End; + }; + +// iterator range free-standing operators ---------------------------// + + //! iterator_range output operator + /*! + Output the range to an ostream. Elements are outputed + in a sequence without separators. + */ + template< typename IteratorT, typename Elem, typename Traits > + std::basic_ostream& operator<<( + std::basic_ostream& Os, + const iterator_range& Range ) + { + std::copy(Range.begin(), Range.end(), std::ostream_iterator(Os)); + + return Os; + } + + +// iterator range utilities -----------------------------------------// + + //! iterator_range construct helper + /*! + Construct an \c iterator_range from a pair of iterators + + \param Begin A begin iterator + \param End An end iterator + \return iterator_range object + */ + template< typename IteratorT > + inline iterator_range< IteratorT > make_iterator_range( IteratorT Begin, IteratorT End ) + { + return iterator_range( Begin, End ); + } + + //! iterator_range construct helper + /*! + Construct an \c iterator_range from a \c std::pair<> containing the begin + and end iterators. + + \param Pair A \c std::pair<> with begin and end iterators + \return \c iterator_range object + */ + template< typename IteratorT > + inline iterator_range< IteratorT > make_iterator_range( const std::pair& Pair ) + { + return iterator_range( Pair.first, Pair.second ); + } + + //! copy a range into a sequence + /*! + Construct a new sequence of the specified type from the elements + in the given range + + \param Range An input range + \return New sequence + */ + template< typename SeqT, typename IteratorT > + inline SeqT copy_iterator_range( const iterator_range& Range ) + { + return SeqT( Range.begin(), Range.end() ); + } + + //! transform a range into a sequence + /*! + Create a new sequence from the elements in the range, transformed + by a function + + \param Range An input range + \param Func Transformation function + \return New sequence + */ + template< typename SeqT, typename IteratorT, typename FuncT > + inline SeqT transform_iterator_range( const iterator_range& Range, FuncT Func ) + { + SeqT Seq; + std::transform( Range.begin(), Range.end(), std::back_inserter(Seq), Func ); + return Seq; + } + + } // namespace algorithm + + // pull names to the namespace boost + using algorithm::iterator_range; + using algorithm::make_iterator_range; + using algorithm::copy_iterator_range; + using algorithm::transform_iterator_range; + +} // namespace boost + + +#endif // BOOST_STRING_ITERATOR_RANGE_HPP diff --git a/include/boost/algorithm/string/predicate.hpp b/include/boost/algorithm/string/predicate.hpp new file mode 100644 index 0000000..47c3e55 --- /dev/null +++ b/include/boost/algorithm/string/predicate.hpp @@ -0,0 +1,365 @@ +// Boost string_algo library predicate.hpp header 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. + +#ifndef BOOST_STRING_PREDICATE_HPP +#define BOOST_STRING_PREDICATE_HPP + +#include +#include +#include +#include +#include + +/*! \file boost/algorithm/string/predicate.hpp + Defines string-related predicates. + The predicates are resolving if a substring is contained in the input string + under various conditions. If a string starts with the substring, ends with the + substring, simply contains the substring or if both strings are equal. + In addition the algorithm \c all() checks all elements of a container to satisfy a + condition. +*/ + +namespace boost { + namespace algorithm { + +// starts_with predicate -----------------------------------------------// + + //! 'Starts with' predicate + /*! + This predicate holds when the test collection is a prefix of the Input. + In other word, if the input starts with the test. + + \param Input An input sequence + \param Test A test sequence + \param Comp An element comparison predicate + \return A result of the test + */ + template + inline bool starts_with( + const Collection1T& Input, + const Collection2T& Test, + PredicateT Comp) + { + typedef BOOST_STRING_TYPENAME + const_iterator_of::type Iterator1T; + typedef BOOST_STRING_TYPENAME + const_iterator_of::type Iterator2T; + + Iterator1T InputEnd=end(Input); + Iterator2T TestEnd=end(Test); + + Iterator1T it=begin(Input); + Iterator2T pit=begin(Test); + for(; + it!=InputEnd && pit!=TestEnd; + ++it,++pit) + { + if( !(Comp(*it,*pit)) ) + return false; + } + + return pit==TestEnd; + } + + //! 'Starts with' predicate + /*! + This predicate holds when the test container is a prefix of the Input. + In other words, if the input starts with the test. + + \param Input An input sequence + \param Test A test sequence + \return A result of the test + */ + template + inline bool starts_with( + const Collection1T& Input, + const Collection2T& Test) + { + return starts_with(Input, Test, is_equal()); + } + + //! 'Starts with' predicate ( case insensitive ) + /*! + This predicate holds when the test container is a prefix of the Input. + In other word, if the input starts with the test. + Elements are compared case insensitively. + + \param Input An input sequence + \param Test A test sequence + \param Loc a locale used for case insensitive comparison + \return A result of the test + */ + template + inline bool istarts_with( + const Collection1T& Input, + const Collection2T& Test, + const std::locale& Loc=std::locale()) + { + return starts_with(Input, Test, is_iequal(Loc)); + } + + +// ends_with predicate -----------------------------------------------// + + //! 'Ends with' predicate + /*! + This predicate holds when the test container is a suffix of the Input. + In other word, if the input ends with the test. + + \param Input An input sequence + \param Test A test sequence + \param Comp An element comparison predicate + \return A result of the test + */ + template + inline bool ends_with( + const Collection1T& Input, + const Collection2T& Test, + PredicateT Comp) + { + typedef BOOST_STRING_TYPENAME + const_iterator_of::type Iterator1T; + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return detail:: + ends_with_iter_select( + begin(Input), + end(Input), + begin(Test), + end(Test), + Comp, + category()); + } + + + //! 'Ends with' predicate + /*! + This predicate holds when the test container is a suffix of the Input. + In other word, if the input ends with the test. + + \param Input An input sequence + \param Test A test sequence + \return A result of the test + */ + template + inline bool ends_with( + const Collection1T& Input, + const Collection2T& Test) + { + return ends_with(Input, Test, is_equal()); + } + + //! 'Ends with' predicate ( case insensitive ) + /*! + This predicate holds when the test container is a suffix of the Input. + In other word, if the input ends with the test. + Elements are compared case insensitively. + + \param Input An input sequence + \param Test A test sequence + \param Loc a locale used for case insensitive comparison + \return A result of the test + */ + template + inline bool iends_with( + const Collection1T& Input, + const Collection2T& Test, + const std::locale& Loc=std::locale()) + { + return ends_with(Input, Test, is_iequal(Loc)); + } + +// contains predicate -----------------------------------------------// + + //! 'Contains' predicate + /*! + This predicate holds when the test container is contained in the Input. + + \param Input An input sequence + \param Test A test sequence + \param Comp An element comparison predicate + \return A result of the test + */ + template + inline bool contains( + const Collection1T& Input, + const Collection2T& Test, + PredicateT Comp) + { + if (empty(Test)) + { + // Empty range is contained always + return true; + } + + return (first_finder(Test,Comp)(begin(Input), end(Input))); + } + + //! 'Contains' predicate + /*! + This predicate holds when the test container is contained in the Input. + + \param Input An input sequence + \param Test A test sequence + \return A result of the test + */ + template + inline bool contains( + const Collection1T& Input, + const Collection2T& Test) + { + return contains(Input, Test, is_equal()); + } + + //! 'Contains' predicate ( case insensitive ) + /*! + This predicate holds when the test container is contained in the Input. + Elements are compared case insensitively. + + \param Input An input sequence + \param Test A test sequence + \param Loc a locale used for case insensitive comparison + \return A result of the test + */ + template + inline bool icontains( + const Collection1T& Input, + const Collection2T& Test, + const std::locale& Loc=std::locale()) + { + return contains(Input, Test, is_iequal(Loc)); + } + +// equals predicate -----------------------------------------------// + + //! 'Equals' predicate + /*! + This predicate holds when the test container is equal to the + input container i.e. all elements in both containers are same. + + \param Input An input sequence + \param Test A test sequence + \param Comp An element comparison predicate + \return A result of the test + */ + template + inline bool equals( + const Collection1T& Input, + const Collection2T& Test, + PredicateT Comp) + { + typedef BOOST_STRING_TYPENAME + const_iterator_of::type Iterator1T; + typedef BOOST_STRING_TYPENAME + const_iterator_of::type Iterator2T; + + Iterator1T InputEnd=end(Input); + Iterator2T TestEnd=end(Test); + + Iterator1T it=begin(Input); + Iterator2T pit=begin(Test); + for(; + it!=InputEnd && pit!=TestEnd; + ++it,++pit) + { + if( !(Comp(*it,*pit)) ) + return false; + } + + return (pit==TestEnd) && (it==InputEnd); + } + + //! 'Equals' predicate + /*! + This predicate holds when the test container is equal to the + input container i.e. all elements in both containers are same. + + \param Input An input sequence + \param Test A test sequence + \return A result of the test + + \note This is two-way version of \c std::equal algorithm + */ + template + inline bool equals( + const Collection1T& Input, + const Collection2T& Test) + { + return equals(Input, Test, is_equal()); + } + + //! 'Equals' predicate ( casa insensitive ) + /*! + This predicate holds when the test container is equal to the + input container i.e. all elements in both containers are same. + Elements are compared case insensitively. + + \param Input An input sequence + \param Test A test sequence + \param Loc a locale used for case insensitive comparison + \return A result of the test + + \note This is two-way version of \c std::equal algorithm + */ + template + inline bool iequals( + const Collection1T& Input, + const Collection2T& Test, + const std::locale& Loc=std::locale()) + { + return equals(Input, Test, is_iequal(Loc)); + } + +// all predicate -----------------------------------------------// + + //! 'All' predicate + /*! + This predicate holds it all its elements satisfy a given + condition, represented by the predicate. + + \param Input An input sequence + \param Pred A predicate + \return A result of the test + */ + template + inline bool all( + const CollectionT& Input, + PredicateT Pred) + { + typedef BOOST_STRING_TYPENAME + const_iterator_of::type Iterator1T; + + Iterator1T InputEnd=end(Input); + for( Iterator1T It=begin(Input); It!=InputEnd; ++It) + { + if (!Pred(*It)) + return false; + } + + return true; + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::starts_with; + using algorithm::istarts_with; + using algorithm::ends_with; + using algorithm::iends_with; + using algorithm::contains; + using algorithm::icontains; + using algorithm::equals; + using algorithm::iequals; + using algorithm::all; + +} // namespace boost + + +#endif // BOOST_STRING_PREDICATE_HPP diff --git a/include/boost/algorithm/string/regex.hpp b/include/boost/algorithm/string/regex.hpp new file mode 100644 index 0000000..0e4842c --- /dev/null +++ b/include/boost/algorithm/string/regex.hpp @@ -0,0 +1,494 @@ +// Boost string_algo library regex.hpp header 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. + +#ifndef BOOST_STRING_REGEX_HPP +#define BOOST_STRING_REGEX_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +/*! \file + Defines regex variant of the algorithms. +*/ + +namespace boost { + namespace algorithm { + +// find_regex -----------------------------------------------// + + //! Find regex algorithm + /*! + Search for a subsequence matching the given regex in the input. + + \param Input A container which will be searched. + \param Rx A regular expression + \param Flags Regex options + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c InputContainerT::iterator or + \c InputContainerT::const_iterator, depending on the constness of + the input parameter. + */ + template< + typename CollectionT, + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT> + inline iterator_range< + BOOST_STRING_TYPENAME result_iterator_of::type > + find_regex( + CollectionT& Input, + const reg_expression& Rx, + match_flag_type Flags=match_default ) + { + return regex_finder(Rx,Flags)( + begin(Input), end(Input) ); + } + +// replace_regex --------------------------------------------------------------------// + + //! Replace regex algorithm + /*! + Search for a subsequence matching given regex and format it with + the specified format. The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Rx A regular expression + \param Format Regex format definition + \param Flags Regex options + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename CollectionT, + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT, + typename FormatStringTraitsT, typename FormatStringAllocatorT > + inline OutputIteratorT replace_regex_copy( + OutputIteratorT Output, + const CollectionT& Input, + const reg_expression& Rx, + const std::basic_string& Format, + match_flag_type Flags=match_default | format_default ) + { + return find_format_copy( + Output, + Input, + regex_finder( Rx, Flags ), + regex_formatter( Format, Flags ) ); + } + + //! Replace regex algorithm + /*! + Search for a subsequence matching given regex and format it with + the specified format. The result is a modified copy of the input. + + \param Input An input sequence + \param Rx A regular expression + \param Format Regex format definition + \param Flags Regex options + \return A modified copy of the input + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT, + typename FormatStringTraitsT, typename FormatStringAllocatorT > + inline SequenceT replace_regex_copy( + const SequenceT& Input, + const reg_expression& Rx, + const std::basic_string& Format, + match_flag_type Flags=match_default | format_default ) + { + return find_format_copy( + Input, + regex_finder( Rx, Flags ), + regex_formatter( Format, Flags ) ); + } + + //! Replace regex algorithm + /*! + Search for a subsequence matching given regex and format it with + the specified format. The input sequence is modified in-place. + + \param Input An input sequence + \param Rx A regular expression + \param Format Regex format definition + \param Flags Regex options + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT, + typename FormatStringTraitsT, typename FormatStringAllocatorT > + inline void replace_regex( + SequenceT& Input, + const reg_expression& Rx, + const std::basic_string& Format, + match_flag_type Flags=match_default | format_default ) + { + find_format( + Input, + regex_finder( Rx, Flags ), + regex_formatter( Format, Flags ) ); + } + +// replace_all_regex --------------------------------------------------------------------// + + //! Replace all regex algorithm + /*! + Format all subsequences, matching given regex, with the specified format. + The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Rx A regular expression + \param Format Regex format definition + \param Flags Regex options + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename CollectionT, + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT, + typename FormatStringTraitsT, typename FormatStringAllocatorT > + inline OutputIteratorT replace_all_regex_copy( + OutputIteratorT Output, + const CollectionT& Input, + const reg_expression& Rx, + const std::basic_string& Format, + match_flag_type Flags=match_default | format_default ) + { + return find_format_all_copy( + Output, + Input, + regex_finder( Rx, Flags ), + regex_formatter( Format, Flags ) ); + } + + //! Replace all regex algorithm + /*! + Format all subsequences, mathing given regex, with the specified format. + The result is a modified copy of the input. + + \param Input An input sequence + \param Rx A regular expression + \param Format Regex format definition + \param Flags Regex options + \return A modified copy of the input + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT, + typename FormatStringTraitsT, typename FormatStringAllocatorT > + inline SequenceT replace_all_regex_copy( + const SequenceT& Input, + const reg_expression& Rx, + const std::basic_string& Format, + match_flag_type Flags=match_default | format_default ) + { + return find_format_all_copy( + Input, + regex_finder( Rx, Flags ), + regex_formatter( Format, Flags ) ); + } + + //! Replace all regex algorithm + /*! + Format all subsequences, matching given regex, with the specified format. + The input sequence is modified in-place. + + \param Input An input sequence + \param Rx A regular expression + \param Format Regex format definition + \param Flags Regex options + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT, + typename FormatStringTraitsT, typename FormatStringAllocatorT > + inline void replace_all_regex( + SequenceT& Input, + const reg_expression& Rx, + const std::basic_string& Format, + match_flag_type Flags=match_default | format_default ) + { + find_format_all( + Input, + regex_finder( Rx, Flags ), + regex_formatter( Format, Flags ) ); + } + +// erase_regex --------------------------------------------------------------------// + + //! Erase regex algorithm + /*! + Remove a subsequence matching given regex from the input. + The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Rx A regular expression + \param Flags Regex options + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename CollectionT, + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT > + inline OutputIteratorT erase_regex_copy( + OutputIteratorT Output, + const CollectionT& Input, + const reg_expression& Rx, + match_flag_type Flags=match_default ) + { + return find_format_copy( + Output, + Input, + regex_finder( Rx, Flags ), + empty_formatter( Input ) ); + } + + //! Erase regex algorithm + /*! + Remove a subsequence matching given regex from the input. + The result is a modified copy of the input. + + \param Input An input sequence + \param Rx A regular expression + \param Flags Regex options + \return A modified copy of the input + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT > + inline SequenceT erase_regex_copy( + const SequenceT& Input, + const reg_expression& Rx, + match_flag_type Flags=match_default ) + { + return find_format_copy( + Input, + regex_finder( Rx, Flags ), + empty_formatter( Input ) ); + } + + //! Erase regex algorithm + /*! + Remove a subsequence matching given regex from the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param Rx A regular expression + \param Flags Regex options + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT > + inline void erase_regex( + SequenceT& Input, + const reg_expression& Rx, + match_flag_type Flags=match_default ) + { + find_format( + Input, + regex_finder( Rx, Flags ), + empty_formatter( Input ) ); + } + +// erase_all_regex --------------------------------------------------------------------// + + //! Erase all regex algorithm + /*! + Erase all subsequences, matching given regex, from the input. + The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Rx A regular expression + \param Flags Regex options + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename CollectionT, + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT > + inline OutputIteratorT erase_all_regex_copy( + OutputIteratorT Output, + const CollectionT& Input, + const reg_expression& Rx, + match_flag_type Flags=match_default ) + { + return find_format_all_copy( + Output, + Input, + regex_finder( Rx, Flags ), + empty_formatter( Input ) ); + } + + //! Erase all regex algorithm + /*! + Erase all subsequences, matching given regex, from the input. + The result is a modified copy of the input. + + \param Input An input sequence + \param Rx A regular expression + \param Flags Regex options + \return A modified copy of the input + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT > + inline SequenceT erase_all_regex_copy( + const SequenceT& Input, + const reg_expression& Rx, + match_flag_type Flags=match_default ) + { + return find_format_all_copy( + Input, + regex_finder( Rx, Flags ), + empty_formatter( Input ) ); + } + + //! Erase all regex algorithm + /*! + Erase all subsequences, matching given regex, from the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param Rx A regular expression + \param Flags Regex options + */ + template< + typename SequenceT, + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT> + inline void erase_all_regex( + SequenceT& Input, + const reg_expression& Rx, + match_flag_type Flags=match_default ) + { + find_format_all( + Input, + regex_finder( Rx, Flags ), + empty_formatter( Input ) ); + } + +// find_all_regex ------------------------------------------------------------------// + + //! Find all regex algorithm + /*! + This algorithm finds all substrings matching the give regex + in the input. The result is given as a 'container of containers'. + Each match of the search sequence is represented by one + element in the result. + + \param Result A 'container container' to container the result of search. + Both outer and inner container must have constructor taking a pair + of iterators as an argument. + Typical type of the result is + \c std::vector>. + (each element of such a vector will container a range delimiting + a match). + \param Input A container which will be searched. + \param Rx A regular expression + \param Flags Regex options + \return A reference to the result + + \note Prior content of the result will be overridden. + */ + template< + typename SequenceSequenceT, + typename CollectionT, + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT > + inline SequenceSequenceT& find_all_regex( + SequenceSequenceT& Result, + const CollectionT& Input, + const reg_expression& Rx, + match_flag_type Flags=match_default ) + { + return iter_find( + Result, + Input, + regex_finder(Rx,Flags) ); + } + +// split_regex ------------------------------------------------------------------// + + //! Split regex algorithm + /*! + Tokenize expression. This function is equivalent of C strtok. Input + sequence is split into tokens, separated by separators. Separator + is an every match of the given regex. + + \param Result A 'container container' to container the result of search. + Both outer and inner container must have constructor taking a pair + of iterators as an argument. + Typical type of the result is + 'c std::vector>. + (each element of such a vector will container a range delimiting + a match). + \param Input A container which will be searched. + \param Rx A regular expression + \param Flags Regex options + \return A reference to the result + + \note Prior content of the result will be overridden. + */ + template< + typename SequenceSequenceT, + typename CollectionT, + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT > + inline SequenceSequenceT& split_regex( + SequenceSequenceT& Result, + const CollectionT& Input, + const reg_expression& Rx, + match_flag_type Flags=match_default ) + { + return iter_split( + Result, + Input, + regex_finder(Rx,Flags) ); + } + + } // namespace algorithm + + // pull names into the boost namespace + using algorithm::find_regex; + using algorithm::replace_regex; + using algorithm::replace_regex_copy; + using algorithm::replace_all_regex; + using algorithm::replace_all_regex_copy; + using algorithm::erase_regex; + using algorithm::erase_regex_copy; + using algorithm::erase_all_regex; + using algorithm::erase_all_regex_copy; + using algorithm::find_all_regex; + using algorithm::split_regex; + +} // namespace boost + + +#endif // BOOST_STRING_REGEX_HPP diff --git a/include/boost/algorithm/string/regex_find_format.hpp b/include/boost/algorithm/string/regex_find_format.hpp new file mode 100644 index 0000000..1ad450e --- /dev/null +++ b/include/boost/algorithm/string/regex_find_format.hpp @@ -0,0 +1,84 @@ +// Boost string_algo library regex_find_format.hpp header 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. + +#ifndef BOOST_STRING_REGEX_FIND_FORMAT_HPP +#define BOOST_STRING_REGEX_FIND_FORMAT_HPP + +#include +#include +#include +#include + +/*! \file + Defines the \c refex_finder and \c regex_formatter generators. These two functors + are designed to work together. \c regex_formatter uses additional information + about a match contained in the reger_finder search result. +*/ + +namespace boost { + namespace algorithm { + +// regex_finder -----------------------------------------------// + + //! "Regex" finder + /*! + Construct the \c regex_finder. Finder uses regex engine to search + for a match. + Result is given in \c regex_search_result. This is an extension + of the iterator_range. In addition it containes match results + from the \c regex_search algorithm. + + \param Rx A regular expression + \param MatchFlags Regex search options + \return An instance of the \c regex_finder object + */ + template< + typename CharT, + typename RegexTraitsT, typename RegexAllocatorT> + inline detail::find_regexF< reg_expression > + regex_finder( + const reg_expression& Rx, + match_flag_type MatchFlags=match_default ) + { + return detail:: + find_regexF< + reg_expression >( Rx, MatchFlags ); + } + +// regex_formater ---------------------------------------------// + + //! Regex formatter + /*! + Construct the \c regex_formatter. Regex formatter uses regex engine to + format a match found by the \c regex_finder. + This formatted it designed to closely cooperate with \c regex_finder. + + \param Format Regex format definition + \param Flags Format flags + \return An instance of the \c regex_formatter functor + */ + template< + typename CharT, + typename TraitsT, typename AllocT > + inline detail::regex_formatF< std::basic_string< CharT, TraitsT, AllocT > > + regex_formatter( + const std::basic_string& Format, + match_flag_type Flags=format_default ) + { + return + detail::regex_formatF< std::basic_string >( + Format, + Flags ); + } + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_REGEX_FIND_FORMAT_HPP diff --git a/include/boost/algorithm/string/replace.hpp b/include/boost/algorithm/string/replace.hpp new file mode 100644 index 0000000..e4d8027 --- /dev/null +++ b/include/boost/algorithm/string/replace.hpp @@ -0,0 +1,936 @@ +// Boost string_algo library replace.hpp header 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. + +#ifndef BOOST_STRING_REPLACE_HPP +#define BOOST_STRING_REPLACE_HPP + +#include +#include +#include +#include +#include +#include +#include + +/*! \file + Defines various replace algorithms. Each algorithm replaces + a part(s) of the input according to a searching and a replace criterium. +*/ + +namespace boost { + namespace algorithm { + +// replace_range --------------------------------------------------------------------// + + //! Replace range algorithm + /*! + Substitute the given range in the input sequence with the + format sequence. The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param SearchRange A range in the input to be substituted + \param Format A substitute sequence + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T> + inline OutputIteratorT replace_range_copy( + OutputIteratorT Output, + const Collection1T& Input, + const iterator_range< + BOOST_STRING_TYPENAME + const_iterator_of::type>& SearchRange, + const Collection2T& Format) + { + return find_format_copy( + Output, + Input, + range_finder(SearchRange), + const_formatter(Format)); + } + + //! Replace range algorithm + /*! + Substitute a given range in the input sequence with the + format sequence. The result is a modified copy of the input. + + \param Input An input sequence + \param SearchRange A range in the input to be substituted + \param Format A substitute sequence + \return A modified copy of the input + */ + template + inline SequenceT replace_range_copy( + const SequenceT& Input, + const iterator_range< + BOOST_STRING_TYPENAME + const_iterator_of::type>& SearchRange, + const CollectionT& Format) + { + return find_format_copy( + Input, + range_finder(SearchRange), + const_formatter(Format)); + } + + //! Replace range algorithm + /*! + Substitute a given range in the input sequence with the + format sequence. The input sequence is modified in-place. + + \param Input An input sequence + \param SearchRange A range in the input to be substituted + \param Format A substitute sequence + */ + template + inline void replace_range( + SequenceT& Input, + const iterator_range< + BOOST_STRING_TYPENAME + iterator_of::type>& SearchRange, + const CollectionT& Format) + { + find_format( + Input, + range_finder(SearchRange), + const_formatter(Format)); + } + +// replace_first --------------------------------------------------------------------// + + //! Replace first algorithm + /*! + Substitute a first match of the search sequence in the input + with the format sequence. The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T, + typename Collection3T> + inline OutputIteratorT replace_first_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search, + const Collection3T& Format) + { + return find_format_copy( + Output, + Input, + first_finder(Search), + const_formatter(Format) ); + } + + //! Replace first algorithm + /*! + Substitute a first match of the search sequence in the input + with the format sequence. The result is a modified copy of the input. + + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \return A modified copy of the input + */ + template + inline SequenceT replace_first_copy( + const SequenceT& Input, + const Collection1T& Search, + const Collection2T& Format ) + { + return find_format_copy( + Input, + first_finder(Search), + const_formatter(Format) ); + } + + //! Replace first algorithm + /*! + Substitute a first match of the search sequence in the input + with the format sequence. The input sequence is modified in-place. + + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + */ + template + inline void replace_first( + SequenceT& Input, + const Collection1T& Search, + const Collection2T& Format ) + { + find_format( + Input, + first_finder(Search), + const_formatter(Format) ); + } + +// replace_first ( case insensitive ) ---------------------------------------------// + + //! Replace first algorithm ( case insensitive ) + /*! + Substitute a first match of the search sequence in the input + with the format sequence. The result is a modified copy of the input. + Searching is case insensitive. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \param Loc a locale used for case insensitive comparison + \return A modified copy of the input + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T, + typename Collection3T> + inline OutputIteratorT ireplace_first_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search, + const Collection3T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Output, + Input, + first_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + + //! Replace first algorithm ( case insensitive ) + /*! + Substitute a first match of the search sequence in the input + with the format sequence. The result is copied to the given output iterator. + Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \param Loc a locale used for case insensitive comparison + \return An output iterator pointing just after last inserted character + */ + template + inline SequenceT ireplace_first_copy( + const SequenceT& Input, + const Collection2T& Search, + const Collection1T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Input, + first_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + + //! Replace first algorithm ( case insensitive ) + /*! + Substitute a first match of the search sequence in the input + with the format sequence. Input sequence is modified in-place. + Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \param Loc a locale used for case insensitive comparison + */ + template + inline void ireplace_first( + SequenceT& Input, + const Collection1T& Search, + const Collection2T& Format, + const std::locale& Loc=std::locale() ) + { + find_format( + Input, + first_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + +// replace_last --------------------------------------------------------------------// + + //! Replace last algorithm + /*! + Substitute a last match of the search sequence in the input + with the format sequence. The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T, + typename Collection3T> + inline OutputIteratorT replace_last_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search, + const Collection3T& Format ) + { + return find_format_copy( + Output, + Input, + last_finder(Search), + const_formatter(Format) ); + } + + //! Replace last algorithm + /*! + Substitute a last match of the search sequence in the input + with the format sequence. The result is a modified copy of the input. + + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \return A modified copy of the input + */ + template + inline SequenceT replace_last_copy( + const SequenceT& Input, + const Collection1T& Search, + const Collection2T& Format ) + { + return find_format_copy( + Input, + last_finder(Search), + const_formatter(Format) ); + } + + //! Replace last algorithm + /*! + Substitute a last match of the search sequence in the input + with the format sequence. Input sequence is modified in-place. + + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + */ + template + inline void replace_last( + SequenceT& Input, + const Collection1T& Search, + const Collection2T& Format ) + { + find_format( + Input, + last_finder(Search), + const_formatter(Format) ); + } + +// replace_last ( case insensitive ) -----------------------------------------------// + + //! Replace last algorithm ( case insensitive ) + /*! + Substitute a last match of the search sequence in the input + with the format sequence. The result is copied to the given output iterator. + Searching is case insensitive. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \param Loc a locale used for case insensitive comparison + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T, + typename Collection3T> + inline OutputIteratorT ireplace_last_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search, + const Collection3T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Output, + Input, + last_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + + //! Replace last algorithm ( case insensitive ) + /*! + Substitute a last match of the search sequence in the input + with the format sequence. The result is a modified copy of the input. + Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \param Loc a locale used for case insensitive comparison + \return A modified copy of the input + */ + template + inline SequenceT ireplace_last_copy( + const SequenceT& Input, + const Collection1T& Search, + const Collection2T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Input, + last_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + + //! Replace last algorithm ( case insensitive ) + /*! + Substitute a last match of the search sequence in the input + with the format sequence.The input sequence is modified in-place. + Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \param Loc a locale used for case insensitive comparison + \return A reference to the modified input + */ + template + inline void ireplace_last( + SequenceT& Input, + const Collection1T& Search, + const Collection2T& Format, + const std::locale& Loc=std::locale() ) + { + find_format( + Input, + last_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + +// replace_nth --------------------------------------------------------------------// + + //! Replace nth algorithm + /*! + Substitute an Nth match of the search sequence in the input + with the format sequence. The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + \param Format A substitute sequence + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T, + typename Collection3T> + inline OutputIteratorT replace_nth_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search, + unsigned int Nth, + const Collection3T& Format ) + { + return find_format_copy( + Output, + Input, + nth_finder(Search, Nth), + const_formatter(Format) ); + } + + //! Replace nth algorithm + /*! + Substitute an Nth match of the search sequence in the input + with the format sequence. The result is a modified copy of the input. + + \param Input An input sequence + \param Search A string to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + \param Format A substitute sequence + \return A modified copy of the input + */ + template + inline SequenceT replace_nth_copy( + const SequenceT& Input, + const Collection1T& Search, + unsigned int Nth, + const Collection2T& Format ) + { + return find_format_copy( + Input, + nth_finder(Search, Nth), + const_formatter(Format) ); + } + + //! Replace nth algorithm + /*! + Substitute an Nth match of the search sequence in the input + with the format sequence. Input sequence is modified in-place. + + \param Input An input sequence + \param Search A string to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + \param Format A substitute sequence + */ + template + inline void replace_nth( + SequenceT& Input, + const Collection1T& Search, + unsigned int Nth, + const Collection2T& Format ) + { + find_format( + Input, + nth_finder(Search, Nth), + const_formatter(Format) ); + } + +// replace_nth ( case insensitive ) -----------------------------------------------// + + //! Replace nth algorithm ( case insensitive ) + /*! + Substitute an Nth match of the search sequence in the input + with the format sequence. The result is copied to the given output iterator. + Searching is case insensitive. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + \param Format A substitute sequence + \param Loc a locale used for case insensitive comparison + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T, + typename Collection3T> + inline OutputIteratorT ireplace_nth_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search, + unsigned int Nth, + const Collection3T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Output, + Input, + nth_finder(Search, Nth, is_iequal(Loc) ), + const_formatter(Format) ); + } + + //! Replace nth algorithm ( case insensitive ) + /*! + Substitute an Nth match of the search sequence in the input + with the format sequence. The result is a modified copy of the input. + Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + \param Format A substitute sequence + \param Loc a locale used for case insensitive comparison + \return A modified copy of the input + */ + template + inline SequenceT ireplace_nth_copy( + const SequenceT& Input, + const Collection1T& Search, + unsigned int Nth, + const Collection2T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_copy( + Input, + nth_finder(Search, Nth, is_iequal(Loc)), + const_formatter(Format) ); + } + + //! Replace nth algorithm ( case insensitive ) + /*! + Substitute an Nth match of the search sequence in the input + with the format sequence. Input sequence is modified in-place. + Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + \param Format A substitute sequence + \param Loc a locale used for case insensitive comparison + */ + template + inline void ireplace_nth( + SequenceT& Input, + const Collection1T& Search, + unsigned int Nth, + const Collection2T& Format, + const std::locale& Loc=std::locale() ) + { + find_format( + Input, + nth_finder(Search, Nth, is_iequal(Loc)), + const_formatter(Format) ); + } + +// replace_all --------------------------------------------------------------------// + + //! Replace all algorithm + /*! + Substitute all occurrences of the search sequence in the input + with the format sequence. The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T, + typename Collection3T> + inline OutputIteratorT replace_all_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search, + const Collection3T& Format ) + { + return find_format_all_copy( + Output, + Input, + first_finder(Search), + const_formatter(Format) ); + } + + //! Replace all algorithm + /*! + Substitute all occurrences of the search sequence in the input + with the format sequence. The result is a modified copy of the input. + + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \return A modified copy of the input + */ + template + inline SequenceT replace_all_copy( + const SequenceT& Input, + const Collection1T& Search, + const Collection2T& Format ) + { + return find_format_all_copy( + Input, + first_finder(Search), + const_formatter(Format) ); + } + + //! Replace all algorithm + /*! + Substitute all occurrences of the search sequence in the input + with the format sequence. The input sequence is modified in-place. + + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \return A reference to the modified input + */ + template + inline void replace_all( + SequenceT& Input, + const Collection1T& Search, + const Collection2T& Format ) + { + find_format_all( + Input, + first_finder(Search), + const_formatter(Format) ); + } + +// replace_all ( case insensitive ) -----------------------------------------------// + + //! Replace all algorithm ( case insensitive ) + /*! + Substitute all occurrences of the search sequence in the input + with the format sequence. The result is copied to the given output iterator. + Searching is case insensitive. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \param Loc a locale used for case insensitive comparison + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T, + typename Collection3T> + inline OutputIteratorT ireplace_all_copy( + OutputIteratorT Output, + const Collection1T& Input, + const Collection2T& Search, + const Collection3T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_all_copy( + Output, + Input, + first_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + + //! Replace all algorithm ( case insensitive ) + /*! + Substitute all occurrences of the search sequence in the input + with the format sequence. The result is a modified copy of the input. + Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \param Loc a locale used for case insensitive comparison + \return A modified copy of the input + */ + template + inline SequenceT ireplace_all_copy( + const SequenceT& Input, + const Collection1T& Search, + const Collection2T& Format, + const std::locale& Loc=std::locale() ) + { + return find_format_all_copy( + Input, + first_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + + //! Replace all algorithm ( case insensitive ) + /*! + Substitute all occurrences of the search sequence in the input + with the format sequence.The input sequence is modified in-place. + Searching is case insensitive. + + \param Input An input sequence + \param Search A string to be searched for. + \param Format A substitute sequence + \param Loc a locale used for case insensitive comparison + */ + template + inline void ireplace_all( + SequenceT& Input, + const Collection1T& Search, + const Collection2T& Format, + const std::locale& Loc=std::locale() ) + { + find_format_all( + Input, + first_finder(Search, is_iequal(Loc)), + const_formatter(Format) ); + } + +// replace_head --------------------------------------------------------------------// + + //! Replace head algorithm + /*! + Replace the head of the input with the given format sequence. + Head is a prefix of a seqence of given size. + If the sequence is shorter then required, whole sequence if + considered to be the head. The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param N A length of the head + \param Format A substitute sequence + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T> + inline OutputIteratorT replace_head_copy( + OutputIteratorT Output, + const Collection1T& Input, + unsigned int N, + const Collection2T& Format ) + { + return find_format_copy( + Output, + Input, + head_finder(N), + const_formatter(Format) ); + } + + //! Replace head algorithm + /*! + Replace the head of the input with the given format sequence. + Head is a prefix of a seqence of given size. + If the sequence is shorter then required, whole sequence if + considered to be the head. The result is a modified copy of the input. + + \param Input An input sequence + \param N A length of the head + \param Format A substitute sequence + \return A modified copy of the input + */ + template + inline SequenceT replace_head_copy( + const SequenceT& Input, + unsigned int N, + const CollectionT& Format ) + { + return find_format_copy( + Input, + head_finder(N), + const_formatter(Format) ); + } + + //! Replace head algorithm + /*! + Replace the head of the input with the given format sequence. + Head is a prefix of a seqence of given size. + If the sequence is shorter then required, whole sequence if + considered to be the head. The input sequence is modified in-place. + + \param Input An input sequence + \param N A length of the head + \param Format A substitute sequence + */ + template + inline void replace_head( + SequenceT& Input, + unsigned int N, + const CollectionT& Format ) + { + find_format( + Input, + head_finder(N), + const_formatter(Format) ); + } + +// replace_tail --------------------------------------------------------------------// + + //! Replace tail algorithm + /*! + Replace the tail of the input with the given format sequence. + Tail is a suffix of a seqence of given size. + If the sequence is shorter then required, whole sequence if + considered to be the tail. The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input sequence + \param N A length of the head + \param Format A substitute sequence + \return An output iterator pointing just after last inserted character + */ + template< + typename OutputIteratorT, + typename Collection1T, + typename Collection2T> + inline OutputIteratorT replace_tail_copy( + OutputIteratorT Output, + const Collection1T& Input, + unsigned int N, + const Collection2T& Format ) + { + return find_format_copy( + Output, + Input, + tail_finder(N), + const_formatter(Format) ); + } + + //! Replace tail algorithm + /*! + Replace the tail of the input with the given format sequence. + Tail is a suffix of a seqence of given size. + If the sequence is shorter then required, whole sequence is + considered to be the tail. The result is a modified copy of the input. + + \param Input An input sequence + \param N A length of the head + \param Format A substitute sequence + \return A modified copy of the input + */ + template + inline SequenceT replace_tail_copy( + const SequenceT& Input, + unsigned int N, + const CollectionT& Format ) + { + return find_format_copy( + Input, + tail_finder(N), + const_formatter(Format) ); + } + + //! Replace tail algorithm + /*! + Replace the tail of the input with the given format sequence. + Tail is a suffix of a seqence of given size. + If the sequence is shorter then required, whole sequence is + considered to be the tail. The input sequence is modified in-place. + + \param Input An input sequence + \param N A length of the head + \param Format A substitute sequence + */ + template + inline void replace_tail( + SequenceT& Input, + unsigned int N, + const CollectionT& Format ) + { + find_format( + Input, + tail_finder(N), + const_formatter(Format) ); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::replace_range_copy; + using algorithm::replace_range; + using algorithm::replace_first_copy; + using algorithm::replace_first; + using algorithm::ireplace_first_copy; + using algorithm::ireplace_first; + using algorithm::replace_last_copy; + using algorithm::replace_last; + using algorithm::ireplace_last_copy; + using algorithm::ireplace_last; + using algorithm::replace_nth_copy; + using algorithm::replace_nth; + using algorithm::ireplace_nth_copy; + using algorithm::ireplace_nth; + using algorithm::replace_all_copy; + using algorithm::replace_all; + using algorithm::ireplace_all_copy; + using algorithm::ireplace_all; + using algorithm::replace_head_copy; + using algorithm::replace_head; + using algorithm::replace_tail_copy; + using algorithm::replace_tail; + +} // namespace boost + +#endif // BOOST_REPLACE_HPP diff --git a/include/boost/algorithm/string/sequence_traits.hpp b/include/boost/algorithm/string/sequence_traits.hpp new file mode 100644 index 0000000..87079a2 --- /dev/null +++ b/include/boost/algorithm/string/sequence_traits.hpp @@ -0,0 +1,144 @@ +// Boost string_algo library sequence_traits.hpp header 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. + +#ifndef BOOST_STRING_SEQUENCE_TRAITS_HPP +#define BOOST_STRING_SEQUENCE_TRAITS_HPP + +#include +#include +#include + +/*! \file + Traits defined in this header are used by various algorithms to achieve + better performance for specific containers. + Traits provide fail-safe defaults. If a container supports some of these + features, it is possible to specialize the specific trait for this container. + For lacking compilers, it is possible of define an override for a specific tester + function. + + Due to language restriction, it is not currently possible to define specialization for + stl containers without including the coresponding header. To decrease the overhead + needed by this inclusion, user can selectively include specialization + header for a specific container. They are located in boost/algorithm/string/stl + directory. Alternatively she can include boost/algorithm/string/std_collection_traits.hpp + header which contains specialization for all stl containers. +*/ + +namespace boost { + namespace algorithm { + +// sequence traits -----------------------------------------------// + + //! Native replace tester + /*! + Declare an override of this tester function with return + type boost::string_algo::yes_type for a sequence with this property. + + \return yes_type if the container has basic_string like native replace + method. + */ + no_type has_native_replace_tester(...); + + //! Native replace trait + /*! + This trait specifies that the sequence has \c std::string like replace method + */ + template< typename T > + class has_native_replace + { + private: + static T* t; + public: + BOOST_STATIC_CONSTANT(bool, value=( + sizeof(has_native_replace_tester(t))==sizeof(yes_type) ) ); + typedef mpl::bool_ type; + }; + + //! Stable iterators tester + /*! + Declare an override of this tester function with return + type boost::string_algo::yes_type for a sequence with this property. + + \return yes_type if the seqeunce's insert/replace/erase methods do not invalidate + existing iterators. + */ + no_type has_stable_iterators_tester(...); + + //! Stable iterators trait + /*! + This trait specifies that the sequence has stable iterators. It means, + that operations like insert/erase/replace do not invalidate iterators. + */ + template< typename T > + class has_stable_iterators + { + private: + static T* t; + public: + + BOOST_STATIC_CONSTANT(bool, value=( + sizeof(has_stable_iterators_tester(t))==sizeof(yes_type) ) ); + typedef mpl::bool_ type; + }; + + //! const time insert tester + /*! + Declare an override of this tester function with return + type boost::string_algo::yes_type for a sequence with this property. + + \return yes_type if the sequence's insert method is working in constant time + */ + no_type has_const_time_insert_tester(...); + + //! Const time insert trait + /*! + This trait specifies that the sequence's insert method has + constant time complexity. + */ + template< typename T > + class has_const_time_insert + { + private: + static T* t; + public: + BOOST_STATIC_CONSTANT(bool, value=( + sizeof(has_const_time_insert_tester(t))==sizeof(yes_type) ) ); + typedef mpl::bool_ type; + }; + + //! const time erase tester + /*! + Declare an override of this tester function with return + type boost::string_algo::yes_type for a sequence with this property. + + \return yes_type if the sequence's erase method is working in constant time + */ + no_type has_const_time_erase_tester(...); + + //! Const time erase trait + /*! + This trait specifies that the sequence's erase method has + constant time complexity. + */ + template< typename T > + class has_const_time_erase + { + private: + static T* t; + public: + BOOST_STATIC_CONSTANT(bool, value=( + sizeof(has_const_time_erase_tester(t))==sizeof(yes_type) ) ); + typedef mpl::bool_ type; + }; + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_SEQUENCE_TRAITS_HPP diff --git a/include/boost/algorithm/string/split.hpp b/include/boost/algorithm/string/split.hpp new file mode 100644 index 0000000..d0d337b --- /dev/null +++ b/include/boost/algorithm/string/split.hpp @@ -0,0 +1,152 @@ +// Boost string_algo library find.hpp header 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. + +#ifndef BOOST_STRING_SPLIT_HPP +#define BOOST_STRING_SPLIT_HPP + +#include +#include +#include +#include +#include +#include + +/*! \file + Defines basic split algorithms. + Split algorithms can be used to divide a sequence + into several parts according to a given criterium. + Result is given as a 'container of containers' where + elements are copies or references to extracted parts. + This file contains some common specializations of generic + algorithms contained in the file split2.hpp +*/ + +namespace boost { + namespace algorithm { + +// find_all ------------------------------------------------------------// + + //! Find all algorithm + /*! + This algorithm finds all occurrences of the search sequence + in the input. A result is given as a 'container of containers'. + Each match of the search sequence is represented by one + element in the result. + + \param Result A 'container container' to container the result of search. + Both outer and inner container must have constructor taking a pair + of iterators as an argument. + Typical type of the result is + \c std::vector). + (each element of such a vector will container a range delimiting + a match). + \param Input A container which will be searched. + \param Search A string to be searched for. + \return A reference the result + + \note Prior content of the result will be overridden. + */ + template< typename SequenceSequenceT, typename Collection1T, typename Collection2T > + inline SequenceSequenceT& find_all( + SequenceSequenceT& Result, + Collection1T& Input, + const Collection2T& Search) + { + return iter_find( + Result, + Input, + first_finder(Search) ); + } + + //! Find all algorithm ( case insensitive ) + /*! + This algorithm finds all occurrences of the search sequence + in the input. A result is given as a 'container of containers'. + Each match of the search sequence is represented by one + element in the result. Searching is case insensitive. + + \param Result A 'container container' to container the result of search. + Both outer and inner container must have constructor taking a pair + of iterators as an argument. + Typical type of the result is + \c std::vector>. + (each element of such a vector will container a range delimiting + a match). + \param Input A container which will be searched. + \param Search A string to be searched for. + \param Loc a locale used for case insensitive comparison + \return A reference the result + + \note Prior content of the result will be overridden. + */ + template< typename SequenceSequenceT, typename Collection1T, typename Collection2T > + inline SequenceSequenceT& ifind_all( + SequenceSequenceT& Result, + Collection1T& Input, + const Collection2T& Search, + const std::locale& Loc=std::locale() ) + { + return iter_find( + Result, + Input, + first_finder(Search, is_iequal(Loc) ) ); + } + + +// tokenize -------------------------------------------------------------// + + //! Split algorithm + /*! + Tokenize expression. This function is equivalent of C strtok. Input + sequence is split into tokens, separated by separators. Separators + are given in the mean of predicate. + + \param Result A 'container container' to container the result of search. + Both outer and inner container must have constructor taking a pair + of iterators as an argument. + Typical type of the result is + \c std::vector>. + (each element of such a vector will container a range delimiting + a match). + + \param Input A container which will be searched. + \param Pred A predicate to identify separators. This predicate is + supposed to return true if a given element is a separator. + \param eCompress If eCompress argument is set to token_compress_on, adjacent + separators are merged together. Otherwise, every two separators + delimit a token. + \return A reference the result + + \note Prior content of the result will be overridden. + */ + template< typename SequenceSequenceT, typename CollectionT, typename PredicateT > + inline SequenceSequenceT& split( + SequenceSequenceT& Result, + CollectionT& Input, + PredicateT Pred, + token_compress_mode_type eCompress=token_compress_off ) + { + return iter_split( + Result, + Input, + token_finder( Pred, eCompress ) ); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::find_all; + using algorithm::ifind_all; + using algorithm::split; + +} // namespace boost + + +#endif // BOOST_STRING_SPLIT_HPP + diff --git a/include/boost/algorithm/string/std/list_traits.hpp b/include/boost/algorithm/string/std/list_traits.hpp new file mode 100644 index 0000000..a36f15e --- /dev/null +++ b/include/boost/algorithm/string/std/list_traits.hpp @@ -0,0 +1,37 @@ +// Boost string_algo library list_traits.hpp header 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. + +#ifndef BOOST_STRING_STD_LIST_TRAITS_HPP +#define BOOST_STRING_STD_LIST_TRAITS_HPP + +#include +#include + +namespace boost { + namespace algorithm { + +// std::list<> traits -----------------------------------------------// + + // stable iterators tester + template + yes_type has_stable_iterators_tester( const std::list* ); + + // const time insert tester + template + yes_type has_const_time_insert_tester( const std::list* ); + + // const time erase tester + template + yes_type has_const_time_erase_tester( const std::list* ); + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_STD_LIST_TRAITS_HPP diff --git a/include/boost/algorithm/string/std/rope_traits.hpp b/include/boost/algorithm/string/std/rope_traits.hpp new file mode 100644 index 0000000..72c0155 --- /dev/null +++ b/include/boost/algorithm/string/std/rope_traits.hpp @@ -0,0 +1,41 @@ +// Boost string_algo library string_traits.hpp header 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. + +#ifndef BOOST_STRING_STD_ROPE_TRAITS_HPP +#define BOOST_STRING_STD_ROPE_TRAITS_HPP + +#include +#include + +namespace boost { + namespace algorithm { + +// SGI's std::rope<> traits -----------------------------------------------// + + // native replace tester + template + yes_type has_native_replace_tester( const std::rope* ); + + // stable iterators tester + template + yes_type has_stable_iterators_tester( const std::rope* ); + + // const time insert tester + template + yes_type has_const_time_insert_tester( const std::rope* ); + + // const time erase tester + template + yes_type has_const_time_erase_tester( const std::rope* ); + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_ROPE_TRAITS_HPP diff --git a/include/boost/algorithm/string/std/slist_traits.hpp b/include/boost/algorithm/string/std/slist_traits.hpp new file mode 100644 index 0000000..a141aff --- /dev/null +++ b/include/boost/algorithm/string/std/slist_traits.hpp @@ -0,0 +1,37 @@ +// Boost string_algo library slist_traits.hpp header 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. + +#ifndef BOOST_STRING_STD_SLIST_TRAITS_HPP +#define BOOST_STRING_STD_SLIST_TRAITS_HPP + +#include +#include + +namespace boost { + namespace algorithm { + +// SGI's std::slist<> traits -----------------------------------------------// + + // stable iterators tester + template + yes_type has_stable_iterators_tester( const std::slist* ); + + // const time insert tester + template + yes_type has_const_time_insert_tester( const std::slist* ); + + // const time erase tester + template + yes_type has_const_time_erase_tester( const std::slist* ); + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_STD_LIST_TRAITS_HPP diff --git a/include/boost/algorithm/string/std/string_traits.hpp b/include/boost/algorithm/string/std/string_traits.hpp new file mode 100644 index 0000000..51cbfb2 --- /dev/null +++ b/include/boost/algorithm/string/std/string_traits.hpp @@ -0,0 +1,29 @@ +// Boost string_algo library string_traits.hpp header 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. + +#ifndef BOOST_STRING_STD_STRING_TRAITS_HPP +#define BOOST_STRING_STD_STRING_TRAITS_HPP + +#include +#include + +namespace boost { + namespace algorithm { + +// std::basic_string<> traits -----------------------------------------------// + + // native replace tester + template + yes_type has_native_replace_tester( const std::basic_string* ); + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_LIST_TRAITS_HPP diff --git a/include/boost/algorithm/string/std_containers_traits.hpp b/include/boost/algorithm/string/std_containers_traits.hpp new file mode 100644 index 0000000..ab0cf3f --- /dev/null +++ b/include/boost/algorithm/string/std_containers_traits.hpp @@ -0,0 +1,25 @@ +// Boost string_algo library std_containers_traits.hpp header 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. + +#ifndef BOOST_STRING_STD_CONTAINERS_TRAITS_HPP +#define BOOST_STRING_STD_CONTAINERS_TRAITS_HPP + +/*!\file + This file includes sequence traits for stl containers. +*/ + +#include +#include +#include + +#ifdef BOOST_HAS_SLIST +# include +#endif + +#endif // BOOST_STRING_STD_CONTAINERS_TRAITS_HPP diff --git a/include/boost/algorithm/string/trim.hpp b/include/boost/algorithm/string/trim.hpp new file mode 100644 index 0000000..a4726be --- /dev/null +++ b/include/boost/algorithm/string/trim.hpp @@ -0,0 +1,382 @@ +// Boost string_algo library trim.hpp header 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. + +#ifndef BOOST_STRING_TRIM_HPP +#define BOOST_STRING_TRIM_HPP + +#include +#include +#include +#include +#include + +/*! \file + Defines trim algorithms. + Trim algorithms are used to remove trailing and leading spaces from a + sequence (string). Space is recognized using given locales. + + Parametric (\c _if) variants use predicate (functor) to select which characters + are to be trimmed.. + Functions take a selection predicate as a parameter, which is used to determine + if a character is a space. Common predicates are provided in classification.hpp header. + +*/ + +namespace boost { + namespace algorithm { + + // left trim -----------------------------------------------// + + + //! Left trim - parametric + /*! + Remove all leading spaces from the input. Supplied predicate + is used to determine which character is a space. + The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input collection + \param IsSpace An unary predicate identifying spaces + \return An output iterator pointing just after last inserted character + */ + template + inline OutputIteratorT trim_left_copy_if( + OutputIteratorT Output, + const CollectionT& Input, + PredicateT IsSpace) + { + std::copy( + detail::trim_begin( + begin(Input), + end(Input), + IsSpace ), + end(Input), + Output); + + return Output; + } + + //! Left trim - parametric + /*! + Remove all leading spaces from the input. Supplied predicate + is used to determine which character is a space. + The result is a trimmed copy if the input + + \param Input An input sequence + \param IsSpace An unary predicate identifying spaces + \return A trimmed copy if the input + */ + template + inline SequenceT trim_left_copy_if(const SequenceT& Input, PredicateT IsSpace) + { + return SequenceT( + detail::trim_begin( + begin(Input), + end(Input), + IsSpace ), + end(Input)); + } + + //! Left trim - parametric + /*! + Remove all leading spaces from the input. + The result is a trimmed copy if the input + + \param Input An input sequence + \param Loc a locale used for 'space' classification + \return A trimmed copy if the input + */ + template + inline SequenceT trim_left_copy(const SequenceT& Input, const std::locale& Loc=std::locale()) + { + return + trim_left_copy_if( + Input, + is_space(Loc)); + } + + //! Left trim + /*! + Remove all leading spaces from the input. Supplied predicate + is used to determine which character is a space. + The input sequence is modified in-place. + + \param Input An input sequence + \param IsSpace An unary predicate identifying spaces + */ + template + inline void trim_left_if(SequenceT& Input, PredicateT IsSpace) + { + Input.erase( + begin(Input), + detail::trim_begin( + begin(Input), + end(Input), + IsSpace)); + } + + //! Left trim + /*! + Remove all leading spaces from the input. + The Input sequence is modified in-place. + + \param Input An input sequence + \param Loc A locale used for 'space' classification + */ + template + inline void trim_left(SequenceT& Input, const std::locale& Loc=std::locale()) + { + trim_left_if( + Input, + is_space(Loc)); + } + + // right trim -----------------------------------------------// + + //! Right trim - parametric + /*! + Remove all trailing spaces from the input. Supplied predicate + is used to determine which character is a space. + The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input collection + \param IsSpace An unary predicate identifying spaces + \return An output iterator pointing just after last inserted character + */ + template + inline OutputIteratorT trim_right_copy_if( + OutputIteratorT Output, + const CollectionT& Input, + PredicateT IsSpace ) + { + std::copy( + begin(Input), + detail::trim_end( + begin(Input), + end(Input), + IsSpace ), + Output ); + + return Output; + } + + //! Right trim - parametric + /*! + Remove all trailing spaces from the input. Supplied predicate + is used to determine which character is a space. + The result is a trimmed copy if the input + + \param Input An input Sequence + \param IsSpace An unary predicate identifying spaces + \return A trimmed copy if the input + */ + template + inline SequenceT trim_right_copy_if(const SequenceT& Input, PredicateT IsSpace) + { + return SequenceT( + begin(Input), + detail::trim_end( + begin(Input), + end(Input), + IsSpace) + ); + } + + //! Right trim + /*! + Remove all trailing spaces from the input. + The result is a trimmed copy if the input + + \param Input An input sequence + \param Loc A locale used for 'space' classification + \return A trimmed copy if the input + */ + template + inline SequenceT trim_right_copy(const SequenceT& Input, const std::locale& Loc=std::locale()) + { + return + trim_right_copy_if( + Input, + is_space(Loc)); + } + + + //! Right trim - parametric + /*! + Remove all trailing spaces from the input. Supplied predicate + is used to determine which character is a space. + The input sequence is modified in-place. + + \param Input An input sequence + \param IsSpace An unary predicate identifying spaces + */ + template + inline void trim_right_if(SequenceT& Input, PredicateT IsSpace) + { + Input.erase( + detail::trim_end( + begin(Input), + end(Input), + IsSpace ), + end(Input) + ); + } + + + //! Right trim + /*! + Remove all trailing spaces from the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param Loc A locale used for 'space' classification + */ + template + inline void trim_right(SequenceT& Input, const std::locale& Loc=std::locale()) + { + trim_right_if( + Input, + is_space(Loc) ); + } + + // both side trim -----------------------------------------------// + + //! Trim - parametric + /*! + Remove all trailing and leading spaces from the input. + Supplied predicate is used to determine which character is a space. + The result is copied to the given output iterator. + + \param Output A output iterator to which the result will be copied + \param Input An input collection + \param IsSpace An unary predicate identifying spaces + \return An output iterator pointing just after last inserted character + */ + template + inline OutputIteratorT trim_copy_if( + OutputIteratorT Output, + const CollectionT& Input, + PredicateT IsSpace) + { + BOOST_STRING_TYPENAME + const_iterator_of::type TrimEnd= + detail::trim_end( + begin(Input), + end(Input), + IsSpace); + + std::copy( + detail::trim_begin( + begin(Input), TrimEnd, IsSpace), + TrimEnd, + Output + ); + + return Output; + } + + //! Trim - parametric + /*! + Remove all leading and trailing spaces from the input. + Supplied predicate is used to determine which character is a space. + The result is a trimmed copy if the input + + \param Input An input sequence + \param IsSpace An unary predicate identifying spaces + \return A trimmed copy if the input + */ + template + inline SequenceT trim_copy_if(const SequenceT& Input, PredicateT IsSpace) + { + BOOST_STRING_TYPENAME + const_iterator_of::type TrimEnd= + detail::trim_end( + begin(Input), + end(Input), + IsSpace); + + return SequenceT( + detail::trim_begin( + begin(Input), + TrimEnd, + IsSpace), + TrimEnd + ); + } + + //! Trim + /*! + Remove all leading and trailing spaces from the input. + The result is a trimmed copy if the input + + \param Input An input sequence + \param Loc A locale used for 'space' classification + \return A trimmed copy if the input + */ + template + inline SequenceT trim_copy( const SequenceT& Input, const std::locale& Loc=std::locale() ) + { + return + trim_copy_if( + Input, + is_space(Loc) ); + } + + //! Trim + /*! + Remove all leading and trailing spaces from the input. + Supplied predicate is used to determine which character is a space. + The input sequence is modified in-place. + + \param Input An input sequence + \param IsSpace An unary predicate identifying spaces + */ + template + inline void trim_if(SequenceT& Input, PredicateT IsSpace) + { + trim_right_if( Input, IsSpace ); + trim_left_if( Input, IsSpace ); + } + + //! Trim + /*! + Remove all leading and trailing spaces from the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param Loc A locale used for 'space' classification + */ + template + inline void trim(SequenceT& Input, const std::locale& Loc=std::locale()) + { + trim_if( + Input, + is_space( Loc ) ); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::trim_left; + using algorithm::trim_left_if; + using algorithm::trim_left_copy; + using algorithm::trim_left_copy_if; + using algorithm::trim_right; + using algorithm::trim_right_if; + using algorithm::trim_right_copy; + using algorithm::trim_right_copy_if; + using algorithm::trim; + using algorithm::trim_if; + using algorithm::trim_copy; + using algorithm::trim_copy_if; + +} // namespace boost + +#endif // BOOST_STRING_TRIM_HPP diff --git a/include/boost/algorithm/string/yes_no_type.hpp b/include/boost/algorithm/string/yes_no_type.hpp new file mode 100644 index 0000000..89a89dc --- /dev/null +++ b/include/boost/algorithm/string/yes_no_type.hpp @@ -0,0 +1,32 @@ +// Boost string_algo library yes_no_type.hpp header 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. + +#ifndef BOOST_STRING_YES_NO_TYPE_DETAIL_HPP +#define BOOST_STRING_YES_NO_TYPE_DETAIL_HPP + +namespace boost { + namespace algorithm { + + // taken from boost mailing-list + // when yes_no_type will become officialy + // a part of boost distribution, this header + // will be deprecated + template struct size_descriptor + { + typedef char (& type)[I]; + }; + + typedef size_descriptor<1>::type yes_type; + typedef size_descriptor<2>::type no_type; + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_YES_NO_TYPE_DETAIL_HPP diff --git a/include/boost/algorithm/string_regex.hpp b/include/boost/algorithm/string_regex.hpp new file mode 100644 index 0000000..5914b03 --- /dev/null +++ b/include/boost/algorithm/string_regex.hpp @@ -0,0 +1,22 @@ +// Boost string_algo library string_algo.hpp header file ---------------------------// + +// (C) Copyright Pavol Droba 2002-2003. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_STRING_ALGO_REGEX_HPP +#define BOOST_STRING_ALGO_REGEX_HPP + +/*! \file + Cumulative include for string_algo library. + In addtion to string_algo.hpp, it contains also regex-related stuff. +*/ + +#include +#include +#include + +#endif // BOOST_STRING_ALGO_REGEX_HPP diff --git a/string/doc/Jamfile.v2 b/string/doc/Jamfile.v2 new file mode 100644 index 0000000..b684f99 --- /dev/null +++ b/string/doc/Jamfile.v2 @@ -0,0 +1,61 @@ +# 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 +# htt../..//www.boost.org/LICENSE_1_0.txt) +# +# See htt../..//www.boost.org for updates, documentation, and revision history. + +project boost/libs/algorithm/string/doc ; + +doxygen reference + : + ../../../../boost/algorithm/string.hpp + ../../../../boost/algorithm/string_regex.hpp + + ../../../../boost/algorithm/string/classification.hpp + ../../../../boost/algorithm/string/iterator_range.hpp + ../../../../boost/algorithm/string/sequence_traits.hpp + ../../../../boost/algorithm/string/std_containers_traits.hpp + ../../../../boost/algorithm/string/container_traits.hpp + ../../../../boost/algorithm/string/concept.hpp + ../../../../boost/algorithm/string/compare.hpp + ../../../../boost/algorithm/string/constants.hpp + + ../../../../boost/algorithm/string/case_conv.hpp + + ../../../../boost/algorithm/string/find.hpp + ../../../../boost/algorithm/string/finder.hpp + ../../../../boost/algorithm/string/find_iterator.hpp + + ../../../../boost/algorithm/string/trim.hpp + + ../../../../boost/algorithm/string/predicate.hpp + ../../../../boost/algorithm/string/split.hpp + ../../../../boost/algorithm/string/iter_find.hpp + + ../../../../boost/algorithm/string/erase.hpp + ../../../../boost/algorithm/string/replace.hpp + ../../../../boost/algorithm/string/find_format.hpp + ../../../../boost/algorithm/string/formatter.hpp + + ../../../../boost/algorithm/string/regex.hpp + ../../../../boost/algorithm/string/regex_find_format.hpp + : + HIDE_UNDOC_MEMBERS=YES + EXTRACT_PRIVATE=NO + ENABLE_PREPROCESSING=YES + MACRO_EXPANSION=YES + EXPAND_ONLY_PREDEF=YES + SEARCH_INCLUDES=YES + PREDEFINED="BOOST_STRING_TYPENAME=typename \"BOOST_STATIC_CONSTANT(type,var)=static const type var;\"" + ; + +boostbook string_algo + : + string_algo.xml + ; + + + diff --git a/string/doc/concept.xml b/string/doc/concept.xml new file mode 100644 index 0000000..5b1fa81 --- /dev/null +++ b/string/doc/concept.xml @@ -0,0 +1,199 @@ + + +
+ Concepts + + + + +
+ Definitions + + + Notation + + + + F + A type that is a model of Finder + + + Fmt + A type that is a model of Formatter + + + Iter + + Iterator Type + + + + f + Object of type F + + + fmt + Object of type Fmt + + + i,j + Objects of type Iter + + + +
+
+ +
+ Finder Concept + + + Finder is a functor which searches for an arbitrary part of a container. + The result of the search is given as an iterator_range + delimiting the selected part. + + + + Valid Expressions + + + + Expression + Return Type + Effects + + + + + f(i,j) + Convertible to iterator_range<Iter> + Perform the search on the interval [i,j) and returns the result of the search + + + +
+ + + Various algorithms need to perform a searching in a container and a Finder is a generalization of such + search operations that allows algorithms to abstract from searching. For instance, generic replace + algorithms can replace any part of the input, and the finder is used to select the desired one. + + + Note, that it is only required that the finder works with a particular iterator type. However, + a Finder operation can be defined as a template, allowing the Finder to work with any iterator. + + + Examples + + + + + Finder implemented as a class. This Finder always returns the whole input as a match. operator() + is templated, so that the finder can be used on any iterator type. + + +struct simple_finder +{ + template<typename ForwardIteratorT> + boost::iterator_range<ForwardIterator> operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + return boost::make_range( Begin, End ); + } +}; + + + + Function Finder. Finder can be any function object. That means, an ordinary function with the + required signature can be used as well. However, such a function can be used only for + a specific iterator type. + + +boost::iterator_range<std::string> simple_finder( + std::string::const_iterator Begin, + std::string::const_iterator End ) +{ + return boost::make_range( Begin, End ); +} + + + + +
+
+ Formatter concept + + + Formatters are used by replace algorithms. + They are used in close combination with finders. + A formatter is a functor, which takes a result from a Finder operation and transforms it in a specific way. + The operation of the formatter can use additional information provided by a specific finder, + for example regex_formatter() uses the match information from + regex_finder() to format the result of formatter operation. + + + + Valid Expressions + + + + Expression + Return Type + Effects + + + + + fmt(f(i,j)) + A container type, accessible using container traits + Formats the result of the finder operation + + + +
+ + + Similarly to finders, formatters generalize format operations. When a finder is used to + select a part of the input, formatter takes this selection and performs some formating + on it. Algorithms can abstract from formating using a formatter. + + + Examples + + + + + Formatter implemented as a class. This Formatter does not perform any formating and + returns repackaged match. operator() + is templated, so that the Formatter can be used on any Finder type. + + +struct simple_formatter +{ + template<typename FindResultT> + std::string operator()( const FindResultT& Match ) + { + std::string Temp( Match.begin(), Match.end() ); + return Temp; + } +}; + + + + Function Formatter. Similarly to Finder, Formatter can be any function object. + However, as a function, it can be used only with a specific Finder type. + + +std::string simple_formatter( boost::iterator_range<std::string::const_iterator>& Match ) +{ + std::string Temp( Match.begin(), Match.end() ); + return Temp; +} + + + + +
+
diff --git a/string/doc/credits.xml b/string/doc/credits.xml new file mode 100644 index 0000000..77b24a2 --- /dev/null +++ b/string/doc/credits.xml @@ -0,0 +1,13 @@ + + +
+ Credits +
+ Acknowledgments + + Thanks for everybody who gave suggestions and comments. Especially to Thorsten Ottosen, Jeff Garland + and the other boost members who participated. + +
+
diff --git a/string/doc/design.xml b/string/doc/design.xml new file mode 100644 index 0000000..8240b4d --- /dev/null +++ b/string/doc/design.xml @@ -0,0 +1,281 @@ + + +
+ Design Topics + + + + +
+ <code>iterator_range</code> class + + + An iterator_range is an encapsulation of a pair of iterators that + delimit a sequence (or, a range). This concept is widely used by + sequence manipulating algorithms. Although being so useful, there no direct support + for it in the standard library (The closest thing is that some algorithms return a pair of iterators). + Instead all STL algorithms have two distinct parameters for beginning and end of a range. This design + is natural for implementation of generic algorithms, but it forbids to work with a range as a single value. + + + It is possible to encapsulate a range in std::pair<>, but + the std::pair<> is a too generic encapsulation, so it is not best match for a range. + For instance, it does not enforce that begin and end iterators are of the same type. + + + Naturally the range concept is heavily used also in this library. During the development of + the library, it was discovered, that there is a need for a reasonable encapsulation for it. + A core part of the library deals with substring searching algorithms. Any such an algorithm, + returns a range delimiting the result of the search. std::pair<> was considered as + unsuitable. Therefore the iterator_range was defined. + + + The intention of the iterator_range class is to manage a range as a single value and provide + a basic interface for common operations. Its interface is similar to that of container. + In addition of begin() + and end() accessors, it has member functions for checking if the range is empty, + or to determine the size of the range. It has also a set of member typedefs that extract + type information from the encapsulated iterators. As such, the interface is compatible with + the container traits requirements so + it is possible to use this class as a parameter to many algorithms in this library. + +
+ +
+ Container Traits + + + Container traits provide uniform access to different types of containers. + This functionality allows to write generic algorithms which work with several + different kinds of containers. For this library it means, that, for instance, + many algorithms work with std::string as well as with char[]. + + + The following container types are supported: + + + Standard containers + + + Built-in arrays (like int[]) + + + Null terminated strings (this includes char[],wchar_t[],char*, and wchar_t*) + + + std::pair<iterator,iterator> + + + + + Container traits support a subset of container concept (Std §23.1). This subset + can be described as an input container concept, e.g. a container with an immutable content. + Its definition can be found in the header boost/string_algo/container_traits.hpp. + + + In the table C denotes a container and c is an object of C. + + + Container Traits + + + + Name + Standard container equivalent + Description + Maeterlinck + + + + container_value_type<C>::type + C::value_type + Type of contained values + + + container_difference_type<C>::type + C::difference_type + difference type of the container + + + container_iterator<C>::type + C::iterator + iterator type of the container + + + container_const_iterator<C>::type + C::const_iterator + const_iterator type of the container + + + container_result_iterator<C>::type + + + result_iterator type of the container. This type maps to C::iterator + for mutable container and C::const_iterator for const containers. + + + + begin(c) + c.begin() + + Gets the iterator pointing to the start of the container. + + + + end(c) + c.end() + + Gets the iterator pointing to the end of the container. + + + + size(c) + c.size() + + Gets the size of the container. + + + + empty(c) + c.empty() + + Checks if the container is empty. + + + + +
+ + + The container traits are only a temporary part of this library. There is a plan for a separate submission + of a container_traits library to Boost. Once it gets accepted, String Algorithm Library will be adopted to + use it and the internal implementation will be deprecated. + + +
+
+ Sequence Traits + + + Major difference between std::list and std::vector is not in the interfaces + they provide, rather in the inner details of the class and the way how it performs + various operation. The problem is that it is not possible to infer this difference from the + definitions of classes without some special mechanism. + However some algorithms can run significantly faster with the knowledge of the properties + of a particular container. + + + Sequence traits allows one to specify additional properties of a sequence container (see Std.§32.2). + These properties are then used by algorithms to select optimized handling for some operations. + The sequence traits are declared in the header + boost/string_algo/sequence_traits.hpp. + + + + In the table C denotes a container and c is an object of C. + + + Sequence Traits + + + + Trait + Description + + + + + sequence_has_native_replace<C>::value + Specifies that the sequence has std::string like replace method + + + sequence_has_stable_iterators<C>::value + + Specifies that the sequence has stable iterators. It means, + that operations like insert/erase/replace + do not invalidate iterators. + + + + sequence_has_const_time_insert<C>::value + + Specifies that the insert method of the sequence has + constant time complexity. + + + + sequence_has_const_time_erase<C>::value + + Specifies that the erase method of the sequence has constant time complexity + + + + +
+ + + Current implementation contains specializations for std::list<T> and + std::basic_string<T> from the standard library and SGI's std::rope<T> and std::slist<T>. + +
+
+ Find Algorithms + + + Find algorithms have similar functionality to std::search() algorithm. They provide a different + interface which is more suitable for common string operations. + Instead of returning just the start of matching subsequence they return a range which is necessary + when the length of the matching subsequence is not known beforehand. + This feature also allows a partitioning of the input sequence into three + parts: a prefix, a substring and a suffix. + + + Another difference is an addition of various searching methods besides find_first, including find_regex. + + + It the library, find algorithms are implemented in terms of + Finders. Finders are used also by other facilities + (replace,split). + For convenience, there are also function wrappers for these finders to simplify find operations. + + + Currently the library contains only naive implementation of find algorithms with complexity + O(n * m) where n is the size of the input sequence and m is the size of the search sequence. + There are algorithms with complexity O(n), but for smaller sequence a constant overhead is + rather big. For small m << n (m magnitued smaller than n) the current implementation + provides acceptable efficiency. + Even the C++ standard defines the required complexity for search algorithm as O(n * m). + It is possible that a future version of library will also contain algorithms with linear + complexity as an option + +
+
+ Replace Algorithms + + + The implementation of replace algorithms follows the layered structure of the library. The + lower layer implements generic substitution of a range in the input sequence. + This layer takes a Finder object and a + Formatter object as an input. These two + functors define what to replace and what to replace it with. The upper layer functions + are just wrapping calls to the lower layer. Finders are shared with the find and split facility. + + + As usual, the implementation of the lower layer is designed to work with a generic sequence while + taking an advantage of specific features if possible + (by using Sequence traits) + +
+
+ Split Algorithms + + + Split algorithms are a logical extension of find facility. + Instead of searching for one match, the whole input is searched. The result of the search is then used + to partition the input. It depends on the algorithms which parts are returned as the result of + split operations. It can be the matching parts (find_all()) of the parts in + between (split()). + +
+
diff --git a/string/doc/environment.xml b/string/doc/environment.xml new file mode 100644 index 0000000..3364b97 --- /dev/null +++ b/string/doc/environment.xml @@ -0,0 +1,55 @@ + + +
+ Environment +
+ Build + + The whole library is provided in headers. Regex variants of some algorithms, + however, are dependent on the Boost.Regex library. All such algorithms are + separated in boost/string_algo/regex.hpp. + If this header is used, an application must be linked with the Boost.Regex + library. + +
+ +
+ Examples + + Examples showing the basic usage of the library can be found in the libs/string_algo/example + directory. There is a separate file for the each part of the library. Please follow the boost + build guidelines to build examples using the bjam. To successfully build regex examples + the Boost.Regex library is required. + +
+ +
+ Tests + + A full set of test cases for the library is located in the libs/string_algo/test directory. + The test cases can be executed using the boost build system. For the tests of regular + expression variants of algorithms, the Boost.Regex library is required. + +
+ +
+ Portability + + The library has been successfully compiled and tested with the following compilers: + + + Microsoft Visual C++ 7.0 + Microsoft Visual C++ 7.1 + GCC 3.2 + GCC 3.3.1 + + + + There are known limitation on platforms not supporting partial template specialization. + Library depends on correctly implemented std::iterator_traits class. If a standard library provided + with compiler is broken, the String Algorithm Library cannot function properly. Usually it implies + that primitive pointer iterators are not working with the library functions. + +
+
diff --git a/string/doc/intro.xml b/string/doc/intro.xml new file mode 100644 index 0000000..882bfb7 --- /dev/null +++ b/string/doc/intro.xml @@ -0,0 +1,45 @@ + + +
+ Introduction + + + The String Algorithm Library provides a generic implementation of + string-related algorithms which are missing in STL. It is an extension + to the algorithms library of STL and it includes trimming, case conversion, + predicates and find/replace functions. All of them come in different variants + so it is easier to choose the best fit for a particular need. + + + The implementation is not restricted to work with a particular container + (like a std::basic_string), rather it is as generic as + possible. This generalization is not compromising the performance since + algorithms are using container specific features when it means a performance + gain. + + + The library has layered structure to simplify the usage without sacrificing the + generalization. + + The easy-to-use interface, defined in the namespace boost, represents the first layer. + Algorithms and classes defined here do not offer a lot of customization opportunities + rather they are provided in more different variants, so a user can chose the + one that suits her needs. + + The second layer, defined in the namespace boost::string_algo, on the + other hand, is generic. Basically it contains the same set of algorithms as the first layer, + but the interface is more flexible and allows more customization, but it is harder to use. + The first layer is implemented as set of wrappers around the second layer. + + + The documentation is divided into several sections. For a quick start read the + Usage section. + The Design Topics, + Concepts and Rationale + provide some explanation about the library design and structure an explain how it should be used. + See the Reference for the complete list of provided utilities + and algorithms. Functions and classes in the reference are organized by the headers in which they are defined. + The reference contains links to the detailed description for every entity in the library. + +
diff --git a/string/doc/rationale.xml b/string/doc/rationale.xml new file mode 100644 index 0000000..4691d7b --- /dev/null +++ b/string/doc/rationale.xml @@ -0,0 +1,76 @@ + + +
+ Rationale + + + + +
+ Library structure + + + When designing a library it is always a problem to find a balance between generalization + and usability. A generic utility can have a wider range of usage with more options for extensibility, + but it can also bring unwanted complexity for everyday usage. + + + Imagine a library for drawing geometric objects. It can contain one generic function draw() + with many parameters specifying what to draw, like size, number of edges, shape etc. + This would allow you to draw almost anything, but usually a user only needs to draw + only a triangle or a square and she will have to specify this simple request in a + very complicated way.For this purpose two functions, draw_triangle() and + draw_square(), would suit much better then a generic draw() function. + + + The String Algorithm Library solves this problem by dividing the interface into two layers. + The first layer (defined in the namespace boost) contains ready to use algorithms specialized + for common tasks. They are provided in multiple variants to better suit specific needs. + The second layer (defined in the namespace boost::string_algo), provides generic interfaces with + more options for extending and tunning. + + + For instance, a boost::trim() algorithm trims spaces from + an input string. When there is a need to trim something else, there is + boost::string_algo::trim() which interface allows one to specify a + predicate which selects the characters to be removed. + +
+
+ Locales + + + Locales have a very close relation to string processing. They contain information about + the character sets and are used, for example, to change the case of characters and + to classify the characters. + + + C++ allows to work with multiple different instances of locales at once. If an algorithm + manipulates some data in a way that requires the usage of locales, there must be a way + to specify them. However, one instance of locales is sufficient for most of the applications, + and for a user it could be very tedious to specify which locales to use on every place + where it is needed. + + + Fortunately, the C++ standard allows to specify the global locales (using static member + function std:locale::global()). When instantiating an + std::locale class without explicit information, the instance will + be initialized with the global locale. It means, that if an algorithm needs a locale, + it should have an std::locale parameter with default value std::locale(). + If a user needs to specify locales explicitly, she can do so. Otherwise the global + locales are used. + +
+
+ Regular Expressions + + + Regular expressions are an essential part of text processing. For this reason, the library + provides also regex variants of some algorithms. The library does not try to replace + Boost.Regex, but it merely wraps its functionality in a new interface. + As a part of this library regex algorithms integrate smoothly with other components which + brings additional value. + +
+
diff --git a/string/doc/string_algo.xml b/string/doc/string_algo.xml new file mode 100644 index 0000000..dae1eb2 --- /dev/null +++ b/string/doc/string_algo.xml @@ -0,0 +1,42 @@ + + + + + + Pavol + Droba + + + + 2002 + 2003 + Pavol Droba + + + + Use, modification and distribution is subject to the Boost + Software License, Version 1.0. (See accompanying file + LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + + + + A set of generic string-related algorithms and utilities. + + + + + Boost String Algorithms Library + + + + + + + + + + diff --git a/string/doc/usage.xml b/string/doc/usage.xml new file mode 100644 index 0000000..df48827 --- /dev/null +++ b/string/doc/usage.xml @@ -0,0 +1,275 @@ + + +
+ Usage + + + + + +
+ First Example + + + Using the algorithms is straightforward. Let us have a look at the first example: + + + #include <boost/string_algo.hpp> + using namespace std; + using namespace boost; + namespace sa=boost::string_algo + + // ... + + string str1(" hello world! "); + trim( to_upper(str1) ); // str1 == "HELLO WORLD!" + + string str2=ireplace_first_copy(str1,"hello","goodbye"); // str2 == "goodbye WORLD!" + + + This example converts str1 to upper case and trims spaces from the start and the end + of the string. str2 is then created as a copy of str1 with "hello" replaced with "goodbye". + This example demonstrates several important concepts used in the library: + + + + Container parameters: + Unlike the STL algorithms, parameters are not specified only in form + of iterators. The STL convention allows for great flexibility, + but it has several limitation. It is not possible to stack algorithms together, + because a container is passed in two parameters, so it is not possible to use + a return value from another algorithm. It is considerably easier to write + to_lower(str1), then to_lower(str1.begin(), str1.end()). + + + The magic of container_traits + provides a uniform way of handling different containers. + If there is a need to pass a pair of iterators, + iterator_range + can be used to package iterators into a structure with the container interface. + + + + Copy vs. Mutable: + Many algorithms in the library are performing a transformation of the input. + The transformation can be done in-place, mutating the input sequence, or a copy + of the transformed input can be created, leaving the input intact. None of + these possibilities is superior to the other one and both have different + advantages and disadvantages. For this reason, both are provided with the library. + + + + Algorithm stacking: + Copy versions return a transformed input as a result. Mutable variants return + a reference to the input. Thus both versions allow a simple chaining of + transformations within one expression (i.e. one can write + trim_copy(to_upper_copy(s)) as well as trim(to_upper(s))). + + + + Naming: + Naming follows the conventions from the Standard C++ Library. If there is a + copy and mutable version of the same algorithm, the mutable version has no suffix + and the copy version has suffix _copy. + Some algorithms have prefix i + (e.g. ifind_first()). + This prefix identifies that the algorithm works in a case-insensitive manner. + + + + + To use the library, include the boost/string_algo.hpp header. + If the regex related functions are needed, include the + boost/string_algo_regex.hpp header. + +
+
+ Case conversion + + + STL has a nice way of converting character case. Unfortunately, it works only + for a single character and we want to convert a string, + + + string str1("HeLlO WoRld!"); + to_upper(str1); // str1=="HELLO WORLD!" + + + to_upper() and to_lower() convert the case of + characters in a container using a specified locale. + +
+
+ Predicates and Classification + + A part of the library deals with string related predicates. Consider this example: + + + bool is_executable( string& filename ) + { + return + iends_with(filename, ".exe") || + iends_with(filename, ".com"); + } + + // ... + string str1("command.com"); + cout + << str1 + << is_executable("command.com")? "is": "is not" + << "an executable" + << endl; // prints "command.com is an executable" + + //.. + char text1[]="hello world!"; + cout + << text1 + << all( text1, is_lower<char>() )? "is": "is not" + << "written in the lower case" + << endl; // prints "hello world! is written in the lower case" + + + The predicates are resolving if a substring is contained in the input string + under various conditions. The conditions are if a string starts with the substring, + ends with the substring, + simply contains the substring or if both strings are equal. See the reference for + boost/string_algo/predicate.hpp for more details. + In addition the algorithm all() checks + all elements of a container to satisfy a condition specified by a predicate. + This predicate can be any unary predicate, but the library provides a bunch of + useful string-related predicates ready for use. + These are located in the boost/string_algo/classification.hpp header. + +
+
+ Trimming + + + When parsing the input of a user, strings usually have unwanted leading or trailing + characters. To get rid of them, we need trim functions: + + + string str1=" hello world! "; + string str2=trim_left_copy(str1); // str2 == "hello world! " + string str3=trim_right_copy(str2); // str3 == " hello world!" + trim(str1); // str1 == "hello world!" + + string phone="00423333444"; + // remove leading 0 from the phone number + sa::trim_left(phone,is_any_of<char>("0")); // phone == "423333444" + + + It is possible to trim the spaces on the right, on the left or on the both sides of a string. + And for those cases when there is a need to remove something else than blank space, the + string_algo namespace contains generic versions of the trim algorithms. Using these, + a user can specify a functor which will select the space to be removed. It is possible to use + classification predicates like is_digit() mentioned in the previous paragraph. + See the reference for the boost/string_algo/trim.hpp. + +
+
+ Find algorithms + + + The library contains a set of find algorithms. Here is an example: + + + char text[]="hello dolly!"; + iterator_range<char*> result=find_last(text,"ll"); + + transform( result.begin(), result.end(), result.begin(), bind2nd(plus<char>(), 1) ); + // text = "hello dommy!" + + to_upper(result); // text == "hello doMMy!" + + + We have used find_last() to search the text for "ll". + The result is given in the iterator_range. + This range delimits the + part of the input which satisfies the find criteria. In our example it is the last occurrence of "ll". + + As we can see, input of the find_last() algorithm can be also + char[] because this type is supported by + container_traits. + + Following lines transform the result. Notice, that + iterator_range have familiar + begin() and end() methods, so it can be used like any other STL container. + +
+
+ Replace Algorithms + + Find algorithms can be used for searching for a specific part of the sequence. Replace goes one step + further. After a matching part is found, it is substituted with something else. The substitution is computed + from an original, using some transformation. + + + string str1="Hello Dolly, Hello World!" + replace_first(str1, "Dolly", "Jane"); // str1 == "Hello Jane, Hello World!" + replace_last(str1, "Hello", "Goodbye"); // str1 == "Hello Jane, Goodbye World!" + erase_all(str1, " "); // str1 == "HelloJane,GoodbyeWorld!" + erase_head(str1, 6); // str1 == "Jane,GoodbyeWorld!" + + + For the complete list of replace and erase functions see the + reference. + There is a lot of predefined function for common usage, however, the library allows you to + define a custom replace() that suits a specific need. There is a generic replace() + function which takes two parameters. + The first one is a Finder object, the second one is + a Formatter object. + The Finder object is a functor which performs the searching for the replacement part. The Formatter object + takes the result of the Finder (usually a reference to the found substring) and creates a + substitute for it. Replace algorithm puts these two together and makes the desired substitution. + +
+
+ Split + + + Split algorithms allow one to divide a sequence into parts. Each part represents a + token and tokens are separated by separators. + One can either search for tokens or search for separators: + + + + string str1("hello abc-*-ABC-*-aBc goodbye"); + + typedef vector< iterator_range<string::iterator> > find_vector_type; + + find_vector_type FindVec; // #1: Search for separators + ifind_all( FindVec, str1, "abc" ); // FindVec == { [abc],[ABC],[aBc] } + + typdef vector< string > split_vector_type; + + split_vector_type SplitVec; // #2: Search for tokens + split( SplitVec, str1, is_any_of<char>("-*") ); // SplitVec == { "hello abc","ABC","aBc goodbye" } + + + [hello] designates an iterator_range delimiting this substring. + + + The result of a split algorithm is a container of containers. There is only one restriction: + The inner container type must be able to hold extracted parts of the input sequence. This example + shows the special case where the inner container is an + iterator_range + instead of e.g. std::string. This way, a user gets a reference + (in the form of iterators) delimiting the parts of the input sequence. Otherwise, a copy of + each extracted part is created and added to the outer container. + + + So to recap, there are two basic algorithms: find_all() + returns extracts the parts + matching the specification whereas split() uses the matching + parts as delimiters, and extracts the parts in between them. + + + Generalizations of these two algorithms are called iter_find() and + iter_split(). They take a + Finder object, as an argument to search for + the substring. + +
+
diff --git a/string/example/Jamfile b/string/example/Jamfile new file mode 100644 index 0000000..ac5a52d --- /dev/null +++ b/string/example/Jamfile @@ -0,0 +1,75 @@ +# Boost string_algo library examples Jamfile --------------------------------- +# +# Copyright Pavol Droba 2002-2003. Use, modification and +# distribution is subject to the Boost Software License, Version +# 1.0. (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +# +# See http://www.boost.org for updates, documentation, and revision history. + +subproject libs/algorithm/string/example ; + +exe conv_example + : + conv_example.cpp + : + $(BOOST_ROOT) + : + ; + +exe predicate_example + : + predicate_example.cpp + : + $(BOOST_ROOT) + : + ; + +exe find_example + : + find_example.cpp + : + $(BOOST_ROOT) + : + ; + +exe replace_example + : + replace_example.cpp + : + $(BOOST_ROOT) + : + ; + +exe rle_example + : + rle_example.cpp + : + $(BOOST_ROOT) + : + ; + +exe trim_example + : + trim_example.cpp + : + $(BOOST_ROOT) + : + ; + +exe regex_example + : + regex_example.cpp + ../../../regex/build/boost_regex + : + $(BOOST_ROOT) + : + ; + +exe split_example + : + split_example.cpp + : + $(BOOST_ROOT) + : + ; diff --git a/string/example/conv_example.cpp b/string/example/conv_example.cpp new file mode 100644 index 0000000..b6a08f9 --- /dev/null +++ b/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 +#include +#include +#include +#include + +using namespace std; +using namespace boost; + +int main() +{ + cout << "* Case Conversion Example *" << endl << endl; + + string str1("AbCdEfG"); + vector vec1( str1.begin(), str1.end() ); + + // Convert vector of chars to lower case + cout << "lower-cased copy of vec1: "; + to_lower_copy( ostream_iterator(cout), vec1 ); + cout << endl; + + // Conver string str1 to upper case ( copy the input ) + cout << "upper-cased copy of str1: " << to_upper_copy( str1 ) << endl; + + // Inplace conversion + to_lower( str1 ); + cout << "lower-cased str1: " << str1 << endl; + + cout << endl; + + return 0; +} diff --git a/string/example/find_example.cpp b/string/example/find_example.cpp new file mode 100644 index 0000000..7fd7e60 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +using namespace std; +using namespace boost; + +int main() +{ + cout << "* Find Example *" << endl << endl; + + string str1("abc___cde___efg"); + string str2("abc"); + + // find "cde" substring + iterator_range range=find_first( str1, string("cde") ); + + // convert a substring to upper case + // note that iterator range can be directly passed to the algorithm + to_upper( range ); + + cout << "str1 with upper-cased part matching cde: " << str1 << endl; + + // get a head of the string + iterator_range head=find_head( str1, 3 ); + cout << "head(3) of the str1: " << string( head.begin(), head.end() ) << endl; + + // get the tail + head=find_tail( str2, 5 ); + cout << "tail(5) of the str2: " << string( head.begin(), head.end() ) << endl; + + // char processing + char text[]="hello dolly!"; + iterator_range crange=find_last(text,"ll"); + + // transform the range ( add 1 ) + transform( crange.begin(), crange.end(), crange.begin(), bind2nd( plus(), 1 ) ); + // uppercase the range + to_upper( crange ); + + cout << text << endl; + + cout << endl; + + return 0; +} diff --git a/string/example/predicate_example.cpp b/string/example/predicate_example.cpp new file mode 100644 index 0000000..037ef47 --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + + +using namespace std; +using namespace boost; + +int main() +{ + cout << "* Predicate Example *" << endl << endl; + + string str1("123xxx321"); + string str2("abc"); + + // Check if str1 starts with '123' + cout << "str1 starts with \"123\": " << + (starts_with( str1, string("123") )?"true":"false") << endl; + + // Check if str1 ends with '123' + cout << "str1 ends with \"123\": " << + (ends_with( str1, string("123") )?"true":"false") << endl; + + // Check if str1 containes 'xxx' + cout << "str1 contains \"xxx\": " << + (contains( str1, string("xxx") )?"true":"false") << endl; + + + // Check if str2 equals to 'abc' + cout << "str2 equals \"abc\": " << + (equals( str2, string("abc") )?"true":"false") << endl; + + + // Classification functors and all predicate + if ( all(";.,", is_punct() ) ) + { + cout << "\";.,\" are all punctuation characters" << endl; + } + + // Classification predicated can be combined + if ( all("abcxxx", is_any_of("xabc") && !is_space() ) ) + { + cout << "true" << endl; + } + + cout << endl; + + return 0; +} diff --git a/string/example/regex_example.cpp b/string/example/regex_example.cpp new file mode 100644 index 0000000..9eba1c7 --- /dev/null +++ b/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 +#include +#include +#include +#include + +using namespace std; +using namespace boost; + +int main() +{ + cout << "* Regex Example *" << endl << endl; + + string str1("abc__(456)__123__(123)__cde"); + + // Replace all substrings matching (digit+) + cout << + "replace all (digit+) in str1 with #digit+# :" << + replace_all_regex_copy( str1, regex("\\(([0-9]+)\\)"), string("#$1#") ) << endl; + + // Erase all substrings matching (digit+) + cout << + "remove all sequences of letters from str1 :" << + erase_all_regex_copy( str1, regex("[[:alpha:]]+") ) << endl; + + // in-place regex transformation + replace_all_regex( str1, regex("_(\\([^\\)]*\\))_"), string("-$1-") ); + cout << "transformad str1: " << str1 << endl; + + cout << endl; + + return 0; +} diff --git a/string/example/replace_example.cpp b/string/example/replace_example.cpp new file mode 100644 index 0000000..b176777 --- /dev/null +++ b/string/example/replace_example.cpp @@ -0,0 +1,88 @@ +// Boost string_algo library example file ---------------------------------// + +// Copyright Pavol Droba 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include +#include +#include + +//Following two includes contain second-layer function. +//They are already included by first-layer header + +//#include +//#include + +using namespace std; +using namespace boost; + +// uppercase formatter +/* + Convert an input to upper case. + Note, that this formatter can be used only on std::string inputs. +*/ +inline string upcase_formatter( + const iterator_range& Replace ) +{ + string Temp(Replace.begin(), Replace.end()); + to_upper(Temp); + return Temp; +} + +int main() +{ + cout << "* Replace Example *" << endl << endl; + + string str1("abc___cde___efg"); + + // Erase 6-9th characters from the string + cout << "str1 without 6th to 9th character:" << + erase_range_copy( str1, make_iterator_range(str1.begin()+6, str1.begin()+9) ) << endl; + + // Replace 6-9th character with '+++' + cout << "str1 with 6th to 9th character replaced with '+++': " << + replace_range_copy( + str1, make_iterator_range(str1.begin()+6, str1.begin()+9), "+++" ) << endl; + + cout << "str1 with 'cde' replaced with 'XYZ': "; + + // Replace first 'cde' with 'XYZ'. Modify the input + replace_first_copy( ostream_iterator(cout), str1, "cde", "XYZ" ); + cout << endl; + + // Replace all '___' + cout << "str1 with all '___' replaced with '---': " << + replace_all_copy( str1, "___", "---" ) << endl; + + // Erase all '___' + cout << "str1 without all '___': " << + erase_all_copy( str1, "___" ) << endl; + + // replace third and 5th occurrence of _ in str1 + // note that nth argument is 0-based + replace_nth( str1, "_", 4, "+" ); + replace_nth( str1, "_", 2, "+" ); + + cout << "str1 with third and 5th occurrence of _ replace: " << str1 << endl; + + // Custom formatter examples + string str2("abC-xxxx-AbC-xxxx-abc"); + + // Find string 'abc' ignoring the case and convert it to upper case + cout << "Upcase all 'abc'(s) in the str2: " << + find_format_all_copy( + str2, + first_finder("abc", is_iequal()), + upcase_formatter ); + + cout << endl; + + return 0; +} diff --git a/string/example/rle_example.cpp b/string/example/rle_example.cpp new file mode 100644 index 0000000..a6ec323 --- /dev/null +++ b/string/example/rle_example.cpp @@ -0,0 +1,241 @@ +// Boost string_algo library example file ---------------------------------// + +// Copyright Pavol Droba 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +/* + RLE compression using replace framework. Goal is to compress a sequence of + repeating characters into 3 bytes ( repeat mark, character and repetition count ). + For simplification, it works only on numeric-value sequences. +*/ + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace boost; + +// replace mark specification, specialize for a specific element type +template< typename T > T repeat_mark() { return std::numeric_limits::max(); }; + +// Compression ----------------------------------------------------------------------- + + +// compress finder -rle +/* + Find a sequence which can be compressed. It has to be at least 3-character long + sequence of repetitive characters +*/ +struct find_compressF +{ + // Construction + find_compressF() {} + + // Operation + template + iterator_range operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef ForwardIteratorT input_iterator_type; + typedef typename boost::detail::iterator_traits::value_type value_type; + typedef iterator_range result_type; + + // begin of the matching segment + input_iterator_type MStart=End; + // Repetition counter + value_type Cnt=0; + + // Search for a sequence of repetitive characters + for(input_iterator_type It=Begin; It!=End;) + { + input_iterator_type It2=It++; + + if ( It==End || Cnt>=std::numeric_limits::max() ) + { + return result_type( MStart, It ); + } + + if ( *It==*It2 ) + { + if ( MStart==End ) + { + // Mark the start + MStart=It2; + } + + // Increate repetition counter + Cnt++; + } + else + { + if ( MStart!=End ) + { + if ( Cnt>2 ) + return result_type( MStart, It ); + else + { + MStart=End; + Cnt=0; + } + } + } + } + + return result_type( End, End ); + } +}; + +// rle compress format +/* + Transform a sequence into repeat mark, character and count +*/ +template +struct format_compressF +{ +private: + typedef SeqT result_type; + typedef typename SeqT::value_type value_type; + +public: + // Construction + format_compressF() {}; + + // Operation + template< typename ReplaceT > + result_type operator()( const ReplaceT& Replace ) const + { + SeqT r; + r.push_back( repeat_mark() ); + r.push_back( *(Replace.begin()) ); + r.push_back( value_type( Replace.size() ) ); + + return r; + } +}; + +// Decompression ----------------------------------------------------------------------- + + +// find decompress-rle functor +/* + find a repetition block +*/ +struct find_decompressF +{ + // Construction + find_decompressF() {} + + // Operation + template + iterator_range operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef ForwardIteratorT input_iterator_type; + typedef typename boost::detail::iterator_traits::value_type value_type; + typedef iterator_range result_type; + + for(input_iterator_type It=Begin; It!=End; It++) + { + if( *It==repeat_mark() ) + { + // Repeat mark found, extract body + input_iterator_type It2=It++; + + if ( It==End ) break; + It++; + if ( It==End ) break; + It++; + + return result_type( It2, It ); + } + } + + return result_type( End, End ); + } +}; + +// rle decompress format +/* + transform a repetition block into a sequence of characters +*/ +template< typename SeqT > +struct format_decompressF +{ +private: + typedef SeqT result_type; + typedef typename SeqT::value_type value_type; + +public: + // Construction + format_decompressF() {}; + + // Operation + template< typename ReplaceT > + result_type operator()( const ReplaceT& Replace ) const + { + // extract info + typename ReplaceT::const_iterator It=Replace.begin(); + + value_type Value=*(++It); + value_type Repeat=*(++It); + + SeqT r; + for( value_type Index=0; Index() ); + + cout << "Compressed string: " << compress << endl; + + // Copy decompression + string decompress=find_format_all_copy( + compress, + find_decompressF(), + format_decompressF() ); + + cout << "Decompressed string: " << decompress << endl; + + // in-place compression + find_format_all( + original, + find_compressF(), + format_compressF() ); + + cout << "Compressed string: " << original << endl; + + // in-place decompression + find_format_all( + original, + find_decompressF(), + format_decompressF() ); + + cout << "Decompressed string: " << original << endl; + + cout << endl; + + return 0; +} diff --git a/string/example/split_example.cpp b/string/example/split_example.cpp new file mode 100644 index 0000000..ea4f25b --- /dev/null +++ b/string/example/split_example.cpp @@ -0,0 +1,63 @@ +// Boost string_algo library example file ---------------------------------// + +// Copyright Pavol Droba 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace boost; + +int main() +{ + cout << "* Split Example *" << endl << endl; + + string str1("abc-*-ABC-*-aBc"); + + cout << "Before: " << str1 << endl; + + // Find all 'abc' substrings (ignoring the case) + // Create a find_iterator + typedef find_iterator string_find_iterator; + for(string_find_iterator It= + make_find_iterator(str1, first_finder("abc", is_iequal())); + It!=string_find_iterator(); + ++It) + { + cout << copy_iterator_range(*It) << endl; + // shift all chars in the match by one + transform( + It->begin(), It->end(), + It->begin(), + bind2nd( plus(), 1 ) ); + } + + // Print the string now + cout << "After: " << str1 << endl; + + // Split the string into tokens ( use '-' and '*' as delimiters ) + // We need copies of the input only, and adjacent tokens are compressed + vector ResultCopy; + split(ResultCopy, str1, is_any_of("-*"), token_compress_on); + + for(unsigned int nIndex=0; nIndex +#include +#include +#include + +using namespace std; +using namespace boost; + +int main() +{ + cout << "* Trim Example *" << endl << endl; + + string str1(" 1x x x x1 "); + string str2("<>trim<>"); + string str3("123abs343"); + + // Simple left trim + cout << "trim_left copy of str1: " << "\"" << trim_left_copy( str1 ) << "\"" << endl; + + // Inplace right trim + trim_right( str1 ); + cout << "trim_right on str1: " << "\"" << str1 << "\"" << endl; + + // Parametric trim. 'Space' is defined using is_any_of predicate + cout + << "trimmed copy of str4 ( space='<>' ): " + << "\""<< trim_copy_if( str2, is_any_of("<>") ) << "\"" << endl; + + + // Parametric trim. 'Space' is defined using is_digit predicate + cout + << "trimmed copy of str5 ( space=digit ): " + << "\"" << trim_copy_if( str3, is_digit() ) << "\"" << endl; + + cout << endl; + + return 0; +} diff --git a/string/test/Jamfile b/string/test/Jamfile new file mode 100644 index 0000000..65572a7 --- /dev/null +++ b/string/test/Jamfile @@ -0,0 +1,68 @@ +# Boost string_algo library test suite Jamfile ---------------------------- +# +# Copyright Pavol Droba 2002-2003. Use, modification and +# distribution is subject to the Boost Software License, Version +# 1.0. (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +# +# See http://www.boost.org for updates, documentation, and revision history. + +subproject libs/algorithm/string/test ; + +# bring in rules for testing +SEARCH on testing.jam = $(BOOST_BUILD_PATH) ; +include testing.jam ; + +test-suite "string_algo" + : [ run + container_test.cpp + : : + : + : container + ] + : [ run + trim_test.cpp + : : + : + : trim + ] + : [ run + conv_test.cpp + : : + : + : conv + ] + : [ run + predicate_test.cpp + : : + : + : predicate + ] + : [ run + find_test.cpp + : : + : + : find + ] + : [ run + split_test.cpp + : : + : + : split + ] + : [ run + replace_test.cpp + : : + : + : replace + ] + : [ run + regex_test.cpp + ../../../regex/build/boost_regex + : : + : + : regex + ] + + ; + diff --git a/string/test/container_test.cpp b/string/test/container_test.cpp new file mode 100644 index 0000000..97561e8 --- /dev/null +++ b/string/test/container_test.cpp @@ -0,0 +1,127 @@ +// 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 unit test framework +#include + +#include +#include +#include + +#include +#include + +// equals predicate is used for result comparison +#include + +// test tools +#include + + +using namespace std; +using namespace boost; + +namespace algo = ::boost::algorithm; + +template< typename T > +void argument_cv_test( const T& C, const string& strResult ) +{ + BOOST_CHECK( equals( make_iterator_range(algo::begin(C),algo::end(C)), strResult ) ); + BOOST_CHECK( algo::size(C)==strResult.size() ); + BOOST_CHECK( algo::empty(C)==strResult.empty() ); +} + +template< typename T > +void argument_test( T& C, const string& strResult ) +{ + BOOST_CHECK( equals( make_iterator_range(algo::begin(C),algo::end(C)), strResult ) ); + BOOST_CHECK( algo::size(C)==strResult.size() ); + BOOST_CHECK( algo::empty(C)==strResult.empty() ); +} + +void container_test() +{ + BOOST_CHECKPOINT( "type test" ); + + // types test + BOOST_REQUIRE( (is_same< + algo::result_iterator_of::type, + string::iterator>::value) ); + BOOST_REQUIRE( (is_same< + algo::result_iterator_of::type, + string::const_iterator>::value) ); + BOOST_REQUIRE( (is_same< + algo::result_iterator_of::type, char*>::value) ); + BOOST_REQUIRE( (is_same< + algo::result_iterator_of::type, + const char*>::value) ); + BOOST_REQUIRE( (is_same< + algo::result_iterator_of::type, char*>::value) ); + BOOST_REQUIRE( (is_same< + algo::result_iterator_of::type, + const char*>::value) ); + BOOST_REQUIRE( (is_same< + algo::result_iterator_of< + pair >::type, string::iterator>::value) ); + BOOST_REQUIRE( (is_same< + algo::result_iterator_of< + const pair >::type, + string::iterator>::value) ); + + BOOST_CHECKPOINT( "non-empty sequence test" ); + + string str1("abc"); + vector vec1( str1.begin(), str1.end() ); + pair pair1= + make_pair( str1.begin(), str1.end() ); + char ach1[]="abc"; + char *pch1="abc"; + + // begin/end tests + argument_cv_test( str1, "abc" ); + argument_test( str1, "abc" ); + argument_cv_test( vec1, "abc" ); + argument_test( vec1, "abc" ); + argument_cv_test( pair1, "abc" ); + argument_test( pair1, "abc" ); + argument_cv_test( ach1, "abc" ); + argument_test( ach1, "abc" ); + argument_cv_test( pch1, "abc" ); + argument_test( pch1, "abc" ); + + BOOST_CHECKPOINT( "empty sequence test" ); + + string str2; + vector vec2( str2.begin(), str2.end() ); + pair pair2= + make_pair( str2.begin(), str2.end() ); + char ach2[]=""; + char *pch2=0; + + // begin/end tests + argument_cv_test( str2, "" ); + argument_test( str2, "" ); + argument_cv_test( vec2, "" ); + argument_test( vec2, "" ); + argument_cv_test( pair2, "" ); + argument_test( pair2, "" ); + argument_cv_test( ach2, "" ); + argument_test( ach2, "" ); + argument_cv_test( pch2, "" ); + argument_test( pch2, "" ); +}; + + +// test main +int test_main( int, char*[] ) +{ + container_test(); + + return 0; +} diff --git a/string/test/conv_test.cpp b/string/test/conv_test.cpp new file mode 100644 index 0000000..d961132 --- /dev/null +++ b/string/test/conv_test.cpp @@ -0,0 +1,88 @@ +// 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 unit test framework +#include + +#include +#include +#include +#include + +using namespace std; +using namespace boost; + +void conv_test() +{ + string str1("AbCdEfG 123 xxxYYYzZzZ"); + string str2("AbCdEfG 123 xxxYYYzZzZ"); + string str3(""); + char* pch1=strdup("AbCdEfG 123 xxxYYYzZzZ"); + char* pch2=strdup("AbCdEfG 123 xxxYYYzZzZ"); + + // *** 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=="" ); + + free(pch1); + free(pch2); +} + +// test main +int test_main( int, char*[] ) +{ + conv_test(); + + return 0; +} diff --git a/string/test/find_test.cpp b/string/test/find_test.cpp new file mode 100644 index 0000000..c1b8baa --- /dev/null +++ b/string/test/find_test.cpp @@ -0,0 +1,230 @@ +// 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 unit test framework +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace boost; + +void find_test() +{ + string str1("123abcxXxabcXxXabc321"); + string str2("abc"); + string str3(""); + char* pch1="123abcxxxabcXXXabc321"; + vector vec1( str1.begin(), str1.end() ); + + // find results ------------------------------------------------------------// + iterator_range nc_result; + iterator_range cv_result; + + iterator_range::iterator> nc_vresult; + iterator_range::const_iterator> cv_vresult; + + iterator_range ch_result; + + // basic tests ------------------------------------------------------------// + + + // find_first + BOOST_CHECKPOINT( "find_first" ); + + nc_result=find_first( str1, string("abc") ); + BOOST_CHECK( + (distance( str1.begin(),nc_result.begin()) == 3) && + (distance( str1.begin(),nc_result.end()) == 6) ); + + cv_result=find_first( const_cast(str1), str2 ); + BOOST_CHECK( + (distance( str1.begin(),cv_result.begin()) == 3) && + (distance( str1.begin(),cv_result.end()) == 6) ); + + cv_result=ifind_first( const_cast(str1), "xXX" ); + BOOST_CHECK( + (distance( str1.begin(),cv_result.begin()) == 6) && + (distance( str1.begin(),cv_result.end()) == 9) ); + + ch_result=find_first( pch1, "abc" ); + BOOST_CHECK(( (ch_result.begin() - pch1 ) == 3) && ( (ch_result.end() - pch1 ) == 6 ) ); + + // find_last + BOOST_CHECKPOINT( "find_last" ); + + nc_result=find_last( str1, string("abc") ); + BOOST_CHECK( + (distance( str1.begin(),nc_result.begin()) == 15) && + (distance( str1.begin(),nc_result.end()) == 18) ); + + cv_result=find_last( const_cast(str1), str2 ); + BOOST_CHECK( + (distance( str1.begin(),cv_result.begin()) == 15) && + (distance( str1.begin(),cv_result.end()) == 18) ); + + cv_result=ifind_last( const_cast(str1), "XXx" ); + BOOST_CHECK( + (distance( str1.begin(),cv_result.begin()) == 12) && + (distance( str1.begin(),cv_result.end()) == 15) ); + + ch_result=find_last( pch1, "abc" ); + BOOST_CHECK(( (ch_result.begin() - pch1 ) == 15) && ( (ch_result.end() - pch1 ) == 18 ) ); + + // find_nth + BOOST_CHECKPOINT( "find_nth" ); + + nc_result=find_nth( str1, string("abc"), 1 ); + BOOST_CHECK( + (distance( str1.begin(),nc_result.begin()) == 9) && + (distance( str1.begin(),nc_result.end()) == 12) ); + + cv_result=find_nth( const_cast(str1), str2, 1 ); + BOOST_CHECK( + (distance( str1.begin(),cv_result.begin()) == 9) && + (distance( str1.begin(),cv_result.end()) == 12) ); + + cv_result=ifind_nth( const_cast(str1), "xxx", 1 ); + BOOST_CHECK( + (distance( str1.begin(),cv_result.begin()) == 12) && + (distance( str1.begin(),cv_result.end()) == 15) ); + + ch_result=find_nth( pch1, "abc", 1 ); + BOOST_CHECK(( (ch_result.begin() - pch1 ) == 9) && ( (ch_result.end() - pch1 ) == 12 ) ); + + // find_head + BOOST_CHECKPOINT( "find_head" ); + + nc_result=find_head( str1, 6 ); + BOOST_CHECK( + (distance( str1.begin(),nc_result.begin()) == 0) && + (distance( str1.begin(),nc_result.end()) == 6) ); + + cv_result=find_head( const_cast(str1), 6 ); + BOOST_CHECK( + (distance( str1.begin(),cv_result.begin()) == 0) && + (distance( str1.begin(),cv_result.end()) == 6) ); + + ch_result=find_head( pch1, 6 ); + BOOST_CHECK( ( (ch_result.begin() - pch1 ) == 0 ) && ( (ch_result.end() - pch1 ) == 6 ) ); + + // find_tail + BOOST_CHECKPOINT( "find_tail" ); + + nc_result=find_tail( str1, 6 ); + BOOST_CHECK( + (distance( str1.begin(),nc_result.begin()) == 15) && + (distance( str1.begin(),nc_result.end()) == 21) ); + + cv_result=find_tail( const_cast(str1), 6 ); + BOOST_CHECK( + (distance( str1.begin(),cv_result.begin()) == 15) && + (distance( str1.begin(),cv_result.end()) == 21) ); + + ch_result=find_tail( pch1, 6 ); + BOOST_CHECK( ( (ch_result.begin() - pch1 ) == 15 ) && ( (ch_result.end() - pch1 ) == 21 ) ); + + // find_token + BOOST_CHECKPOINT( "find_token" ); + + nc_result=find_token( str1, is_any_of("abc"), token_compress_on ); + BOOST_CHECK( + (distance( str1.begin(),nc_result.begin()) == 3) && + (distance( str1.begin(),nc_result.end()) == 6) ); + + cv_result=find_token( const_cast(str1), is_any_of("abc"), token_compress_on ); + BOOST_CHECK( + (distance( str1.begin(),cv_result.begin()) == 3) && + (distance( str1.begin(),cv_result.end()) == 6) ); + + nc_result=find_token( str1, is_any_of("abc"), token_compress_off ); + BOOST_CHECK( + (distance( str1.begin(),nc_result.begin()) == 3) && + (distance( str1.begin(),nc_result.end()) == 4) ); + + cv_result=find_token( const_cast(str1), is_any_of("abc"), token_compress_off ); + BOOST_CHECK( + (distance( str1.begin(),cv_result.begin()) == 3) && + (distance( str1.begin(),cv_result.end()) == 4) ); + + ch_result=find_token( pch1, is_any_of("abc"), token_compress_off ); + BOOST_CHECK( ( (ch_result.begin() - pch1 ) == 3 ) && ( (ch_result.end() - pch1 ) == 4 ) ); + + // generic find + BOOST_CHECKPOINT( "generic find" ); + + nc_result=find(str1, first_finder(string("abc"))); + BOOST_CHECK( + (distance( str1.begin(),nc_result.begin()) == 3) && + (distance( str1.begin(),nc_result.end()) == 6) ); + + cv_result=find(const_cast(str1), first_finder(str2) ); + BOOST_CHECK( + (distance( str1.begin(),cv_result.begin()) == 3) && + (distance( str1.begin(),cv_result.end()) == 6) ); + + // multi-type comparison test + BOOST_CHECKPOINT( "multi-type" ); + + nc_vresult=find_first( vec1, string("abc") ); + BOOST_CHECK( + (distance::const_iterator>( vec1.begin(),nc_vresult.begin()) == 3) && + (distance::const_iterator>( vec1.begin(),nc_vresult.end()) == 6) ); + + cv_vresult=find_first( const_cast&>(vec1), str2 ); + BOOST_CHECK( + (distance::const_iterator>( vec1.begin(),cv_vresult.begin()) == 3) && + (distance::const_iterator>( vec1.begin(),cv_vresult.end()) == 6) ); + + // overflow test + BOOST_CHECKPOINT( "overflow" ); + + nc_result=find_first( str2, string("abcd") ); + BOOST_CHECK( nc_result.begin()==nc_result.end() ); + cv_result=find_first( const_cast(str2), string("abcd") ); + BOOST_CHECK( cv_result.begin()==cv_result.end() ); + + cv_result=find_head( const_cast(str2), 4 ); + BOOST_CHECK( string( cv_result.begin(), cv_result.end() )== string("abc") ); + cv_result=find_tail( const_cast(str2), 4 ); + BOOST_CHECK( string( cv_result.begin(), cv_result.end() )== string("abc") ); + + // Empty string test + BOOST_CHECKPOINT( "empty" ); + + nc_result=find_first( str3, string("abcd") ); + BOOST_CHECK( nc_result.begin()==nc_result.end() ); + nc_result=find_first( str1, string("") ); + BOOST_CHECK( nc_result.begin()==nc_result.end() ); + + cv_result=find_first( const_cast(str3), string("abcd") ); + BOOST_CHECK( cv_result.begin()==cv_result.end() ); + cv_result=find_first( const_cast(str1), string("") ); + BOOST_CHECK( cv_result.begin()==cv_result.end() ); + + // iterator_range specific tests + ostringstream osstr; + osstr << find_first( str1, "abc" ); + BOOST_CHECK( osstr.str()=="abc" ); +} + +// test main +int test_main( int, char*[] ) +{ + find_test(); + + return 0; +} diff --git a/string/test/predicate_test.cpp b/string/test/predicate_test.cpp new file mode 100644 index 0000000..378349a --- /dev/null +++ b/string/test/predicate_test.cpp @@ -0,0 +1,125 @@ +// 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 unit test framework +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace boost; + +void predicate_test() +{ + string str1("123xxx321"); + string str1_prefix("123"); + string str2("abc"); + string str3(""); + string str4("abc"); + vector vec1( str1.begin(), str1.end() ); + + // Basic tests + BOOST_CHECK( starts_with( str1, string("123") ) ); + BOOST_CHECK( !starts_with( str1, string("1234") ) ); + + BOOST_CHECK( istarts_with( "aBCxxx", "abc" ) ); + BOOST_CHECK( !istarts_with( "aBCxxx", "abcd" ) ); + + BOOST_CHECK( ends_with( str1, string("321") ) ); + BOOST_CHECK( !ends_with( str1, string("123") ) ); + + BOOST_CHECK( iends_with( "aBCxXx", "XXX" ) ); + BOOST_CHECK( !iends_with( "aBCxxX", "xXXX" ) ); + + BOOST_CHECK( contains( str1, string("xxx") ) ); + BOOST_CHECK( !contains( str1, string("yyy") ) ); + + BOOST_CHECK( icontains( "123XxX321", "xxx" ) ); + BOOST_CHECK( !icontains( "123xXx321", "yyy" ) ); + + BOOST_CHECK( equals( str2, string("abc") ) ); + BOOST_CHECK( !equals( str1, string("yyy") ) ); + + BOOST_CHECK( iequals( "AbC", "abc" ) ); + BOOST_CHECK( !iequals( "aBc", "yyy" ) ); + + // multi-type comparison test + BOOST_CHECK( starts_with( vec1, string("123") ) ); + BOOST_CHECK( ends_with( vec1, string("321") ) ); + BOOST_CHECK( contains( vec1, string("xxx") ) ); + BOOST_CHECK( equals( vec1, str1 ) ); + + // overflow test + BOOST_CHECK( !starts_with( str2, string("abcd") ) ); + BOOST_CHECK( !ends_with( str2, string("abcd") ) ); + BOOST_CHECK( !contains( str2, string("abcd") ) ); + BOOST_CHECK( !equals( str2, string("abcd") ) ); + + // equal test + BOOST_CHECK( starts_with( str2, string("abc") ) ); + BOOST_CHECK( ends_with( str2, string("abc") ) ); + BOOST_CHECK( contains( str2, string("abc") ) ); + BOOST_CHECK( equals( str2, string("abc") ) ); + + //! Empty string test + BOOST_CHECK( starts_with( str2, string("") ) ); + BOOST_CHECK( ends_with( str2, string("") ) ); + BOOST_CHECK( contains( str2, string("") ) ); + BOOST_CHECK( equals( str3, string("") ) ); + + //! Container compatibility test + BOOST_CHECK( starts_with( "123xxx321", "123" ) ); + BOOST_CHECK( ends_with( "123xxx321", "321" ) ); + BOOST_CHECK( contains( "123xxx321", "xxx" ) ); + BOOST_CHECK( equals( "123xxx321", "123xxx321" ) ); +} + +#define TEST_CLASS( Pred, YesInput, NoInput )\ +{\ + BOOST_CHECK( all( string(YesInput), Pred ) );\ + BOOST_CHECK( !all( string(NoInput), Pred ) );\ +} + +void classification_test() +{ + TEST_CLASS( is_space(), "\n\r\t ", "..." ); + TEST_CLASS( is_alnum(), "ab129ABc", "_ab129ABc" ); + TEST_CLASS( is_alpha(), "abc", "abc1" ); + TEST_CLASS( is_cntrl(), "\n\t\r", "..." ); + TEST_CLASS( is_digit(), "1234567890", "abc" ); + TEST_CLASS( is_graph(), "123abc.,", " \t" ); + TEST_CLASS( is_lower(), "abc", "Aasdf" ); + TEST_CLASS( is_print(), "abs", "\nasdf" ); + TEST_CLASS( is_punct(), ".,;\"", "abc" ); + TEST_CLASS( is_upper(), "ABC", "aBc" ); + TEST_CLASS( is_xdigit(), "ABC123", "XFD" ); + TEST_CLASS( is_any_of( string("abc") ), "aaabbcc", "aaxb" ); + TEST_CLASS( is_any_of( "abc" ), "aaabbcc", "aaxb" ); + TEST_CLASS( is_from_range( 'a', 'c' ), "aaabbcc", "aaxb" ); + + TEST_CLASS( !is_classified(std::ctype_base::space), "...", "..\n\r\t " ); + TEST_CLASS( ( !is_any_of("abc") && is_from_range('a','e') ) || is_space(), "d e", "abcde" ); +} + +#undef TEST_CLASS + +// test main +int test_main( int, char*[] ) +{ + predicate_test(); + classification_test(); + + return 0; +} diff --git a/string/test/regex_test.cpp b/string/test/regex_test.cpp new file mode 100644 index 0000000..407eeaa --- /dev/null +++ b/string/test/regex_test.cpp @@ -0,0 +1,135 @@ +// 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 unit test framework +#include + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace boost; + +static void find_test() +{ + string str1("123a1cxxxa23cXXXa456c321"); + char* pch1="123a1cxxxa23cXXXa456c321"; + regex rx("a[0-9]+c"); + vector vec1( str1.begin(), str1.end() ); + vector tokens; + + // find results + iterator_range nc_result; + iterator_range cv_result; + + iterator_range::iterator> nc_vresult; + iterator_range::const_iterator> cv_vresult; + + iterator_range ch_result; + + // basic tests + nc_result=find_regex( str1, rx ); + BOOST_CHECK( + (distance( str1.begin(),nc_result.begin()) == 3) && + (distance( str1.begin(),nc_result.end()) == 6) ); + + cv_result=find_regex( str1, rx ); + BOOST_CHECK( + (distance( str1.begin(),cv_result.begin()) == 3) && + (distance( str1.begin(),cv_result.end()) == 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( + (distance::const_iterator>( vec1.begin(),nc_vresult.begin()) == 3) && + (distance::const_iterator>( vec1.begin(),nc_vresult.end()) == 6) ); + + cv_vresult=find_regex( vec1, rx ); + BOOST_CHECK( + (distance::const_iterator>( vec1.begin(),cv_vresult.begin()) == 3) && + (distance::const_iterator>( vec1.begin(),cv_vresult.end()) == 6) ); +*/ + // find_all_regex test + find_all_regex( tokens, str1, rx ); + + BOOST_REQUIRE( tokens.size()==3 ); + BOOST_CHECK( tokens[0]==string("a1c") ); + BOOST_CHECK( tokens[1]==string("a23c") ); + BOOST_CHECK( tokens[2]==string("a456c") ); + + // split_regex test + split_regex( tokens, str1, rx ); + + BOOST_REQUIRE( tokens.size()==4 ); + BOOST_CHECK( tokens[0]==string("123") ); + BOOST_CHECK( tokens[1]==string("xxx") ); + BOOST_CHECK( tokens[2]==string("XXX") ); + BOOST_CHECK( tokens[3]==string("321") ); + +} + +static void replace_test() +{ + string str1("123a1cxxxa23cXXXa456c321"); + regex rx1("a([0-9]+)c"); + regex rx2("([xX]+)"); + regex rx3("_[^_]*_"); + string fmt1("_A$1C_"); + string fmt2("_xXx_"); + vector vec1( str1.begin(), str1.end() ); + + // inmutable tests + + // basic tests + BOOST_CHECK( replace_regex_copy( str1, rx1, fmt1 )==string("123_A1C_xxxa23cXXXa456c321") ); + BOOST_CHECK( replace_all_regex_copy( str1, rx1, fmt1 )==string("123_A1C_xxx_A23C_XXX_A456C_321") ); + BOOST_CHECK( erase_regex_copy( str1, rx1 )==string("123xxxa23cXXXa456c321") ); + BOOST_CHECK( erase_all_regex_copy( str1, rx1 )==string(string("123xxxXXX321")) ); + + // output iterator variants test + string strout; + replace_regex_copy( back_inserter(strout), str1, rx1, fmt1 ); + BOOST_CHECK( strout==string("123_A1C_xxxa23cXXXa456c321") ); + strout.clear(); + replace_all_regex_copy( back_inserter(strout), str1, rx1, fmt1 ); + BOOST_CHECK( strout==string("123_A1C_xxx_A23C_XXX_A456C_321") ); + strout.clear(); + erase_regex_copy( back_inserter(strout), str1, rx1 ); + BOOST_CHECK( strout==string("123xxxa23cXXXa456c321") ); + strout.clear(); + erase_all_regex_copy( back_inserter(strout), str1, rx1 ); + BOOST_CHECK( strout==string("123xxxXXX321") ); + strout.clear(); + + // in-place test + replace_regex( str1, rx1, fmt2 ); + BOOST_CHECK( str1==string("123_xXx_xxxa23cXXXa456c321") ); + + replace_all_regex( str1, rx2, fmt1 ); + BOOST_CHECK( str1==string("123__AxXxC___AxxxC_a23c_AXXXC_a456c321") ); + erase_regex( str1, rx3 ); + BOOST_CHECK( str1==string("123AxXxC___AxxxC_a23c_AXXXC_a456c321") ); + erase_all_regex( str1, rx3 ); + BOOST_CHECK( str1==string("123AxXxCa23ca456c321") ); +} + +int test_main( int, char*[] ) +{ + find_test(); + replace_test(); + + return 0; +} diff --git a/string/test/replace_test.cpp b/string/test/replace_test.cpp new file mode 100644 index 0000000..0877bca --- /dev/null +++ b/string/test/replace_test.cpp @@ -0,0 +1,247 @@ +// 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 unit test framework +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +// equals predicate is used for result comparison +#include + +#include +#include + +using namespace std; +using namespace boost; + +void sequence_traits_test() +{ + // basic_string traits + BOOST_CHECK( boost::algorithm::has_native_replace::value ); + BOOST_CHECK( !boost::algorithm::has_stable_iterators::value ); + BOOST_CHECK( !boost::algorithm::has_const_time_insert::value ); + BOOST_CHECK( !boost::algorithm::has_const_time_erase::value ); + + // vector traits + BOOST_CHECK( !boost::algorithm::has_native_replace< vector >::value ); + BOOST_CHECK( !boost::algorithm::has_stable_iterators< vector >::value ); + BOOST_CHECK( !boost::algorithm::has_const_time_insert< vector >::value ); + BOOST_CHECK( !boost::algorithm::has_const_time_erase< vector >::value ); + + // list traits + BOOST_CHECK( !boost::algorithm::has_native_replace< list >::value ); + BOOST_CHECK( boost::algorithm::has_stable_iterators< list >::value ); + BOOST_CHECK( boost::algorithm::has_const_time_insert< list >::value ); + BOOST_CHECK( boost::algorithm::has_const_time_erase< list >::value ); +} + +// Combine tests for all variants of the algorithm +#define TEST_ALGO( Algo, Input, Params, Output ) \ +{\ + BOOST_CHECKPOINT( #Input );\ +\ + string str1(Input);\ +\ + /* Copy test */ \ + BOOST_CHECK( Algo##_copy( str1, BOOST_PP_SEQ_ENUM( Params ) )==Output );\ +\ + /* Iterator test */\ + string strout;\ + Algo##_copy( back_inserter(strout), str1, BOOST_PP_SEQ_ENUM( Params ) );\ + BOOST_CHECK( strout==Output ); \ +\ + /* In-place test */\ + vector vec1( str1.begin(), str1.end() );\ + list list1( str1.begin(), str1.end() );\ + Algo( str1, BOOST_PP_SEQ_ENUM( Params ) ); \ + BOOST_CHECK( equals( str1, Output ) );\ + Algo( vec1, BOOST_PP_SEQ_ENUM( Params ) ); \ + BOOST_CHECK( equals( vec1, Output ) );\ + Algo( list1, BOOST_PP_SEQ_ENUM( Params ) ); \ + BOOST_CHECK( equals( list1, Output ) );\ +} + +void replace_test() +{ + // replace first + TEST_ALGO( replace_first, "1abc3abc2", (string("abc"))(string("YYY")), string("1YYY3abc2") ); + TEST_ALGO( ireplace_first, "1AbC3abc2", ("aBc")("YYY"), string("1YYY3abc2") ); + TEST_ALGO( replace_first, "1abc3abc2", (string("abc"))(string("Z")), string("1Z3abc2") ); + TEST_ALGO( replace_first, "1abc3abc2", (string("abc"))(string("XXXX")), string("1XXXX3abc2") ); + TEST_ALGO( replace_first, "1abc3abc2", (string(""))(string("XXXX")), string("1abc3abc2") ); + TEST_ALGO( replace_first, "1abc3abc2", ("")("XXXX"), string("1abc3abc2") ); + TEST_ALGO( replace_first, "", (string(""))(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("") ); + + // replace last + TEST_ALGO( replace_last, "1abc3abc2", (string("abc"))(string("YYY")), string("1abc3YYY2") ); + TEST_ALGO( ireplace_last, "1abc3AbC2", ("aBc")("YYY"), string("1abc3YYY2") ); + TEST_ALGO( replace_last, "1abc3abc2", (string("abc"))(string("Z")), string("1abc3Z2") ); + TEST_ALGO( replace_last, "1abc3abc2", (string("abc"))(string("XXXX")), string("1abc3XXXX2") ); + TEST_ALGO( replace_last, "1abc3abc2", ("abc")("XXXX"), string("1abc3XXXX2") ); + TEST_ALGO( replace_last, "", (string(""))(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("") ); + + // replace all + TEST_ALGO( replace_all, "1abc3abc2", (string("abc"))(string("YYY")), string("1YYY3YYY2") ); + TEST_ALGO( ireplace_all, "1aBc3AbC2", ("abC")("YYY"), string("1YYY3YYY2") ); + TEST_ALGO( replace_all, "1abc3abc2", (string("abc"))(string("Z")), string("1Z3Z2") ); + TEST_ALGO( replace_all, "1abc3abc2", (string("abc"))(string("XXXX")), string("1XXXX3XXXX2") ); + TEST_ALGO( replace_all, "1abc3abc2", ("abc")("XXXX"), string("1XXXX3XXXX2") ); + TEST_ALGO( replace_all, "", (string(""))(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("") ); + + // replace nth + TEST_ALGO( replace_nth, "1abc3abc2", (string("abc"))(0)(string("YYY")), string("1YYY3abc2") ); + TEST_ALGO( ireplace_nth, "1AbC3abc2", ("aBc")(0)("YYY"), string("1YYY3abc2") ); + TEST_ALGO( replace_nth, "1abc3abc2", (string("abc"))(0)(string("Z")), string("1Z3abc2") ); + TEST_ALGO( replace_nth, "1abc3abc2", (string("abc"))(0)(string("XXXX")), string("1XXXX3abc2") ); + TEST_ALGO( replace_nth, "1abc3abc2", ("abc")(0)("XXXX"), string("1XXXX3abc2") ); + TEST_ALGO( replace_nth, "1abc3abc2", (string(""))(0)(string("XXXX")), string("1abc3abc2") ); + TEST_ALGO( replace_nth, "", (string(""))(0)(string("XXXX")), string("") ); + TEST_ALGO( erase_nth, "1abc3abc2", (string("abc"))(0), string("13abc2") ); + TEST_ALGO( ierase_nth, "1aBc3aBc2", ("ABC")(0), string("13aBc2") ); + TEST_ALGO( erase_nth, "1abc3abc2", ("abc")(0), string("13abc2") ); + TEST_ALGO( erase_nth, "1abc3abc2", (string(""))(0), string("1abc3abc2") ); + TEST_ALGO( erase_nth, "", (string("abc"))(0), string("") ); + TEST_ALGO( replace_nth, "1abc3abc2", (string("abc"))(1)(string("YYY")), string("1abc3YYY2") ); + TEST_ALGO( replace_nth, "1abc3abc2", (string("abc"))(2)(string("YYY")), string("1abc3abc2") ); + + // replace head + TEST_ALGO( replace_head, "abc3abc2", (3)(string("YYY")), string("YYY3abc2") ); + TEST_ALGO( replace_head, "abc3abc2", (3)("YYY"), string("YYY3abc2") ); + TEST_ALGO( replace_head, "abc", (3)(string("Z")), string("Z") ); + TEST_ALGO( replace_head, "abc", (6)(string("XXXX")), string("XXXX") ); + TEST_ALGO( replace_head, "abc3abc2", (0)(string("XXXX")), string("abc3abc2") ); + TEST_ALGO( replace_head, "", (4)(string("XXXX")), string("") ); + TEST_ALGO( erase_head, "abc3abc2", (3), string("3abc2") ); + TEST_ALGO( erase_head, "abc3abc2", (0), string("abc3abc2") ); + TEST_ALGO( erase_head, "", (4), string("") ); + + // replace tail + TEST_ALGO( replace_tail, "abc3abc", (3)(string("YYY")), string("abc3YYY") ); + TEST_ALGO( replace_tail, "abc3abc", (3)("YYY"), string("abc3YYY") ); + TEST_ALGO( replace_tail, "abc", (3)(string("Z")), string("Z") ); + TEST_ALGO( replace_tail, "abc", (6)(string("XXXX")), string("XXXX") ); + TEST_ALGO( replace_tail, "abc3abc", (0)(string("XXXX")), string("abc3abc") ); + TEST_ALGO( replace_tail, "", (4)(string("XXXX")), string("") ); + TEST_ALGO( erase_tail, "abc3abc", (3), string("abc3") ); + TEST_ALGO( erase_tail, "abc3abc", (0), string("abc3abc") ); + TEST_ALGO( erase_tail, "", (4), string("") ); + + // replace_range + { + BOOST_CHECKPOINT( "replace_range" ); + + string str1("1abc3abc2"); + BOOST_CHECK( + replace_range_copy( + str1, + make_iterator_range(str1.begin()+1, str1.begin()+4), + string("XXX") )==string("1XXX3abc2") ); + + string strout; + replace_range_copy( + back_inserter( strout ), + str1, + make_iterator_range(str1.begin()+1, str1.begin()+4), + string("XXX") ); + BOOST_CHECK( strout==string("1XXX3abc2") ); + + replace_range( + str1, + make_iterator_range(str1.begin()+1, str1.begin()+4), + string("XXX") ); + BOOST_CHECK( str1==string("1XXX3abc2") ); + } + // erase_range + { + BOOST_CHECKPOINT( "erase_range" ); + + string str1("1abc3abc2"); + BOOST_CHECK( + erase_range_copy( + str1, + make_iterator_range(str1.begin()+1, str1.begin()+4))==string("13abc2") ); + + string strout; + erase_range_copy( + back_inserter( strout ), + str1, + make_iterator_range(str1.begin()+1, str1.begin()+4)); + BOOST_CHECK( strout==string("13abc2") ); + + erase_range( + str1, + make_iterator_range(str1.begin()+1, str1.begin()+4)); + BOOST_CHECK( str1==string("13abc2") ); + } + + // container traits complatibility tests + { + string strout; + replace_first_copy( back_inserter(strout), "1abc3abc2", "abc", "YYY" ); + BOOST_CHECK( strout==string("1YYY3abc2") ); + } + { + string strout; + replace_last_copy( back_inserter(strout), "1abc3abc2", "abc", "YYY" ); + BOOST_CHECK( strout==string("1abc3YYY2") ); + } + { + string strout; + replace_all_copy( back_inserter(strout), "1abc3abc2", "abc", "YYY" ); + BOOST_CHECK( strout==string("1YYY3YYY2") ); + } + { + string strout; + replace_nth_copy( back_inserter(strout), "1abc3abc2", "abc", 1, "YYY" ); + BOOST_CHECK( strout==string("1abc3YYY2") ); + } + { + string strout; + replace_head_copy( back_inserter(strout), "abc3abc2", 3 , "YYY" ); + BOOST_CHECK( strout==string("YYY3abc2") ); + } + { + string strout; + replace_tail_copy( back_inserter(strout), "abc3abc", 3 , "YYY" ); + BOOST_CHECK( strout==string("abc3YYY") ); + } +} + +// test main +int test_main( int, char*[] ) +{ + sequence_traits_test(); + replace_test(); + + return 0; +} diff --git a/string/test/split_test.cpp b/string/test/split_test.cpp new file mode 100644 index 0000000..f65310a --- /dev/null +++ b/string/test/split_test.cpp @@ -0,0 +1,123 @@ +// 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 unit test framework +#include + +#include +#include +#include + +#include +#include +#include + +// equals predicate is used for result comparison +#include + + +using namespace std; +using namespace boost; + +template< typename T1, typename T2 > +void deep_compare( const T1& X, const T2& Y ) +{ + BOOST_REQUIRE( X.size() == Y.size() ); + for( unsigned int nIndex=0; nIndex tokens; + vector< vector > vtokens; + + ifind_all( + tokens, + str2, + "xx" ); + + BOOST_REQUIRE( tokens.size()==2 ); + BOOST_CHECK( tokens[0]==string("Xx") ); + BOOST_CHECK( tokens[1]==string("xX") ); + + // find_all tests + 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, + str1, + 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( + tokens, + pch1, + is_any_of("x"), + token_compress_on ); + + BOOST_REQUIRE( tokens.size()==3 ); + BOOST_CHECK( tokens[0]==string("") ); + BOOST_CHECK( tokens[1]==string("-abc--") ); + BOOST_CHECK( tokens[2]==string("-abb") ); + + split( + vtokens, + str1, + is_any_of("x"), + token_compress_on ); + deep_compare( tokens, vtokens ); + + split( + tokens, + str1, + is_punct(), + token_compress_off ); + + BOOST_REQUIRE( tokens.size()==5 ); + BOOST_CHECK( tokens[0]==string("xx") ); + BOOST_CHECK( tokens[1]==string("abc") ); + BOOST_CHECK( tokens[2]==string("") ); + BOOST_CHECK( tokens[3]==string("xx") ); + BOOST_CHECK( tokens[4]==string("abb") ); +} + +// test main +int test_main( int, char*[] ) +{ + iterator_test(); + + return 0; +} diff --git a/string/test/trim_test.cpp b/string/test/trim_test.cpp new file mode 100644 index 0000000..531d48d --- /dev/null +++ b/string/test/trim_test.cpp @@ -0,0 +1,117 @@ +// 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 unit test framework +#include + +#include +#include +#include +#include + +using namespace std; +using namespace boost; + +void trim_test() +{ + string str1(" 1x x x x1 "); + string str2(" 2x x x x2 "); + string str3(" "); + + // *** value passing tests *** // + + // general string test + BOOST_CHECK( trim_left_copy( str1 )=="1x x x x1 " ) ; + BOOST_CHECK( trim_right_copy( str1 )==" 1x x x x1" ) ; + BOOST_CHECK( trim_copy( str1 )=="1x x x x1" ) ; + + // spaces-only string test + BOOST_CHECK( trim_left_copy( str3 )=="" ); + BOOST_CHECK( trim_right_copy( str3 )=="" ); + BOOST_CHECK( trim_copy( str3 )=="" ); + + // empty string check + BOOST_CHECK( trim_left_copy( string("") )=="" ); + BOOST_CHECK( trim_right_copy( string("") )=="" ); + BOOST_CHECK( trim_copy( string("") )=="" ); + + // iterator tests + string str; + trim_left_copy_if( std::back_inserter(str), str1, is_space() ); + BOOST_CHECK( str=="1x x x x1 " ); + + str.clear(); + trim_right_copy_if( std::back_inserter(str), str1, is_space() ); + BOOST_CHECK( str==" 1x x x x1" ); + + str.clear(); + trim_copy_if( std::back_inserter(str), str1, is_space() ); + BOOST_CHECK( str=="1x x x x1" ); + + str.clear(); + trim_left_copy_if( + std::back_inserter(str), + " 1x x x x1 ", + is_space() ); + BOOST_CHECK( str=="1x x x x1 " ); + + str.clear(); + trim_right_copy_if( + std::back_inserter(str), + " 1x x x x1 ", + is_space() ); + BOOST_CHECK( str==" 1x x x x1" ); + + str.clear(); + trim_copy_if( + std::back_inserter(str), + " 1x x x x1 ", + is_space() ); + BOOST_CHECK( str=="1x x x x1" ); + // *** inplace tests *** // + + // general string test + trim_left( str1 ); + BOOST_CHECK( str1=="1x x x x1 " ); + trim_right( str1 ); + BOOST_CHECK( str1=="1x x x x1" ); + trim( str2 ); + BOOST_CHECK( str2=="2x x x x2" ); + + // spaces-only string test + str3 = " "; trim_left( str3 ); + BOOST_CHECK( str3=="" ); + str3 = " "; trim_right( str3 ); + BOOST_CHECK( str3=="" ); + str3 = " "; trim( str3 ); + BOOST_CHECK( str3=="" ); + + // empty string check + str3 = ""; trim_left( str3 ); + BOOST_CHECK( str3=="" ); + str3 = ""; trim_right( str3 ); + BOOST_CHECK( str3=="" ); + str3 = ""; trim( str3 ); + BOOST_CHECK( str3=="" ); + + // *** non-standard predicate tests *** // + BOOST_CHECK( + trim_copy_if( + string("123abc456"), + is_classified(std::ctype_base::digit) )=="abc" ); + BOOST_CHECK( trim_copy_if( string("<>abc<>"), is_any_of( "<<>>" ) )=="abc" ); +} + +// test main +int test_main( int, char*[] ) +{ + trim_test(); + + return 0; +}