code:
//  (C) Copyright Gennadiy Rozental 2001.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief defines singleton class unit_test_log and all manipulators.
/// unit_test_log has output stream like interface. It's implementation is
/// completely hidden with pimple idiom
// ***************************************************************************

#ifndef BOOST_TEST_UNIT_TEST_LOG_HPP_071894GER
#define BOOST_TEST_UNIT_TEST_LOG_HPP_071894GER

// Boost.Test
#include <boost/test/tree/observer.hpp>

#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/log_level.hpp>
#include <boost/test/detail/fwd_decl.hpp>

#include <boost/test/utils/wrap_stringstream.hpp>
#include <boost/test/utils/trivial_singleton.hpp>
#include <boost/test/utils/lazy_ostream.hpp>

// Boost

// STL
#include <iosfwd>   // for std::ostream&

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {
namespace unit_test {

// ************************************************************************** //
// **************                log manipulators              ************** //
// ************************************************************************** //

namespace log {

struct BOOST_TEST_DECL begin {
    begin( const_string fn, std::size_t ln )
    : m_file_name( fn )
    , m_line_num( ln )
    {}

    const_string m_file_name;
    std::size_t m_line_num;
};

struct end {};

} // namespace log

// ************************************************************************** //
// **************             entry_value_collector            ************** //
// ************************************************************************** //

namespace ut_detail {

class BOOST_TEST_DECL entry_value_collector {
public:
    // Constructors
    entry_value_collector() : m_last( true ) {}
    entry_value_collector( entry_value_collector const& rhs ) : m_last( true ) { rhs.m_last = false; }
    ~entry_value_collector();

    // collection interface
    entry_value_collector const& operator<<( lazy_ostream const& ) const;
    entry_value_collector const& operator<<( const_string ) const;

private:
    // Data members
    mutable bool    m_last;
};

} // namespace ut_detail

// ************************************************************************** //
// **************                 unit_test_log                ************** //
// ************************************************************************** //

/// @brief Manages the sets of loggers, their streams and log levels
///
/// The Boost.Test framework allows for having several formatters/loggers at the same time, each of which
/// having their own log level and output stream.
///
/// This class serves the purpose of
/// - exposing an interface to the test framework (as a boost::unit_test::test_observer)
/// - exposing an interface to the testing tools
/// - managing several loggers
///
/// @note Accesses to the functions exposed by this class are made through the singleton
///   @c boost::unit_test::unit_test_log.
///
/// Users/developers willing to implement their own formatter need to:
/// - implement a boost::unit_test::unit_test_log_formatter that will output the desired format
/// - register the formatter during a eg. global fixture using the method @c set_formatter (though the framework singleton).
///
/// @warning this observer has a higher priority than the @ref boost::unit_test::results_collector_t. This means
/// that the various @ref boost::unit_test::test_results associated to each test unit may not be available at the time
/// the @c test_unit_start, @c test_unit_finish ... are called.
///
/// @see
/// - boost::unit_test::test_observer
/// - boost::unit_test::unit_test_log_formatter
class BOOST_TEST_DECL unit_test_log_t : public test_observer, public singleton<unit_test_log_t> {
public:
    // test_observer interface implementation
    virtual void        test_start( counter_t test_cases_amount );
    virtual void        test_finish();
    virtual void        test_aborted();

    virtual void        test_unit_start( test_unit const& );
    virtual void        test_unit_finish( test_unit const&, unsigned long elapsed );
    virtual void        test_unit_skipped( test_unit const&, const_string );
    virtual void        test_unit_aborted( test_unit const& );

    virtual void        exception_caught( execution_exception const& ex );

    virtual int         priority() { return 1; }

    // log configuration methods
    //! Sets the stream for all loggers
    //!
    //! This will override the log sink/stream of all loggers, whether enabled or not.
    void                set_stream( std::ostream& );

    //! Sets the stream for specific logger
    //!
    //! @note Has no effect if the specified format is not found
    //! @par Since Boost 1.62
    void                set_stream( output_format, std::ostream& );

    //! Sets the threshold level for all loggers/formatters.
    //!
    //! This will override the log level of all loggers, whether enabled or not.
    void                set_threshold_level( log_level );

    //! Sets the threshold/log level of a specific format
    //!
    //! @note Has no effect if the specified format is not found
    //! @par Since Boost 1.62
    void                set_threshold_level( output_format, log_level );

    //! Add a format to the set of loggers
    //!
    //! Adding a logger means that the specified logger is enabled. The log level is managed by the formatter itself
    //! and specifies what events are forwarded to the underlying formatter.
    //! @par Since Boost 1.62
    void                add_format( output_format );

    //! Sets the format of the logger
    //!
    //! This will become the only active format of the logs.
    void                set_format( output_format );

    //! Returns the logger instance for a specific format.
    //!
    //! @returns the logger/formatter instance, or @c (unit_test_log_formatter*)0 if the format is not found.
    //! @par Since Boost 1.62
    unit_test_log_formatter* get_formatter( output_format );

    //! Sets the logger instance
    //!
    //! The specified logger becomes the unique active one. The custom log formatter has the
    //! format @c OF_CUSTOM_LOGGER. If such a format exists already, its formatter gets replaced by the one
    //! given in argument.
    //!
    //! The log level and output stream of the new formatter are taken from the currently active logger. In case
    //! several loggers are active, the order of priority is CUSTOM, HRF, XML, and JUNIT.
    //! If (unit_test_log_formatter*)0 is given as argument, the custom logger (if any) is removed.
    //!
    //! @note The ownership of the pointer is transfered to the Boost.Test framework. This call is equivalent to
    //! - a call to @c add_formatter
    //! - a call to @c set_format(OF_CUSTOM_LOGGER)
    //! - a configuration of the newly added logger with a previously configured stream and log level.
    void                set_formatter( unit_test_log_formatter* );

    //! Adds a custom log formatter to the set of formatters
    //!
    //! The specified logger is added with the format @c OF_CUSTOM_LOGGER, such that it can
    //! be futher selected or its stream/log level can be specified.
    //! If there is already a custom logger (with @c OF_CUSTOM_LOGGER), then
    //! the existing one gets replaced by the one given in argument.
    //! The provided logger is added with an enabled state.
    //! If (unit_test_log_formatter*)0 is given as argument, the custom logger (if any) is removed and
    //! no other action is performed.
    //!
    //! @note The ownership of the pointer is transfered to the Boost.Test framework.
    //! @par Since Boost 1.62
    void                add_formatter( unit_test_log_formatter* the_formatter );

    // test progress logging
    void                set_checkpoint( const_string file, std::size_t line_num, const_string msg = const_string() );

    // entry logging
    unit_test_log_t&    operator<<( log::begin const& );        // begin entry
    unit_test_log_t&    operator<<( log::end const& );          // end entry
    unit_test_log_t&    operator<<( log_level );                // set entry level
    unit_test_log_t&    operator<<( const_string );             // log entry value
    unit_test_log_t&    operator<<( lazy_ostream const& );      // log entry value

    ut_detail::entry_value_collector operator()( log_level );   // initiate entry collection

private:
    // Implementation helpers
    bool                log_entry_start(output_format log_format);
    void                log_entry_context( log_level l );
    void                clear_entry_context();

    BOOST_TEST_SINGLETON_CONS( unit_test_log_t )
}; // unit_test_log_t

BOOST_TEST_SINGLETON_INST( unit_test_log )

// helper macros
#define BOOST_TEST_LOG_ENTRY( ll )                                                  \
    (::boost::unit_test::unit_test_log                                              \
        << ::boost::unit_test::log::begin( BOOST_TEST_L(__FILE__), __LINE__ ))(ll)  \
/**/

} // namespace unit_test
} // namespace boost

// ************************************************************************** //
// **************       Unit test log interface helpers        ************** //
// ************************************************************************** //

// messages sent by the framework
#define BOOST_TEST_FRAMEWORK_MESSAGE( M )                       \
   (::boost::unit_test::unit_test_log                           \
        << ::boost::unit_test::log::begin(                      \
                "boost.test framework",                         \
                __LINE__ ))                                     \
             ( ::boost::unit_test::log_messages )               \
    << BOOST_TEST_LAZY_MSG( M )                                 \
/**/

#define BOOST_TEST_MESSAGE( M )                                 \
    BOOST_TEST_LOG_ENTRY( ::boost::unit_test::log_messages )    \
    << BOOST_TEST_LAZY_MSG( M )                                 \
/**/

//____________________________________________________________________________//

#define BOOST_TEST_PASSPOINT()                                  \
    ::boost::unit_test::unit_test_log.set_checkpoint(           \
        BOOST_TEST_L(__FILE__),                                 \
        static_cast<std::size_t>(__LINE__) )                    \
/**/

//____________________________________________________________________________//

#define BOOST_TEST_CHECKPOINT( M )                              \
    ::boost::unit_test::unit_test_log.set_checkpoint(           \
        BOOST_TEST_L(__FILE__),                                 \
        static_cast<std::size_t>(__LINE__),                     \
        (::boost::wrap_stringstream().ref() << M).str() )       \
/**/

//____________________________________________________________________________//

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_UNIT_TEST_LOG_HPP_071894GER


code:
//  (C) Copyright Gennadiy Rozental 2001.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief Defines unit test log formatter interface
///
/// You can define a class with implements this interface and use an instance of it
/// as a Unit Test Framework log formatter
// ***************************************************************************

#ifndef BOOST_TEST_UNIT_TEST_LOG_FORMATTER_HPP_071894GER
#define BOOST_TEST_UNIT_TEST_LOG_FORMATTER_HPP_071894GER

// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/log_level.hpp>
#include <boost/test/detail/fwd_decl.hpp>

// STL
#include <iosfwd>
#include <string> // for std::string
#include <iostream>

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {
namespace unit_test {

// ************************************************************************** //
/// Collection of log entry attributes
// ************************************************************************** //

struct BOOST_TEST_DECL log_entry_data {
    log_entry_data()
    {
        m_file_name.reserve( 200 );
    }

    std::string     m_file_name; ///< log entry file name
    std::size_t     m_line_num;  ///< log entry line number
    log_level       m_level;     ///< log entry level

    void clear()
    {
        m_file_name.erase();
        m_line_num      = 0;
        m_level     = log_nothing;
    }
};

// ************************************************************************** //
/// Collection of log checkpoint attributes
// ************************************************************************** //

struct BOOST_TEST_DECL log_checkpoint_data
{
    const_string    m_file_name; ///< log checkpoint file name
    std::size_t     m_line_num;  ///< log checkpoint file name
    std::string     m_message;   ///< log checkpoint message

    void clear()
    {
        m_file_name.clear();
        m_line_num  = 0;
        m_message   = std::string();
    }
};

// ************************************************************************** //
/// @brief Abstract Unit Test Framework log formatter interface
///
/// During the test module execution Unit Test Framework can report messages about success
/// or failure of assertions, which test suites are being run and more (specifically which
/// messages are reported depends on log level threshold selected by the user).
///
/// All these messages constitute Unit Test Framework log. There are many ways (formats) to present
/// these messages to the user.
///
/// Boost.Test comes with three formats:
/// - Compiler-like log format: intended for human consumption/diagnostic
/// - XML based log format:  intended for processing by automated regression test systems.
/// - JUNIT based log format:  intended for processing by automated regression test systems.
///
/// If you want to produce some other format you need to implement class with specific interface and use
/// method @c unit_test_log_t::set_formatter during a test module initialization to set an active formatter.
/// The class unit_test_log_formatter defines this interface.
///
/// This interface requires you to format all possible messages being produced in the log.
/// These includes error messages about failed assertions, messages about caught exceptions and
/// information messages about test units being started/ended. All the methods in this interface takes
/// a reference to standard stream as a first argument. This is where final messages needs to be directed
/// to. Also you are given all the information necessary to produce a message.
///
/// @par Since Boost 1.62:
/// - Each formatter may indicate the default output stream. This is convenient for instance for streams intended
///   for automated processing that indicate a file. See @c get_default_stream_description for more details.
/// - Each formatter may manage its own log level through the getter/setter @c get_log_level and @c set_log_level .
///
/// @see
/// - boost::unit_test::test_observer for an indication of the calls of the test observer interface
class BOOST_TEST_DECL unit_test_log_formatter {
public:
    /// Types of log entries (messages written into a log)
    enum log_entry_types { BOOST_UTL_ET_INFO,       ///< Information message from the framework
                           BOOST_UTL_ET_MESSAGE,    ///< Information message from the user
                           BOOST_UTL_ET_WARNING,    ///< Warning (non error) condition notification message
                           BOOST_UTL_ET_ERROR,      ///< Non fatal error notification message
                           BOOST_UTL_ET_FATAL_ERROR ///< Fatal error notification message
    };

    //! Constructor
    unit_test_log_formatter()
        : m_log_level(log_all_errors)
    {}

    // Destructor
    virtual             ~unit_test_log_formatter() {}

    // @name Test start/finish

    /// Invoked at the beginning of test module execution
    ///
    /// @param[in] os   output stream to write a messages to
    /// @param[in] test_cases_amount total test case amount to be run
    /// @see log_finish
    virtual void        log_start( std::ostream& os, counter_t test_cases_amount ) = 0;

    /// Invoked at the end of test module execution
    ///
    /// @param[in] os   output stream to write a messages into
    /// @see log_start
    virtual void        log_finish( std::ostream& os ) = 0;

    /// Invoked when Unit Test Framework build information is requested
    ///
    /// @param[in] os   output stream to write a messages into
    virtual void        log_build_info( std::ostream& os ) = 0;
    // @}

    // @name Test unit start/finish

    /// Invoked when test unit starts (either test suite or test case)
    ///
    /// @param[in] os   output stream to write a messages into
    /// @param[in] tu   test unit being started
    /// @see test_unit_finish
    virtual void        test_unit_start( std::ostream& os, test_unit const& tu ) = 0;

    /// Invoked when test unit finishes
    ///
    /// @param[in] os   output stream to write a messages into
    /// @param[in] tu   test unit being finished
    /// @param[in] elapsed time in microseconds spend executing this test unit
    /// @see test_unit_start
    virtual void        test_unit_finish( std::ostream& os, test_unit const& tu, unsigned long elapsed ) = 0;

    /// Invoked if test unit skipped for any reason
    ///
    /// @param[in] os   output stream to write a messages into
    /// @param[in] tu   skipped test unit
    /// @param[in] reason explanation why was it skipped
    virtual void        test_unit_skipped( std::ostream& os, test_unit const& tu, const_string /* reason */)
    {
        test_unit_skipped( os, tu );
    }

    /// Deprecated version of this interface
    virtual void        test_unit_skipped( std::ostream& /* os */, test_unit const& /* tu */) {}

    /// Invoked when a test unit is aborted
    virtual void        test_unit_aborted( std::ostream& /* os */, test_unit const& /* tu */) {}

    // @}

    // @name Uncaught exception report

    /// Invoked when Unit Test Framework detects uncaught exception
    ///
    /// The framwork calls this function when an uncaught exception it detected.
    /// This call is followed by context information:
    /// - one call to @c entry_context_start,
    /// - as many calls to @c log_entry_context as there are context entries
    /// - one call to @c entry_context_finish
    ///
    /// The logging of the exception information is finilized by a call to @c log_exception_finish.
    ///
    /// @param[in] os   output stream to write a messages into
    /// @param[in] lcd  information about the last checkpoint before the exception was triggered
    /// @param[in] ex   information about the caught exception
    /// @see log_exception_finish
    virtual void        log_exception_start( std::ostream& os, log_checkpoint_data const& lcd, execution_exception const& ex ) = 0;

    /// Invoked when Unit Test Framework detects uncaught exception
    ///
    /// Call to this function finishes uncaught exception report.
    /// @param[in] os   output stream to write a messages into
    /// @see log_exception_start
    virtual void        log_exception_finish( std::ostream& os ) = 0;
    // @}

    // @name Regular log entry

    /// Invoked by Unit Test Framework to start new log entry

    /// Call to this function starts new log entry. It is followed by series of log_entry_value calls and finally call to log_entry_finish.
    /// A log entry may consist of one or more values being reported. Some of these values will be plain strings, while others can be complicated
    /// expressions in a form of "lazy" expression template lazy_ostream.
    /// @param[in] os   output stream to write a messages into
    /// @param[in] led  log entry attributes
    /// @param[in] let  log entry type log_entry_finish
    /// @see log_entry_value, log_entry_finish
    ///
    /// @note call to this function may happen before any call to test_unit_start or all calls to test_unit_finish as the
    /// framework might log errors raised during global initialization/shutdown.
    virtual void        log_entry_start( std::ostream& os, log_entry_data const& led, log_entry_types let ) = 0;

    /// Invoked by Unit Test Framework to report a log entry content
    ///
    /// This is one of two overloaded methods to report log entry content. This one is used to report plain string value.
    /// @param[in] os   output stream to write a messages into.
    /// @param[in] value log entry string value
    /// @see log_entry_start, log_entry_finish
    virtual void        log_entry_value( std::ostream& os, const_string value ) = 0;

    /// Invoked by Unit Test Framework to report a log entry content

    /// This is one of two overloaded methods to report log entry content. This one is used to report some complicated expression passed as
    /// an expression template lazy_ostream. In most cases default implementation provided by the framework should work as is (it just converts
    /// the lazy expression into a string.
    /// @param[in] os   output stream to write a messages into
    /// @param[in] value log entry "lazy" value
    /// @see log_entry_start, log_entry_finish
    virtual void        log_entry_value( std::ostream& os, lazy_ostream const& value ); // there is a default impl

    /// Invoked by Unit Test Framework to finish a log entry report

    /// @param[in] os   output stream to write a messages into
    /// @see log_entry_start, log_entry_start
    virtual void        log_entry_finish( std::ostream& os ) = 0;
    // @}

    // @name Log entry context report

    /// Invoked by Unit Test Framework to start log entry context report

    /// Unit Test Framework logs for failed assertions and uncaught exceptions context if one was defined by a test module.
    /// Context consists of multiple "scopes" identified by description messages assigned by the test module using
    /// BOOST_TEST_INFO/BOOST_TEST_CONTEXT statements.
    /// @param[in] os   output stream to write a messages into
    /// @param[in] l    entry log_level, to be used to fine tune the message
    /// @see log_entry_context, entry_context_finish
    virtual void        entry_context_start( std::ostream& os, log_level l ) = 0;

    /// Invoked by Unit Test Framework to report log entry context "scope" description

    /// Each "scope" description is reported by separate call to log_entry_context.
    /// @param[in] os   output stream to write a messages into
    /// @param[in] value  context "scope" description
    /// @see log_entry_start, entry_context_finish
    virtual void        log_entry_context( std::ostream& os, const_string value ) = 0;

    /// Invoked by Unit Test Framework to finish log entry context report

    /// @param[in] os   output stream to write a messages into
    /// @see log_entry_start, entry_context_context
    virtual void        entry_context_finish( std::ostream& os ) = 0;
    // @}

    // @name Log level management

    /// Sets the log level of the logger/formatter
    ///
    /// Some loggers need to manage the log level by their own. This
    /// member function let the implementation decide of that.
    /// @par Since Boost 1.62
    virtual void        set_log_level(log_level new_log_level);

    /// Returns the log level of the logger/formatter
    /// @par Since Boost 1.62
    virtual log_level   get_log_level() const;
    // @}

    // @name Stream management

    /// Returns a default stream for this logger.
    ///
    /// The returned string describes the stream as if it was passed from
    /// the command line @c "--log_sink" parameter. With that regards, @b stdout and @b stderr
    /// have special meaning indicating the standard output or error stream respectively.
    ///
    /// @par Since Boost 1.62
    virtual std::string  get_default_stream_description() const
    {
        return "stdout";
    }

    // @}

protected:
    log_level           m_log_level;

};

} // namespace unit_test
} // namespace boost

//____________________________________________________________________________//

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_UNIT_TEST_LOG_FORMATTER_HPP_071894GER

license: mit


code:
//  (C) Copyright Gennadiy Rozental 2001.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief defines specific version of execution monitor used to managed run unit of test cases
///
/// Translates execution exception into error level
// ***************************************************************************

#ifndef BOOST_TEST_UNIT_TEST_MONITOR_HPP_020905GER
#define BOOST_TEST_UNIT_TEST_MONITOR_HPP_020905GER

// Boost.Test
#include <boost/test/execution_monitor.hpp>
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/utils/trivial_singleton.hpp>

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {
namespace unit_test {

// ************************************************************************** //
// **************               unit_test_monitor              ************** //
// ************************************************************************** //

class BOOST_TEST_DECL unit_test_monitor_t : public singleton<unit_test_monitor_t>, public execution_monitor {
public:
    enum error_level {
        test_ok                 =  0,
        precondition_failure    = -1,
        unexpected_exception    = -2,
        os_exception            = -3,
        os_timeout              = -4,
        fatal_error             = -5  // includes both system and user
    };

    static bool is_critical_error( error_level e ) { return e <= fatal_error; }

    // monitor method
    error_level execute_and_translate( boost::function<void ()> const& func, unsigned timeout = 0 );

private:
    BOOST_TEST_SINGLETON_CONS( unit_test_monitor_t )
};

BOOST_TEST_SINGLETON_INST( unit_test_monitor )

} // namespace unit_test
} // namespace boost

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_UNIT_TEST_MONITOR_HPP_020905GER


code:
//  (C) Copyright Gennadiy Rozental 2001.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief Provides access to various Unit Test Framework runtime parameters
///
/// Primarily for use by the framework itself
// ***************************************************************************

#ifndef BOOST_TEST_UNIT_TEST_PARAMETERS_HPP_071894GER
#define BOOST_TEST_UNIT_TEST_PARAMETERS_HPP_071894GER

// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/utils/runtime/argument.hpp>
#include <boost/make_shared.hpp>

// STL
#include <iostream>
#include <fstream>

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {
namespace unit_test {
namespace runtime_config {

// ************************************************************************** //
// **************                 runtime_config               ************** //
// ************************************************************************** //

// UTF parameters
BOOST_TEST_DECL extern std::string AUTO_START_DBG;
BOOST_TEST_DECL extern std::string BREAK_EXEC_PATH;
BOOST_TEST_DECL extern std::string BUILD_INFO;
BOOST_TEST_DECL extern std::string CATCH_SYS_ERRORS;
BOOST_TEST_DECL extern std::string COLOR_OUTPUT;
BOOST_TEST_DECL extern std::string DETECT_FP_EXCEPT;
BOOST_TEST_DECL extern std::string DETECT_MEM_LEAKS;
BOOST_TEST_DECL extern std::string LIST_CONTENT;
BOOST_TEST_DECL extern std::string LIST_LABELS;
BOOST_TEST_DECL extern std::string COMBINED_LOGGER;
BOOST_TEST_DECL extern std::string LOG_FORMAT;
BOOST_TEST_DECL extern std::string LOG_LEVEL;
BOOST_TEST_DECL extern std::string LOG_SINK;
BOOST_TEST_DECL extern std::string OUTPUT_FORMAT;
BOOST_TEST_DECL extern std::string RANDOM_SEED;
BOOST_TEST_DECL extern std::string REPORT_FORMAT;
BOOST_TEST_DECL extern std::string REPORT_LEVEL;
BOOST_TEST_DECL extern std::string REPORT_MEM_LEAKS;
BOOST_TEST_DECL extern std::string REPORT_SINK;
BOOST_TEST_DECL extern std::string RESULT_CODE;
BOOST_TEST_DECL extern std::string RUN_FILTERS;
BOOST_TEST_DECL extern std::string SAVE_TEST_PATTERN;
BOOST_TEST_DECL extern std::string SHOW_PROGRESS;
BOOST_TEST_DECL extern std::string USE_ALT_STACK;
BOOST_TEST_DECL extern std::string WAIT_FOR_DEBUGGER;

BOOST_TEST_DECL void init( int& argc, char** argv );

// ************************************************************************** //
// **************              runtime_param::get              ************** //
// ************************************************************************** //

/// Access to arguments
BOOST_TEST_DECL runtime::arguments_store const& argument_store();

template<typename T>
inline T const&
get( runtime::cstring parameter_name )
{
    return argument_store().get<T>( parameter_name );
}

inline bool has( runtime::cstring parameter_name )
{
    return argument_store().has( parameter_name );
}

/// For public access
BOOST_TEST_DECL bool save_pattern();

// ************************************************************************** //
// **************                  stream_holder               ************** //
// ************************************************************************** //

class stream_holder {
public:
    // Constructor
    explicit        stream_holder( std::ostream& default_stream = std::cout)
    : m_stream( &default_stream )
    {
    }

    void            setup( const const_string& stream_name )
    {
        if(stream_name.empty())
            return;

        if( stream_name == "stderr" )
            m_stream = &std::cerr;
        else if( stream_name == "stdout" )
            m_stream = &std::cout;
        else {
            m_file = boost::make_shared<std::ofstream>();
            m_file->open( std::string(stream_name.begin(), stream_name.end()).c_str() );
            m_stream = m_file.get();
        }
    }

    // Access methods
    std::ostream&   ref() const { return *m_stream; }

private:
    // Data members
    boost::shared_ptr<std::ofstream>   m_file;
    std::ostream*   m_stream;
};

} // namespace runtime_config
} // namespace unit_test
} // namespace boost

//____________________________________________________________________________//

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_UNIT_TEST_PARAMETERS_HPP_071894GER


code:
//  (C) Copyright Gennadiy Rozental 2001.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief Defines Unit Test Framework public API
// ***************************************************************************

#ifndef BOOST_TEST_UNIT_TEST_SUITE_HPP_071894GER
#define BOOST_TEST_UNIT_TEST_SUITE_HPP_071894GER

// Boost.Test
#include <boost/test/framework.hpp>
#include <boost/test/tree/auto_registration.hpp>
#include <boost/test/tree/test_case_template.hpp>
#include <boost/test/tree/global_fixture.hpp>

#include <boost/test/detail/suppress_warnings.hpp>

#include <boost/test/detail/pp_variadic.hpp>

//____________________________________________________________________________//

// ************************************************************************** //
// **************    Non-auto (explicit) test case interface   ************** //
// ************************************************************************** //

#define BOOST_TEST_CASE( test_function )                                   \
boost::unit_test::make_test_case( boost::function<void ()>(test_function), \
                                  BOOST_TEST_STRINGIZE( test_function ),   \
                                  __FILE__, __LINE__ )
#define BOOST_CLASS_TEST_CASE( test_function, tc_instance )                \
boost::unit_test::make_test_case( (test_function),                         \
                                  BOOST_TEST_STRINGIZE( test_function ),   \
                                  __FILE__, __LINE__, tc_instance )

// ************************************************************************** //
// **************               BOOST_TEST_SUITE               ************** //
// ************************************************************************** //

#define BOOST_TEST_SUITE( testsuite_name ) \
( new boost::unit_test::test_suite( testsuite_name, __FILE__, __LINE__ ) )

// ************************************************************************** //
// **************             BOOST_AUTO_TEST_SUITE            ************** //
// ************************************************************************** //

#define BOOST_AUTO_TEST_SUITE_WITH_DECOR( suite_name, decorators )      \
namespace suite_name {                                                  \
BOOST_AUTO_TU_REGISTRAR( suite_name )(                                  \
    BOOST_STRINGIZE( suite_name ),                                      \
    __FILE__, __LINE__,                                                 \
    decorators );                                                       \
/**/

#define BOOST_AUTO_TEST_SUITE_NO_DECOR( suite_name )                    \
    BOOST_AUTO_TEST_SUITE_WITH_DECOR(                                   \
        suite_name,                                                     \
        boost::unit_test::decorator::collector::instance() )            \
/**/

#if BOOST_PP_VARIADICS
#define BOOST_AUTO_TEST_SUITE( ... )                                    \
    BOOST_TEST_INVOKE_IF_N_ARGS( 1,                                     \
        BOOST_AUTO_TEST_SUITE_NO_DECOR,                                 \
        BOOST_AUTO_TEST_SUITE_WITH_DECOR,                               \
        __VA_ARGS__)                                                    \
/**/

#else /* BOOST_PP_VARIADICS */

#define BOOST_AUTO_TEST_SUITE( suite_name )                             \
    BOOST_AUTO_TEST_SUITE_NO_DECOR( suite_name )                        \
/**/

#endif /* BOOST_PP_VARIADICS */

// ************************************************************************** //
// **************            BOOST_FIXTURE_TEST_SUITE          ************** //
// ************************************************************************** //

#define BOOST_FIXTURE_TEST_SUITE_WITH_DECOR(suite_name, F, decorators)  \
    BOOST_AUTO_TEST_SUITE_WITH_DECOR( suite_name, decorators )          \
typedef F BOOST_AUTO_TEST_CASE_FIXTURE;                                 \
/**/

#define BOOST_FIXTURE_TEST_SUITE_NO_DECOR( suite_name, F )              \
    BOOST_AUTO_TEST_SUITE_NO_DECOR( suite_name )                        \
typedef F BOOST_AUTO_TEST_CASE_FIXTURE;                                 \
/**/

#if BOOST_PP_VARIADICS

#define BOOST_FIXTURE_TEST_SUITE( ... )                                 \
    BOOST_TEST_INVOKE_IF_N_ARGS( 2,                                     \
        BOOST_FIXTURE_TEST_SUITE_NO_DECOR,                              \
        BOOST_FIXTURE_TEST_SUITE_WITH_DECOR,                            \
        __VA_ARGS__)                                                    \
/**/

#else /* BOOST_PP_VARIADICS */

#define BOOST_FIXTURE_TEST_SUITE( suite_name, F  )                      \
   BOOST_FIXTURE_TEST_SUITE_NO_DECOR( suite_name, F )                   \
/**/

#endif /* BOOST_PP_VARIADICS */

// ************************************************************************** //
// **************           BOOST_AUTO_TEST_SUITE_END          ************** //
// ************************************************************************** //

#define BOOST_AUTO_TEST_SUITE_END()                                     \
BOOST_AUTO_TU_REGISTRAR( BOOST_JOIN( end_suite, __LINE__ ) )( 1 );      \
}                                                                       \
/**/

// ************************************************************************** //
// **************    BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES    ************** //
// ************************************************************************** //

/// @deprecated use decorator instead
#define BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( test_name, n )          \
BOOST_TEST_DECORATOR( * boost::unit_test::expected_failures( n ) )      \
/**/

// ************************************************************************** //
// **************            BOOST_FIXTURE_TEST_CASE           ************** //
// ************************************************************************** //

#define BOOST_FIXTURE_TEST_CASE_WITH_DECOR( test_name, F, decorators )  \
struct test_name : public F { void test_method(); };                    \
                                                                        \
static void BOOST_AUTO_TC_INVOKER( test_name )()                        \
{                                                                       \
    BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture entry.");    \
    test_name t;                                                        \
    BOOST_TEST_CHECKPOINT('"' << #test_name << "\" entry.");            \
    t.test_method();                                                    \
    BOOST_TEST_CHECKPOINT('"' << #test_name << "\" exit.");             \
}                                                                       \
                                                                        \
struct BOOST_AUTO_TC_UNIQUE_ID( test_name ) {};                         \
                                                                        \
BOOST_AUTO_TU_REGISTRAR( test_name )(                                   \
    boost::unit_test::make_test_case(                                   \
        &BOOST_AUTO_TC_INVOKER( test_name ),                            \
        #test_name, __FILE__, __LINE__ ),                               \
        decorators );                                                   \
                                                                        \
void test_name::test_method()                                           \
/**/

#define BOOST_FIXTURE_TEST_CASE_NO_DECOR( test_name, F )                \
BOOST_FIXTURE_TEST_CASE_WITH_DECOR( test_name, F,                       \
    boost::unit_test::decorator::collector::instance() )                \
/**/

#if BOOST_PP_VARIADICS

#define BOOST_FIXTURE_TEST_CASE( ... )                                  \
    BOOST_TEST_INVOKE_IF_N_ARGS( 2,                                     \
        BOOST_FIXTURE_TEST_CASE_NO_DECOR,                               \
        BOOST_FIXTURE_TEST_CASE_WITH_DECOR,                             \
         __VA_ARGS__)                                                   \
/**/

#else /* BOOST_PP_VARIADICS */

#define BOOST_FIXTURE_TEST_CASE( test_name, F )                         \
     BOOST_FIXTURE_TEST_CASE_NO_DECOR(test_name, F)                     \
/**/

#endif /* BOOST_PP_VARIADICS */

// ************************************************************************** //
// **************             BOOST_AUTO_TEST_CASE             ************** //
// ************************************************************************** //

#define BOOST_AUTO_TEST_CASE_NO_DECOR( test_name )                      \
    BOOST_FIXTURE_TEST_CASE_NO_DECOR( test_name,                        \
        BOOST_AUTO_TEST_CASE_FIXTURE )                                  \
/**/

#define BOOST_AUTO_TEST_CASE_WITH_DECOR( test_name, decorators )        \
    BOOST_FIXTURE_TEST_CASE_WITH_DECOR( test_name,                      \
        BOOST_AUTO_TEST_CASE_FIXTURE, decorators )                      \
/**/

#if BOOST_PP_VARIADICS

#define BOOST_AUTO_TEST_CASE( ... )                                     \
    BOOST_TEST_INVOKE_IF_N_ARGS( 1,                                     \
        BOOST_AUTO_TEST_CASE_NO_DECOR,                                  \
        BOOST_AUTO_TEST_CASE_WITH_DECOR,                                \
         __VA_ARGS__)                                                   \
/**/

#else /* BOOST_PP_VARIADICS */

#define BOOST_AUTO_TEST_CASE( test_name )                               \
    BOOST_AUTO_TEST_CASE_NO_DECOR( test_name )                          \
/**/

#endif /* BOOST_PP_VARIADICS */

// ************************************************************************** //
// **************       BOOST_FIXTURE_TEST_CASE_TEMPLATE       ************** //
// ************************************************************************** //

#define BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_name, type_name, TL, F ) \
template<typename type_name>                                            \
struct test_name : public F                                             \
{ void test_method(); };                                                \
                                                                        \
struct BOOST_AUTO_TC_INVOKER( test_name ) {                             \
    template<typename TestType>                                         \
    static void run( boost::type<TestType>* = 0 )                       \
    {                                                                   \
        BOOST_TEST_CHECKPOINT('"' << #test_name <<"\" fixture entry."); \
        test_name<TestType> t;                                          \
        BOOST_TEST_CHECKPOINT('"' << #test_name << "\" entry.");        \
        t.test_method();                                                \
        BOOST_TEST_CHECKPOINT('"' << #test_name << "\" exit.");         \
    }                                                                   \
};                                                                      \
                                                                        \
BOOST_AUTO_TU_REGISTRAR( test_name )(                                   \
    boost::unit_test::ut_detail::template_test_case_gen<                \
        BOOST_AUTO_TC_INVOKER( test_name ),TL >(                        \
          BOOST_STRINGIZE( test_name ), __FILE__, __LINE__ ),           \
    boost::unit_test::decorator::collector::instance() );               \
                                                                        \
template<typename type_name>                                            \
void test_name<type_name>::test_method()                                \
/**/

// ************************************************************************** //
// **************        BOOST_AUTO_TEST_CASE_TEMPLATE         ************** //
// ************************************************************************** //

#define BOOST_AUTO_TEST_CASE_TEMPLATE( test_name, type_name, TL )       \
BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_name, type_name, TL,             \
    BOOST_AUTO_TEST_CASE_FIXTURE )                                      \
/**/

// ************************************************************************** //
// **************           BOOST_TEST_CASE_TEMPLATE           ************** //
// ************************************************************************** //

#define BOOST_TEST_CASE_TEMPLATE( name, typelist )                      \
    boost::unit_test::ut_detail::template_test_case_gen<name,typelist>( \
        BOOST_TEST_STRINGIZE( name ), __FILE__, __LINE__ )              \
/**/

// ************************************************************************** //
// **************      BOOST_TEST_CASE_TEMPLATE_FUNCTION       ************** //
// ************************************************************************** //

#define BOOST_TEST_CASE_TEMPLATE_FUNCTION( name, type_name )            \
template<typename type_name>                                            \
void BOOST_JOIN( name, _impl )( boost::type<type_name>* );              \
                                                                        \
struct name {                                                           \
    template<typename TestType>                                         \
    static void run( boost::type<TestType>* frwrd = 0 )                 \
    {                                                                   \
       BOOST_JOIN( name, _impl )( frwrd );                              \
    }                                                                   \
};                                                                      \
                                                                        \
template<typename type_name>                                            \
void BOOST_JOIN( name, _impl )( boost::type<type_name>* )               \
/**/

// ************************************************************************** //
// **************              BOOST_GLOBAL_FIXTURE            ************** //
// ************************************************************************** //

#define BOOST_GLOBAL_FIXTURE( F ) \
static boost::unit_test::ut_detail::global_fixture_impl<F> BOOST_JOIN( gf_, F ) \
/**/

// ************************************************************************** //
// **************             BOOST_TEST_DECORATOR             ************** //
// ************************************************************************** //

#define BOOST_TEST_DECORATOR( D )                                       \
static boost::unit_test::decorator::collector const&                    \
BOOST_JOIN(decorator_collector,__LINE__) = D;                           \
/**/

// ************************************************************************** //
// **************         BOOST_AUTO_TEST_CASE_FIXTURE         ************** //
// ************************************************************************** //

namespace boost { namespace unit_test { namespace ut_detail {

struct nil_t {};

} // namespace ut_detail
} // unit_test
} // namespace boost

// Intentionally is in global namespace, so that FIXTURE_TEST_SUITE can reset it in user code.
typedef ::boost::unit_test::ut_detail::nil_t BOOST_AUTO_TEST_CASE_FIXTURE;

// ************************************************************************** //
// **************   Auto registration facility helper macros   ************** //
// ************************************************************************** //

#define BOOST_AUTO_TU_REGISTRAR( test_name )                    \
static boost::unit_test::ut_detail::auto_test_unit_registrar    \
BOOST_JOIN( BOOST_JOIN( test_name, _registrar ), __LINE__ )     \
/**/
#define BOOST_AUTO_TC_INVOKER( test_name )      BOOST_JOIN( test_name, _invoker )
#define BOOST_AUTO_TC_UNIQUE_ID( test_name )    BOOST_JOIN( test_name, _id )

// ************************************************************************** //
// **************                BOOST_TEST_MAIN               ************** //
// ************************************************************************** //

#if defined(BOOST_TEST_MAIN)

#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
bool init_unit_test()                   {
#else
::boost::unit_test::test_suite*
init_unit_test_suite( int, char* [] )   {
#endif

#ifdef BOOST_TEST_MODULE
    using namespace ::boost::unit_test;
    assign_op( framework::master_test_suite().p_name.value, BOOST_TEST_STRINGIZE( BOOST_TEST_MODULE ).trim( "\"" ), 0 );

#endif

#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
    return true;
}
#else
    return 0;
}
#endif

#endif

//____________________________________________________________________________//

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_UNIT_TEST_SUITE_HPP_071894GER


code:
//  (C) Copyright Gennadiy Rozental 2001.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// Addition to STL algorithms
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_ALGORITHM_HPP
#define BOOST_TEST_UTILS_ALGORITHM_HPP

// STL
#include <utility>
#include <algorithm> // std::find
#include <functional> // std::bind1st

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {
namespace unit_test {
namespace utils {

/// @brief this algorithm search through two collections for first mismatch position that get returned as a pair
/// of iterators, first pointing to the mismatch position in first collection, second iterator in second one
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
template <class InputIter1, class InputIter2>
inline std::pair<InputIter1, InputIter2>
mismatch( InputIter1 first1, InputIter1 last1,
          InputIter2 first2, InputIter2 last2 )
{
    while( first1 != last1 && first2 != last2 && *first1 == *first2 ) {
        ++first1;
        ++first2;
    }

    return std::pair<InputIter1, InputIter2>(first1, first2);
}

//____________________________________________________________________________//

/// @brief this algorithm search through two collections for first mismatch position that get returned as a pair
/// of iterators, first pointing to the mismatch position in first collection, second iterator in second one. This algorithms
/// uses supplied predicate for collection elements comparison
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
/// @param pred - predicate to be used for search
template <class InputIter1, class InputIter2, class Predicate>
inline std::pair<InputIter1, InputIter2>
mismatch( InputIter1 first1, InputIter1 last1,
          InputIter2 first2, InputIter2 last2,
          Predicate pred )
{
    while( first1 != last1 && first2 != last2 && pred( *first1, *first2 ) ) {
        ++first1;
        ++first2;
    }

    return std::pair<InputIter1, InputIter2>(first1, first2);
}

//____________________________________________________________________________//

/// @brief this algorithm search through first collection for first element that does not belong a second one
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
template<class ForwardIterator1, class ForwardIterator2>
inline ForwardIterator1
find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
                   ForwardIterator2 first2, ForwardIterator2 last2 )
{
    while( first1 != last1 ) {
        if( std::find( first2, last2, *first1 ) == last2 )
            break;
        ++first1;
    }

    return first1;
}

//____________________________________________________________________________//

/// @brief this algorithm search through first collection for first element that does not satisfy binary
/// predicate in conjunction will any element in second collection
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
/// @param pred - predicate to be used for search
template<class ForwardIterator1, class ForwardIterator2, class Predicate>
inline ForwardIterator1
find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
                   ForwardIterator2 first2, ForwardIterator2 last2,
                   Predicate pred )
{
    while( first1 != last1 ) {
        if( std::find_if( first2, last2, std::bind1st( pred, *first1 ) ) == last2 )
            break;
        ++first1;
    }

    return first1;
}

//____________________________________________________________________________//

/// @brief this algorithm search through first collection for last element that belongs to a second one
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
template<class BidirectionalIterator1, class ForwardIterator2>
inline BidirectionalIterator1
find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
              ForwardIterator2 first2, ForwardIterator2 last2 )
{
    if( first1 == last1 || first2 == last2 )
        return last1;

    BidirectionalIterator1 it1 = last1;
    while( --it1 != first1 && std::find( first2, last2, *it1 ) == last2 ) {}

    return it1 == first1 && std::find( first2, last2, *it1 ) == last2 ? last1 : it1;
}

//____________________________________________________________________________//

/// @brief this algorithm search through first collection for last element that satisfy binary
/// predicate in conjunction will at least one element in second collection
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
/// @param pred - predicate to be used for search
template<class BidirectionalIterator1, class ForwardIterator2, class Predicate>
inline BidirectionalIterator1
find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
              ForwardIterator2 first2, ForwardIterator2 last2,
              Predicate pred )
{
    if( first1 == last1 || first2 == last2 )
        return last1;

    BidirectionalIterator1 it1 = last1;
    while( --it1 != first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) == last2 ) {}

    return it1 == first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) == last2 ? last1 : it1;
}

//____________________________________________________________________________//

/// @brief this algorithm search through first collection for last element that does not belong to a second one
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
template<class BidirectionalIterator1, class ForwardIterator2>
inline BidirectionalIterator1
find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
                  ForwardIterator2 first2, ForwardIterator2 last2 )
{
    if( first1 == last1 || first2 == last2 )
        return last1;

    BidirectionalIterator1 it1 = last1;
    while( --it1 != first1 && std::find( first2, last2, *it1 ) != last2 ) {}

    return it1 == first1 && std::find( first2, last2, *it1 ) != last2 ? last1 : it1;
}

//____________________________________________________________________________//

/// @brief this algorithm search through first collection for last element that does not satisfy binary
/// predicate in conjunction will any element in second collection
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
/// @param pred - predicate to be used for search
template<class BidirectionalIterator1, class ForwardIterator2, class Predicate>
inline BidirectionalIterator1
find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
                  ForwardIterator2 first2, ForwardIterator2 last2,
                  Predicate pred )
{
    if( first1 == last1 || first2 == last2 )
        return last1;

    BidirectionalIterator1 it1 = last1;
    while( --it1 != first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) != last2 ) {}

    return it1 == first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) == last2 ? last1 : it1;
}

//____________________________________________________________________________//

/// @brief This algorithm replaces all occurrences of a set of substrings by another substrings
///
/// @param str - string of operation
/// @param first1 - iterator to the beginning of the substrings to replace
/// @param last1 - iterator to the end of the substrings to replace
/// @param first2 - iterator to the beginning of the substrings to replace with
/// @param last2 - iterator to the end of the substrings to replace with
template<class StringClass, class ForwardIterator>
inline StringClass
replace_all_occurrences_of( StringClass str,
                            ForwardIterator first1, ForwardIterator last1,
                            ForwardIterator first2, ForwardIterator last2)
{
    for(; first1 != last1 && first2 != last2; ++first1, ++first2) {
        std::size_t found = str.find( *first1 );
        while( found != StringClass::npos ) {
            str.replace(found, first1->size(), *first2 );
            found = str.find( *first1, found + first2->size() );
        }
    }

    return str;
}

/// @brief This algorithm replaces all occurrences of a string with basic wildcards
/// with another (optionally containing wildcards as well).
///
/// @param str - string to transform
/// @param it_string_to_find - iterator to the beginning of the substrings to replace
/// @param it_string_to_find_end - iterator to the end of the substrings to replace
/// @param it_string_to_replace - iterator to the beginning of the substrings to replace with
/// @param it_string_to_replace_end - iterator to the end of the substrings to replace with
///
/// The wildcard is the symbol '*'. Only a unique wildcard per string is supported. The replacement
/// string may also contain a wildcard, in which case it is considered as a placeholder to the content
/// of the wildcard in the source string.
/// Example:
/// - In order to replace the occurrences of @c 'time=\"some-variable-value\"' to a constant string,
///   one may use @c 'time=\"*\"' as the string to search for, and 'time=\"0.0\"' as the replacement string.
/// - In order to replace the occurrences of 'file.cpp(XX)' per 'file.cpp:XX', where XX is a variable to keep,
///   on may use @c 'file.cpp(*)' as the string to search for, and 'file.cpp:*' as the replacement string.
template<class StringClass, class ForwardIterator>
inline StringClass
replace_all_occurrences_with_wildcards(
    StringClass str,
    ForwardIterator it_string_to_find, ForwardIterator it_string_to_find_end,
    ForwardIterator it_string_to_replace, ForwardIterator it_string_to_replace_end)
{
    for(; it_string_to_find != it_string_to_find_end && it_string_to_replace != it_string_to_replace_end;
        ++it_string_to_find, ++ it_string_to_replace) {

        std::size_t wildcard_pos = it_string_to_find->find("*");
        if(wildcard_pos == StringClass::npos) {
            ForwardIterator it_to_find_current_end(it_string_to_find);
            ForwardIterator it_to_replace_current_end(it_string_to_replace);
            str = replace_all_occurrences_of(
                str,
                it_string_to_find, ++it_to_find_current_end,
                it_string_to_replace, ++it_to_replace_current_end);
            continue;
        }

        std::size_t wildcard_pos_replace = it_string_to_replace->find("*");

        std::size_t found_begin = str.find( it_string_to_find->substr(0, wildcard_pos) );
        while( found_begin != StringClass::npos ) {
            std::size_t found_end = str.find(it_string_to_find->substr(wildcard_pos+1), found_begin + wildcard_pos + 1); // to simplify
            if( found_end != StringClass::npos ) {

                if( wildcard_pos_replace == StringClass::npos ) {
                    StringClass replace_content = *it_string_to_replace;
                    str.replace(
                        found_begin,
                        found_end + (it_string_to_find->size() - wildcard_pos - 1 ) - found_begin,
                        replace_content);
                } else {
                    StringClass replace_content =
                        it_string_to_replace->substr(0, wildcard_pos_replace)
                        + str.substr(found_begin + wildcard_pos,
                                     found_end - found_begin - wildcard_pos)
                        + it_string_to_replace->substr(wildcard_pos_replace+1) ;
                    str.replace(
                        found_begin,
                        found_end + (it_string_to_find->size() - wildcard_pos - 1 ) - found_begin,
                        replace_content);

                }
            }

            // may adapt the restart to the replacement and be more efficient
            found_begin = str.find( it_string_to_find->substr(0, wildcard_pos), found_begin + 1 );
       }
    }

    return str;
}

} // namespace utils
} // namespace unit_test
} // namespace boost

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_UTILS_ALGORITHM_HPP


code:
//  (C) Copyright Gennadiy Rozental 2001.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : overloadable assignment
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_ASSIGN_OP_HPP
#define BOOST_TEST_UTILS_ASSIGN_OP_HPP

namespace boost {
namespace unit_test {

// ************************************************************************** //
// **************             generic assign operator          ************** //
// ************************************************************************** //

// generic
template<typename T,typename S>
inline void
assign_op( T& t, S const& s, long )
{
    t = s;
}

//____________________________________________________________________________//

} // namespace unit_test
} // namespace boost

#endif // BOOST_TEST_UTILS_ASSIGN_OP_HPP


code:
//  (C) Copyright Gennadiy Rozental 2001.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : class basic_cstring wraps C string and provide std_string like
//                interface
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_HPP
#define BOOST_TEST_UTILS_BASIC_CSTRING_HPP

// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring_fwd.hpp>
#include <boost/test/utils/basic_cstring/bcs_char_traits.hpp>

// Boost
#include <boost/type_traits/remove_cv.hpp>

// STL
#include <string>

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {

namespace unit_test {

// ************************************************************************** //
// **************                basic_cstring                 ************** //
// ************************************************************************** //

template<typename CharT>
class basic_cstring {
    typedef basic_cstring<CharT>                        self_type;
public:
    // Subtypes
    typedef ut_detail::bcs_char_traits<CharT>           traits_type;
    typedef typename ut_detail::bcs_char_traits<CharT>::std_string  std_string;

    typedef CharT                                       value_type;
    typedef typename remove_cv<value_type>::type        value_ret_type;
    typedef value_type*                                 pointer;
    typedef value_type const*                           const_pointer;
    typedef value_type&                                 reference;
    typedef const value_type&                           const_reference;
    typedef std::size_t                                 size_type;
    typedef std::ptrdiff_t                              difference_type;

    typedef value_type const*                           const_iterator;
    typedef value_type*                                 iterator;

    // !! should also present reverse_iterator, const_reverse_iterator

#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
    enum npos_type { npos = static_cast<size_type>(-1) };
#else
    // IBM/VisualAge version 6 is not able to handle enums larger than 4 bytes.
    // But size_type is 8 bytes in 64bit mode.
    static const size_type npos = -1 ;
#endif

    static pointer  null_str();

    // Constructors; default copy constructor is generated by compiler
    basic_cstring();
    basic_cstring( std_string const& s );
    basic_cstring( pointer s );
    template<typename LenType>
    basic_cstring( pointer s, LenType len ) : m_begin( s ), m_end( m_begin + len ) {}
    basic_cstring( pointer first, pointer last );

    // data access methods
    value_ret_type  operator[]( size_type index ) const;
    value_ret_type  at( size_type index ) const;

    // size operators
    size_type       size() const;
    bool            is_empty() const;
    void            clear();
    void            resize( size_type new_len );

    // !! only for STL container conformance use is_empty instead
    bool            empty() const;

    // Trimming
    self_type&      trim_right( size_type trim_size );
    self_type&      trim_left( size_type trim_size );
    self_type&      trim_right( iterator it );
    self_type&      trim_left( iterator it );
#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(800))
    self_type&      trim_left( self_type exclusions = self_type() ) ;
    self_type&      trim_right( self_type exclusions = self_type() ) ;
    self_type&      trim( self_type exclusions = self_type() ) ;
#else
    // VA C++/XL C++ v6 and v8 has in this case a problem with the default arguments.
    self_type&      trim_left( self_type exclusions );
    self_type&      trim_right( self_type exclusions );
    self_type&      trim( self_type exclusions );
    self_type&      trim_left()     { return trim_left( self_type() ); }
    self_type&      trim_right()    { return trim_right( self_type() ); }
    self_type&      trim()          { return trim( self_type() ); }
#endif

    // Assignment operators
    basic_cstring&  operator=( self_type const& s );
    basic_cstring&  operator=( std_string const& s );
    basic_cstring&  operator=( pointer s );

    template<typename CharT2>
    basic_cstring&  assign( basic_cstring<CharT2> const& s )
    {
        return *this = basic_cstring<CharT>( s.begin(), s.end() );
    }
    template<typename PosType, typename LenType>
    basic_cstring&  assign( self_type const& s, PosType pos, LenType len )
    {
        return *this = self_type( s.m_begin + pos, len );
    }

    basic_cstring&  assign( std_string const& s );
    template<typename PosType, typename LenType>
    basic_cstring&  assign( std_string const& s, PosType pos, LenType len )
    {
        return *this = self_type( s.c_str() + pos, len );
    }
    basic_cstring&  assign( pointer s );
    template<typename LenType>
    basic_cstring&  assign( pointer s, LenType len )
    {
        return *this = self_type( s, len );
    }
    basic_cstring&  assign( pointer f, pointer l );

    // swapping
    void            swap( self_type& s );

    // Iterators
    iterator        begin();
    const_iterator  begin() const;
    iterator        end();
    const_iterator  end() const;

    // !! should have rbegin, rend

    // substring search operation
    size_type       find( basic_cstring ) const;
    size_type       rfind( basic_cstring ) const;
    self_type       substr( size_type beg_index, size_type end_index = npos ) const;

private:
    static self_type default_trim_ex();

    // Data members
    iterator        m_begin;
    iterator        m_end;
};

//____________________________________________________________________________//

template<typename CharT>
inline typename basic_cstring<CharT>::pointer
basic_cstring<CharT>::null_str()
{
    static CharT null = 0;
    return &null;
}

//____________________________________________________________________________//

template<typename CharT>
inline
basic_cstring<CharT>::basic_cstring()
: m_begin( null_str() )
, m_end( m_begin )
{
}

//____________________________________________________________________________//

template<typename CharT>
inline
basic_cstring<CharT>::basic_cstring( std_string const& s )
: m_begin( s.c_str() )
, m_end( m_begin + s.size() )
{
}

//____________________________________________________________________________//

template<typename CharT>
inline
basic_cstring<CharT>::basic_cstring( pointer s )
: m_begin( s ? s : null_str() )
, m_end  ( m_begin + (s ? traits_type::length( s ) : 0 ) )
{
}

//____________________________________________________________________________//

template<typename CharT>
inline
basic_cstring<CharT>::basic_cstring( pointer first, pointer last )
: m_begin( first )
, m_end( last )
{
}

//____________________________________________________________________________//

template<typename CharT>
inline typename basic_cstring<CharT>::value_ret_type
basic_cstring<CharT>::operator[]( size_type index ) const
{
    return m_begin[index];
}

//____________________________________________________________________________//

template<typename CharT>
inline typename basic_cstring<CharT>::value_ret_type
basic_cstring<CharT>::at( size_type index ) const
{
    if( m_begin + index >= m_end )
        return static_cast<value_type>(0);

    return m_begin[index];
}

//____________________________________________________________________________//

template<typename CharT>
inline typename basic_cstring<CharT>::size_type
basic_cstring<CharT>::size() const
{
    return static_cast<size_type>(m_end - m_begin);
}

//____________________________________________________________________________//

template<typename CharT>
inline bool
basic_cstring<CharT>::is_empty() const
{
    return m_end == m_begin;
}

//____________________________________________________________________________//

template<typename CharT>
inline bool
basic_cstring<CharT>::empty() const
{
    return is_empty();
}

//____________________________________________________________________________//

template<typename CharT>
inline void
basic_cstring<CharT>::clear()
{
    m_begin = m_end;
}

//____________________________________________________________________________//

template<typename CharT>
inline void
basic_cstring<CharT>::resize( size_type new_len )
{
    if( m_begin + new_len < m_end )
        m_end = m_begin + new_len;
}

//____________________________________________________________________________//

template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_left( size_type trim_size )
{
    m_begin += trim_size;
    if( m_end <= m_begin )
        clear();

    return *this;
}

//____________________________________________________________________________//

template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_left( iterator it )
{
    m_begin = it;
    if( m_end <= m_begin )
        clear();

    return *this;
}

//____________________________________________________________________________//

template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_left( basic_cstring exclusions )
{
    if( exclusions.is_empty() )
        exclusions = default_trim_ex();

    iterator it;
    for( it = begin(); it != end(); ++it ) {
        if( traits_type::find( exclusions.begin(), exclusions.size(), *it ) == reinterpret_cast<pointer>(0) )
            break;
    }

    return trim_left( it );
}

//____________________________________________________________________________//

template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_right( size_type trim_size )
{
    m_end  -= trim_size;
    if( m_end <= m_begin )
        clear();

    return *this;
}

//____________________________________________________________________________//

template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_right( iterator it )
{
    m_end = it;
    if( m_end <= m_begin )
        clear();

    return *this;
}

//____________________________________________________________________________//

template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_right( basic_cstring exclusions )
{
    if( exclusions.is_empty() )
        exclusions = default_trim_ex();

    iterator it;

    for( it = end()-1; it != begin()-1; --it ) {
        if( self_type::traits_type::find( exclusions.begin(),  exclusions.size(), *it ) == reinterpret_cast<pointer>(0) )
            break;
    }

    return trim_right( it+1 );
}

//____________________________________________________________________________//

template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim( basic_cstring exclusions )
{
    trim_left( exclusions );
    trim_right( exclusions );

    return *this;
}

//____________________________________________________________________________//

template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::operator=( basic_cstring<CharT> const& s )
{
    m_begin = s.m_begin;
    m_end   = s.m_end;

    return *this;
}

//____________________________________________________________________________//

template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::operator=( std_string const& s )
{
    return *this = self_type( s );
}

//____________________________________________________________________________//

template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::operator=( pointer s )
{
    return *this = self_type( s );
}

//____________________________________________________________________________//

template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::assign( std_string const& s )
{
    return *this = self_type( s );
}

//____________________________________________________________________________//

template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::assign( pointer s )
{
    return *this = self_type( s );
}

//____________________________________________________________________________//

template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::assign( pointer f, pointer l )
{
    return *this = self_type( f, l );
}

//____________________________________________________________________________//

template<typename CharT>
inline void
basic_cstring<CharT>::swap( basic_cstring<CharT>& s )
{
    // do not want to include alogrithm
    pointer tmp1    = m_begin;
    pointer tmp2    = m_end;

    m_begin         = s.m_begin;
    m_end           = s.m_end;

    s.m_begin       = tmp1;
    s.m_end         = tmp2;
}

//____________________________________________________________________________//

template<typename CharT>
inline typename basic_cstring<CharT>::iterator
basic_cstring<CharT>::begin()
{
    return m_begin;
}

//____________________________________________________________________________//

template<typename CharT>
inline typename basic_cstring<CharT>::const_iterator
basic_cstring<CharT>::begin() const
{
    return m_begin;
}

//____________________________________________________________________________//

template<typename CharT>
inline typename basic_cstring<CharT>::iterator
basic_cstring<CharT>::end()
{
    return m_end;
}

//____________________________________________________________________________//

template<typename CharT>
inline typename basic_cstring<CharT>::const_iterator
basic_cstring<CharT>::end() const
{
    return m_end;
}

//____________________________________________________________________________//

template<typename CharT>
inline typename basic_cstring<CharT>::size_type
basic_cstring<CharT>::find( basic_cstring<CharT> str ) const
{
    if( str.is_empty() || str.size() > size() )
        return static_cast<size_type>(npos);

    const_iterator it   = begin();
    const_iterator last = end() - str.size() + 1;

    while( it != last ) {
        if( traits_type::compare( it, str.begin(), str.size() ) == 0 )
            break;

        ++it;
    }

    return it == last ? npos : static_cast<size_type>(it - begin());
}

//____________________________________________________________________________//

template<typename CharT>
inline typename basic_cstring<CharT>::size_type
basic_cstring<CharT>::rfind( basic_cstring<CharT> str ) const
{
    if( str.is_empty() || str.size() > size() )
        return static_cast<size_type>(npos);

    const_iterator it   = end() - str.size();
    const_iterator last = begin()-1;

    while( it != last ) {
        if( traits_type::compare( it, str.begin(), str.size() ) == 0 )
            break;

        --it;
    }

    return it == last ? static_cast<size_type>(npos) : static_cast<size_type>(it - begin());
}

//____________________________________________________________________________//

template<typename CharT>
inline basic_cstring<CharT>
basic_cstring<CharT>::substr( size_type beg_index, size_type end_index ) const
{
    return beg_index > size()
            ?       self_type()
            : end_index > size()
                ?   self_type( m_begin + beg_index, m_end )
                :   self_type( m_begin + beg_index, m_begin + end_index );
}

//____________________________________________________________________________//

template<typename CharT>
inline basic_cstring<CharT>
basic_cstring<CharT>::default_trim_ex()
{
    static CharT ws[3] = { CharT(' '), CharT('\t'), CharT('\n') }; // !! wide case

    return self_type( ws, 3 );
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************             comparison operators             ************** //
// ************************************************************************** //

template<typename CharT1,typename CharT2>
inline bool
operator==( basic_cstring<CharT1> const& s1, basic_cstring<CharT2> const& s2 )
{
    typedef typename basic_cstring<CharT1>::traits_type traits_type;
    return s1.size() == s2.size() &&
               traits_type::compare( s1.begin(), s2.begin(), s1.size() ) == 0;
}

//____________________________________________________________________________//

template<typename CharT1,typename CharT2>
inline bool
operator==( basic_cstring<CharT1> const& s1, CharT2* s2 )
{
#if !defined(__DMC__)
    return s1 == basic_cstring<CharT2>( s2 );
#else
    return s1 == basic_cstring<CharT2 const>( s2 );
#endif
}

//____________________________________________________________________________//

template<typename CharT>
inline bool
operator==( basic_cstring<CharT> const& s1, typename basic_cstring<CharT>::std_string const& s2 )
{
    return s1 == basic_cstring<CharT>( s2 );
}

//____________________________________________________________________________//

template<typename CharT1,typename CharT2>
inline bool
operator==( CharT1* s2, basic_cstring<CharT2> const& s1 )
{
    return s1 == s2;
}

//____________________________________________________________________________//

template<typename CharT>
inline bool
operator==( typename basic_cstring<CharT>::std_string const& s2, basic_cstring<CharT> const& s1 )
{
    return s1 == s2;
}

//____________________________________________________________________________//

template<typename CharT>
inline bool
operator!=( basic_cstring<CharT> const& s1, CharT* s2 )
{
    return !(s1 == s2);
}

//____________________________________________________________________________//

template<typename CharT>
inline bool
operator!=( CharT* s2, basic_cstring<CharT> const& s1 )
{
    return !(s1 == s2);
}

//____________________________________________________________________________//

template<typename CharT>
inline bool
operator!=( basic_cstring<CharT> const& s1, basic_cstring<CharT> const& s2 )
{
    return !(s1 == s2);
}

//____________________________________________________________________________//

template<typename CharT>
inline bool
operator!=( basic_cstring<CharT> const& s1, typename basic_cstring<CharT>::std_string const& s2 )
{
    return !(s1 == s2);
}

//____________________________________________________________________________//

template<typename CharT>
inline bool
operator!=( typename basic_cstring<CharT>::std_string const& s2, basic_cstring<CharT> const& s1 )
{
    return !(s1 == s2);
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************                  first_char                  ************** //
// ************************************************************************** //

template<typename CharT>
inline typename basic_cstring<CharT>::value_ret_type
first_char( basic_cstring<CharT> source )
{
    typedef typename basic_cstring<CharT>::value_ret_type res_type;

    return source.is_empty() ? static_cast<res_type>(0) : *source.begin();
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************                  last_char                   ************** //
// ************************************************************************** //

template<typename CharT>
inline typename basic_cstring<CharT>::value_ret_type
last_char( basic_cstring<CharT> source )
{
    typedef typename basic_cstring<CharT>::value_ret_type res_type;

    return source.is_empty() ? static_cast<res_type>(0) : *(source.end()-1);
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************                  assign_op                   ************** //
// ************************************************************************** //

template<typename CharT1, typename CharT2>
inline void
assign_op( std::basic_string<CharT1>& target, basic_cstring<CharT2> src, int )
{
    target.assign( src.begin(), src.size() );
}

//____________________________________________________________________________//

template<typename CharT1, typename CharT2>
inline std::basic_string<CharT1>&
operator+=( std::basic_string<CharT1>& target, basic_cstring<CharT2> const& str )
{
    target.append( str.begin(), str.end() );
    return target;
}

//____________________________________________________________________________//

template<typename CharT1, typename CharT2>
inline std::basic_string<CharT1>
operator+( std::basic_string<CharT1> const& lhs, basic_cstring<CharT2> const& rhs )
{
    std::basic_string<CharT1> res( lhs );

    res.append( rhs.begin(), rhs.end() );
    return res;
}

//____________________________________________________________________________//

} // namespace unit_test

} // namespace boost

//____________________________________________________________________________//

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_UTILS_BASIC_CSTRING_HPP


code:
//  (C) Copyright Gennadiy Rozental 2001.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : basic_cstring class wrap C string and provide std_string like
//                interface
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP
#define BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP

#include <boost/detail/workaround.hpp>

namespace boost {

namespace unit_test {

template<typename CharT> class      basic_cstring;
typedef basic_cstring<char const>   const_string;
#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590041))
typedef const_string                literal_string;
#else
typedef const_string const          literal_string;
#endif

typedef char const* const           c_literal_string;

} // namespace unit_test

} // namespace boost

#endif // BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP


code:
//  (C) Copyright Gennadiy Rozental 2001.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : generic char traits class; wraps std::char_traits
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_BCS_CHAR_TRAITS_HPP
#define BOOST_TEST_UTILS_BCS_CHAR_TRAITS_HPP

// Boost
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/test/detail/config.hpp>
#include <boost/type_traits/add_const.hpp>

// STL
#include <string>                       // std::char_traits
#include <cstddef>                      // std::size_t

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {

namespace unit_test {

namespace ut_detail {

template<typename CharT> struct bcs_base_char           { typedef CharT type; };

template<> struct bcs_base_char<char const>             { typedef char type; };
template<> struct bcs_base_char<unsigned char>          { typedef char type; };
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template<> struct bcs_base_char<unsigned char const>    { typedef char type; };
#endif

template<> struct bcs_base_char<wchar_t const>          { typedef wchar_t type; };

// ************************************************************************** //
// **************               bcs_char_traits                ************** //
// ************************************************************************** //

template<typename CharT>
struct bcs_char_traits_impl
{
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
    typedef CharT const const_char;
#else
    typedef typename boost::add_const<CharT>::type const_char;
#endif
    static bool eq( CharT c1, CharT c2 )
    {
        return c1 == c2;
    }
    static bool lt( CharT c1, CharT c2 )
    {
        return c1 < c2;
    }

    static int compare( const_char* cstr1, const_char* cstr2, std::size_t n )
    {
        while( n > 0 ) {
            if( !eq( *cstr1, *cstr2 ) )
                return lt( *cstr1, *cstr2 ) ? -1 : 1;
            ++cstr1;
            ++cstr2;
            --n;
        }

        return 0;
    }

    static std::size_t length( const_char* cstr )
    {
        const_char null_char = CharT();

        const_char* ptr = cstr;
        while( !eq( *ptr, null_char ) )
            ++ptr;

        return ptr - cstr;
    }

    static const_char* find( const_char* s, std::size_t n, CharT c )
    {
        while( n > 0 ) {
            if( eq( *s, c ) )
                return s;

            ++s;
            --n;
        }
        return 0;
    }
};

#ifdef BOOST_CLASSIC_IOSTREAMS
template<typename CharT>
struct char_traits_with_find : std::string_char_traits<CharT> {
    static CharT const* find( CharT const* s, std::size_t n, CharT c )
    {
        while( n > 0 ) {
            if( eq( *s, c ) )
                return s;

            ++s;
            --n;
        }
        return 0;
    }
};

template<> struct bcs_char_traits_impl<char> : public char_traits_with_find<char> {};
template<> struct bcs_char_traits_impl<wchar_t> : public char_traits_with_find<wchar_t> {};
#else
template<> struct bcs_char_traits_impl<char> : public std::char_traits<char> {};
template<> struct bcs_char_traits_impl<wchar_t> : public std::char_traits<wchar_t> {};
#endif

template<typename CharT>
class bcs_char_traits : public bcs_char_traits_impl<CharT> {
    typedef typename ut_detail::bcs_base_char<CharT>::type                              the_base_char;
public:
#ifdef BOOST_CLASSIC_IOSTREAMS
    typedef std::basic_string<the_base_char, std::string_char_traits<the_base_char> >   std_string;
#else
    typedef std::basic_string<the_base_char, std::char_traits<the_base_char> >          std_string;
#endif
};

} // namespace ut_detail

} // namespace unit_test

} // namespace boost

//____________________________________________________________________________//

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_UTILS_BCS_CHAR_TRAITS_HPP


code:
//  (C) Copyright Gennadiy Rozental 2001.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : class basic_cstring comparisons implementation
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_COMPARE_HPP
#define BOOST_TEST_UTILS_BASIC_CSTRING_COMPARE_HPP

// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>

// STL
#include <functional>
#include <cctype>

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

# if defined(BOOST_NO_STDC_NAMESPACE) && !BOOST_WORKAROUND(__BORLANDC__, <= 0x570)
namespace std { using ::toupper; }
# endif

namespace boost {

namespace unit_test {

// ************************************************************************** //
// **************                case_ins_compare              ************** //
// ************************************************************************** //

namespace ut_detail {

template<class CharT>
struct case_ins
{
    static bool         eq( CharT c1, CharT c2 ) { return (std::toupper)( c1 ) == (std::toupper)( c2 ); }
    static bool         lt( CharT c1, CharT c2 ) { return (std::toupper)( c1 ) <  (std::toupper)( c2 ); }

    static int          compare( CharT const* s1, CharT const* s2, std::size_t n )
    {
        for( std::size_t i = 0; i < n; ++i ) {
            if( !eq( s1[i], s2[i] ) )
                return lt( s1[i], s2[i] ) ? -1 : 1;
        }
        return 0;
    }
};

} // namespace ut_detail

// ************************************************************************** //
// **************                  case_ins_eq                 ************** //
// ************************************************************************** //

template<class CharT>
inline bool
case_ins_eq( basic_cstring<CharT> x, basic_cstring<CharT> y )
{
    return x.size() == y.size() && ut_detail::case_ins<CharT>::compare( x.begin(), y.begin(), x.size() ) == 0;
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************                 case_ins_less                ************** //
// ************************************************************************** //

template<class CharT>
class case_ins_less : public std::binary_function<basic_cstring<CharT>,basic_cstring<CharT>,bool>
{
public:
    bool operator()( basic_cstring<CharT> x, basic_cstring<CharT> y ) const
    {
        return x.size() != y.size()
                ? x.size() < y.size()
                : ut_detail::case_ins<CharT>::compare( x.begin(), y.begin(), x.size() ) < 0;
    }
};

//____________________________________________________________________________//

// ************************************************************************** //
// **************                 operators <,>                ************** //
// ************************************************************************** //

template<class CharT>
inline bool
operator <( boost::unit_test::basic_cstring<CharT> const& x,
            boost::unit_test::basic_cstring<CharT> const& y )
{
    typedef typename boost::unit_test::basic_cstring<CharT>::traits_type traits_type;
    return x.size() != y.size()
            ? x.size() < y.size()
            : traits_type::compare( x.begin(), y.begin(), x.size() ) < 0;
}

//____________________________________________________________________________//

template<class CharT>
inline bool
operator <=( boost::unit_test::basic_cstring<CharT> const& x,
            boost::unit_test::basic_cstring<CharT> const& y )
{
    return !(y < x);
}

//____________________________________________________________________________//

template<class CharT>
inline bool
operator >( boost::unit_test::basic_cstring<CharT> const& x,
            boost::unit_test::basic_cstring<CharT> const& y )
{
    return y < x;
}

//____________________________________________________________________________//

template<class CharT>
inline bool
operator >=( boost::unit_test::basic_cstring<CharT> const& x,
            boost::unit_test::basic_cstring<CharT> const& y )
{
    return !(x < y);
}

//____________________________________________________________________________//

} // namespace unit_test

} // namespace boost

//____________________________________________________________________________//

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_BASIC_CSTRING_COMPARE_HPP_071894GER


code:
//  (C) Copyright Gennadiy Rozental 2001.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : basic_cstring i/o implementation
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_IO_HPP
#define BOOST_TEST_UTILS_BASIC_CSTRING_IO_HPP

// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>

// STL
#include <iosfwd>
#include <string>

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

namespace boost {

namespace unit_test {

#ifdef BOOST_CLASSIC_IOSTREAMS

template<typename CharT>
inline std::ostream&
operator<<( std::ostream& os, basic_cstring<CharT> const& str )
{
    typedef typename ut_detail::bcs_base_char<CharT>::type char_type;
    char_type const* const beg = reinterpret_cast<char_type const* const>( str.begin() );
    char_type const* const end = reinterpret_cast<char_type const* const>( str.end() );
    os << std::basic_string<char_type>( beg, end - beg );

    return os;
}

#else

template<typename CharT1, typename Tr,typename CharT2>
inline std::basic_ostream<CharT1,Tr>&
operator<<( std::basic_ostream<CharT1,Tr>& os, basic_cstring<CharT2> const& str )
{
    CharT1 const* const beg = reinterpret_cast<CharT1 const*>( str.begin() ); // !!
    CharT1 const* const end = reinterpret_cast<CharT1 const*>( str.end() );
    os << std::basic_string<CharT1,Tr>( beg, end - beg );

    return os;
}

#endif

//____________________________________________________________________________//

} // namespace unit_test

} // namespace boost

//____________________________________________________________________________//

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_BASIC_CSTRING_IO_HPP_071894GER