code:
//  (C) Copyright Gennadiy Rozental 2001.
//  Use, modification, and distribution are subject to the
//  Boost Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief CLA parser
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP
#define BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP

// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/argument.hpp>
#include <boost/test/utils/runtime/modifier.hpp>
#include <boost/test/utils/runtime/parameter.hpp>

#include <boost/test/utils/runtime/cla/argv_traverser.hpp>

// Boost.Test
#include <boost/test/utils/foreach.hpp>
#include <boost/test/utils/algorithm.hpp>
#include <boost/test/detail/throw_exception.hpp>
#include <boost/test/detail/global_typedef.hpp>

#include <boost/algorithm/cxx11/all_of.hpp> // !! ?? unnecessary after cxx11

// STL
// !! ?? #include <unordered_set>
#include <set>
#include <iostream>

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

namespace boost {
namespace runtime {
namespace cla {

// ************************************************************************** //
// **************         runtime::cla::parameter_trie         ************** //
// ************************************************************************** //

namespace rt_cla_detail {

struct parameter_trie;
typedef shared_ptr<parameter_trie> parameter_trie_ptr;
typedef std::map<char,parameter_trie_ptr> trie_per_char;
typedef std::vector<boost::reference_wrapper<parameter_cla_id const> > param_cla_id_list;

struct parameter_trie {
    parameter_trie() : m_has_final_candidate( false ) {}

    /// If subtrie corresponding to the char c exists returns it otherwise creates new
    parameter_trie_ptr  make_subtrie( char c )
    {
        trie_per_char::const_iterator it = m_subtrie.find( c );

        if( it == m_subtrie.end() )
            it = m_subtrie.insert( std::make_pair( c, parameter_trie_ptr( new parameter_trie ) ) ).first;

        return it->second;
    }

    /// Creates series of sub-tries per characters in a string
    parameter_trie_ptr  make_subtrie( cstring s )
    {
        parameter_trie_ptr res;

        BOOST_TEST_FOREACH( char, c, s )
            res = (res ? res->make_subtrie( c ) : make_subtrie( c ));

        return res;
    }

    /// Registers candidate parameter for this subtrie. If final, it needs to be unique
    void                add_candidate_id( parameter_cla_id const& param_id, basic_param_ptr param_candidate, bool final )
    {
        BOOST_TEST_I_ASSRT( !m_has_final_candidate && (!final || m_id_candidates.empty()),
          conflicting_param() << "Parameter cla id " << param_id.m_tag << " conflicts with the "
                              << "parameter cla id " << m_id_candidates.back().get().m_tag );

        m_has_final_candidate = final;
        m_id_candidates.push_back( ref(param_id) );

        if( m_id_candidates.size() == 1 )
            m_param_candidate = param_candidate;
        else
            m_param_candidate.reset();
    }

    /// Gets subtrie for specified char if present or nullptr otherwise
    parameter_trie_ptr  get_subtrie( char c ) const
    {
        trie_per_char::const_iterator it = m_subtrie.find( c );

        return it != m_subtrie.end() ? it->second : parameter_trie_ptr();
    }

    // Data members
    trie_per_char       m_subtrie;
    param_cla_id_list   m_id_candidates;
    basic_param_ptr     m_param_candidate;
    bool                m_has_final_candidate;
};

// ************************************************************************** //
// **************      runtime::cla::report_foreing_token      ************** //
// ************************************************************************** //

static void
report_foreing_token( cstring program_name, cstring token )
{
    std::cerr << "Boost.Test WARNING: token \"" << token << "\" does not correspond to the Boost.Test argument \n"
              << "                    and should be placed after all Boost.Test arguments and the -- separator.\n"
              << "                    For example: " << program_name << " --random -- " << token << "\n";
}

} // namespace rt_cla_detail

// ************************************************************************** //
// **************             runtime::cla::parser             ************** //
// ************************************************************************** //

class parser {
public:
    /// Initializes a parser and builds internal trie representation used for
    /// parsing based on the supplied parameters
#ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
    template<typename Modifiers=nfp::no_params_type>
    parser( parameters_store const& parameters, Modifiers const& m = nfp::no_params )
#else
    template<typename Modifiers>
    parser( parameters_store const& parameters, Modifiers const& m )
#endif
    {
        nfp::opt_assign( m_end_of_param_indicator, m, end_of_params );
        nfp::opt_assign( m_negation_prefix, m, negation_prefix );

        BOOST_TEST_I_ASSRT( algorithm::all_of( m_end_of_param_indicator.begin(),
                                               m_end_of_param_indicator.end(),
                                               parameter_cla_id::valid_prefix_char ),
                            invalid_cla_id() << "End of parameters indicator can only consist of prefix characters." );

        BOOST_TEST_I_ASSRT( algorithm::all_of( m_negation_prefix.begin(),
                                               m_negation_prefix.end(),
                                               parameter_cla_id::valid_name_char ),
                            invalid_cla_id() << "Negation prefix can only consist of prefix characters." );

        build_trie( parameters );
    }

    // input processing method
    int
    parse( int argc, char** argv, runtime::arguments_store& res )
    {
        // save program name for help message
        m_program_name = argv[0];
        cstring path_sep( "\\/" );

        cstring::iterator it = unit_test::utils::find_last_of( m_program_name.begin(), m_program_name.end(),
                                                                path_sep.begin(), path_sep.end() );
        if( it != m_program_name.end() )
            m_program_name.trim_left( it + 1 );

        // Set up the traverser
        argv_traverser tr( argc, (char const**)argv );

        // Loop till we reach end of input
        while( !tr.eoi() ) {
            cstring curr_token = tr.current_token();

            cstring prefix;
            cstring name;
            cstring value_separator;
            bool    negative_form = false;

            // Perform format validations and split the argument into prefix, name and separator
            // False return value indicates end of params indicator is met
            if( !validate_token_format( curr_token, prefix, name, value_separator, negative_form ) ) {
                // get rid of "end of params" token
                tr.next_token();
                break;
            }

            // Locate trie corresponding to found prefix and skip it in the input
            trie_ptr curr_trie = m_param_trie[prefix];

            if( !curr_trie ) {
                //  format_error() << "Unrecognized parameter prefix in the argument " << tr.current_token()
                rt_cla_detail::report_foreing_token( m_program_name, curr_token );
                tr.save_token();
                continue;
            }

            curr_token.trim_left( prefix.size() );

            // Locate parameter based on a name and skip it in the input
            locate_result locate_res = locate_parameter( curr_trie, name, curr_token );
            parameter_cla_id const& found_id    = locate_res.first;
            basic_param_ptr         found_param = locate_res.second;

            if( negative_form ) {
                BOOST_TEST_I_ASSRT( found_id.m_negatable,
                                    format_error( found_param->p_name )
                                        << "Parameter tag " << found_id.m_tag << " is not negatable." );

                curr_token.trim_left( m_negation_prefix.size() );
            }

            curr_token.trim_left( name.size() );

            cstring value;

            // Skip validations if parameter has optional value and we are at the end of token
            if( !value_separator.is_empty() || !found_param->p_has_optional_value ) {
                // Validate and skip value separator in the input
                BOOST_TEST_I_ASSRT( found_id.m_value_separator == value_separator,
                                    format_error( found_param->p_name )
                                        << "Invalid separator for the parameter "
                                        << found_param->p_name
                                        << " in the argument " << tr.current_token() );

                curr_token.trim_left( value_separator.size() );

                // Deduce value source
                value = curr_token;
                if( value.is_empty() ) {
                    tr.next_token();
                    value = tr.current_token();
                }

                BOOST_TEST_I_ASSRT( !value.is_empty(),
                                    format_error( found_param->p_name )
                                        << "Missing an argument value for the parameter "
                                        << found_param->p_name
                                        << " in the argument " << tr.current_token() );
            }

            // Validate against argument duplication
            BOOST_TEST_I_ASSRT( !res.has( found_param->p_name ) || found_param->p_repeatable,
                                duplicate_arg( found_param->p_name )
                                    << "Duplicate argument value for the parameter "
                                    << found_param->p_name
                                    << " in the argument " << tr.current_token() );

            // Produce argument value
            found_param->produce_argument( value, negative_form, res );

            tr.next_token();
        }

        // generate the remainder and return it's size
        return tr.remainder();
    }

    // help/usage/version
    void
    version( std::ostream& ostr )
    {
       ostr << "Boost.Test module ";

#if defined(BOOST_TEST_MODULE)
       // we do not want to refer to the master test suite there
       ostr << '\'' << BOOST_TEST_STRINGIZE( BOOST_TEST_MODULE ).trim( "\"" ) << "' ";
#endif

       ostr << "in executable '" << m_program_name << "'\n";
       ostr << "Compiled from Boost version "
            << BOOST_VERSION/100000      << "."
            << BOOST_VERSION/100 % 1000  << "."
            << BOOST_VERSION % 100       ;
       ostr << " with ";
#if defined(BOOST_TEST_INCLUDED)
       ostr << "single header inclusion of";
#elif defined(BOOST_TEST_DYN_LINK)
       ostr << "dynamic linking to";
#else
       ostr << "static linking to";
#endif
       ostr << " Boost.Test\n";
       ostr << "- Compiler: " << BOOST_COMPILER << '\n'
            << "- Platform: " << BOOST_PLATFORM << '\n'
            << "- STL     : " << BOOST_STDLIB;
       ostr << std::endl;
    }

    void
    usage( std::ostream& ostr, cstring param_name = cstring() )
    {
        if( !param_name.is_empty() ) {
            basic_param_ptr param = locate_parameter( m_param_trie[help_prefix], param_name, "" ).second;
            param->usage( ostr, m_negation_prefix );
        }
        else {
            ostr << "Usage: " << m_program_name << " [Boost.Test argument]... ";
            if( !m_end_of_param_indicator.empty() )
                ostr << m_end_of_param_indicator << " [custom test module argument]...";
            ostr << "\n";
        }

        ostr << "\nFor detailed help on Boost.Test parameters use:\n"
             << "  " << m_program_name << " --help\n"
             << "or\n"
             << "  " << m_program_name << " --help=<parameter name>\n";
    }

    void
    help( std::ostream& ostr, parameters_store const& parameters, cstring param_name )
    {
        if( !param_name.is_empty() ) {
            basic_param_ptr param = locate_parameter( m_param_trie[help_prefix], param_name, "" ).second;
            param->help( ostr, m_negation_prefix );
            return;
        }

        ostr << "Usage: " << m_program_name << " [Boost.Test argument]... ";
        if( !m_end_of_param_indicator.empty() )
            ostr << m_end_of_param_indicator << " [custom test module argument]...";

        ostr << "\n\nBoost.Test arguments correspond to parameters listed below. "
                "All parameters are optional. You can use specify parameter value either "
                "as a command line argument or as a value of corresponding environment "
                "variable. In case if argument for the same parameter is specified in both "
                "places, command line is taking precedence. Command line argument format "
                "supports parameter name guessing, so you can use any unambiguous "
                "prefix to identify a parameter.";
        if( !m_end_of_param_indicator.empty() )
            ostr << " All the arguments after the " << m_end_of_param_indicator << " are ignored by the Boost.Test.";

        ostr << "\n\nBoost.Test supports following parameters:\n";

        BOOST_TEST_FOREACH( parameters_store::storage_type::value_type const&, v, parameters.all() ) {
            basic_param_ptr param = v.second;

            param->usage( ostr, m_negation_prefix );
        }

        ostr << "\nUse --help=<parameter name> to display detailed help for specific parameter.\n";
    }

private:
    typedef rt_cla_detail::parameter_trie_ptr   trie_ptr;
    typedef rt_cla_detail::trie_per_char        trie_per_char;
    typedef std::map<cstring,trie_ptr>          str_to_trie;

    void
    build_trie( parameters_store const& parameters )
    {
        // Iterate over all parameters
        BOOST_TEST_FOREACH( parameters_store::storage_type::value_type const&, v, parameters.all() ) {
            basic_param_ptr param = v.second;

            // Register all parameter's ids in trie.
            BOOST_TEST_FOREACH( parameter_cla_id const&, id, param->cla_ids() ) {
                // This is the trie corresponding to the prefix.
                trie_ptr next_trie = m_param_trie[id.m_prefix];
                if( !next_trie )
                    next_trie = m_param_trie[id.m_prefix] = trie_ptr( new rt_cla_detail::parameter_trie );

                // Build the trie, by following name's characters
                // and register this parameter as candidate on each level
                for( size_t index = 0; index < id.m_tag.size(); ++index ) {
                    next_trie = next_trie->make_subtrie( id.m_tag[index] );

                    next_trie->add_candidate_id( id, param, index == (id.m_tag.size() - 1) );
                }
            }
        }
    }

    bool
    validate_token_format( cstring token, cstring& prefix, cstring& name, cstring& separator, bool& negative_form )
    {
        // Match prefix
        cstring::iterator it = token.begin();
        while( it != token.end() && parameter_cla_id::valid_prefix_char( *it ) )
            ++it;

        prefix.assign( token.begin(), it );

        if( prefix.empty() )
            return true;

        // Match name
        while( it != token.end() && parameter_cla_id::valid_name_char( *it ) )
            ++it;

        name.assign( prefix.end(), it );

        if( name.empty() ) {
            if( prefix == m_end_of_param_indicator )
                return false;

            BOOST_TEST_I_THROW( format_error() << "Invalid format for an actual argument " << token );
        }

        // Match value separator
        while( it != token.end() && parameter_cla_id::valid_separator_char( *it ) )
            ++it;

        separator.assign( name.end(), it );

        // Match negation prefix
        negative_form = !m_negation_prefix.empty() && ( name.substr( 0, m_negation_prefix.size() ) == m_negation_prefix );
        if( negative_form )
            name.trim_left( m_negation_prefix.size() );

        return true;
    }

    // C++03: cannot have references as types
    typedef std::pair<parameter_cla_id, basic_param_ptr> locate_result;

    locate_result
    locate_parameter( trie_ptr curr_trie, cstring name, cstring token )
    {
        std::vector<trie_ptr> typo_candidates;
        std::vector<trie_ptr> next_typo_candidates;
        trie_ptr next_trie;

        BOOST_TEST_FOREACH( char, c, name ) {
            if( curr_trie ) {
                // locate next subtrie corresponding to the char
                next_trie = curr_trie->get_subtrie( c );

                if( next_trie )
                    curr_trie = next_trie;
                else {
                    // Initiate search for typo candicates. We will account for 'wrong char' typo
                    // 'missing char' typo and 'extra char' typo
                    BOOST_TEST_FOREACH( trie_per_char::value_type const&, typo_cand, curr_trie->m_subtrie ) {
                        // 'wrong char' typo
                        typo_candidates.push_back( typo_cand.second );

                        // 'missing char' typo
                        if( (next_trie = typo_cand.second->get_subtrie( c )) )
                            typo_candidates.push_back( next_trie );
                    }

                    // 'extra char' typo
                    typo_candidates.push_back( curr_trie );

                    curr_trie.reset();
                }
            }
            else {
                // go over existing typo candidates and see if they are still viable
                BOOST_TEST_FOREACH( trie_ptr, typo_cand, typo_candidates ) {
                    trie_ptr next_typo_cand = typo_cand->get_subtrie( c );

                    if( next_typo_cand )
                        next_typo_candidates.push_back( next_typo_cand );
                }

                next_typo_candidates.swap( typo_candidates );
                next_typo_candidates.clear();
            }
        }

        if( !curr_trie ) {
            std::vector<cstring> typo_candidate_names;
            std::set<parameter_cla_id const*> unique_typo_candidate; // !! ?? unordered_set
            typo_candidate_names.reserve( typo_candidates.size() );
// !! ??            unique_typo_candidate.reserve( typo_candidates.size() );

            BOOST_TEST_FOREACH( trie_ptr, trie_cand, typo_candidates ) {
                // avoid ambiguos candidate trie
                if( trie_cand->m_id_candidates.size() > 1 )
                    continue;

                BOOST_TEST_FOREACH( parameter_cla_id const&, param_cand, trie_cand->m_id_candidates ) {
                    if( !unique_typo_candidate.insert( &param_cand ).second )
                        continue;

                    typo_candidate_names.push_back( param_cand.m_tag );
                }
            }

#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
            BOOST_TEST_I_THROW( unrecognized_param( std::move(typo_candidate_names) )
                                << "An unrecognized parameter in the argument "
                                << token );
#else
            BOOST_TEST_I_THROW( unrecognized_param( typo_candidate_names )
                                << "An unrecognized parameter in the argument "
                                << token );
#endif
        }

        if( curr_trie->m_id_candidates.size() > 1 ) {
            std::vector<cstring> amb_names;
            BOOST_TEST_FOREACH( parameter_cla_id const&, param_id, curr_trie->m_id_candidates )
                amb_names.push_back( param_id.m_tag );

#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
            BOOST_TEST_I_THROW( ambiguous_param( std::move( amb_names ) )
                                << "An ambiguous parameter name in the argument " << token );
#else
            BOOST_TEST_I_THROW( ambiguous_param( amb_names )
                                << "An ambiguous parameter name in the argument " << token );
#endif
        }

        return locate_result( curr_trie->m_id_candidates.back().get(), curr_trie->m_param_candidate );
    }

    // Data members
    cstring     m_program_name;
    std::string m_end_of_param_indicator;
    std::string m_negation_prefix;
    str_to_trie m_param_trie;
};

} // namespace cla
} // namespace runtime
} // namespace boost

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

#endif // BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_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 : implements fetching absent parameter athuments from environment
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_RUNTIME_ENV_FETCH_HPP
#define BOOST_TEST_UTILS_RUNTIME_ENV_FETCH_HPP

// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/parameter.hpp>
#include <boost/test/utils/runtime/argument.hpp>

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

// C Runtime
#include <stdlib.h>

namespace boost {
namespace runtime {
namespace env {

namespace env_detail {

#ifndef UNDER_CE

#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4996) // getenv
#endif

inline std::pair<cstring,bool>
sys_read_var( cstring var_name )
{
    using namespace std;
    char const* res = getenv( var_name.begin() );

    return std::make_pair( cstring(res), res != NULL );
}

#ifdef BOOST_MSVC
#pragma warning(pop)
#endif

#else

inline std::pair<cstring,bool>
sys_read_var( cstring var_name )
{
    return std::make_pair( cstring(), false );
}

#endif

//____________________________________________________________________________//

template<typename ReadFunc>
inline void
fetch_absent( parameters_store const& params, runtime::arguments_store& args, ReadFunc read_func )
{
    BOOST_TEST_FOREACH( parameters_store::storage_type::value_type const&, v, params.all() ) {
        basic_param_ptr param = v.second;

        if( args.has( param->p_name ) || param->p_env_var.empty() )
            continue;

        std::pair<cstring,bool> value = read_func( param->p_env_var );

        if( !value.second )
            continue;

        // Validate against unexpected empty value
        BOOST_TEST_I_ASSRT( !value.first.is_empty() || param->p_has_optional_value,
            format_error( param->p_name )
                << "Missing an argument value for the parameter " << param->p_name
                << " in the environment." );

        // Produce argument value
        param->produce_argument( value.first, false, args );

    }
}

//____________________________________________________________________________//

} // namespace env_detail

inline void
fetch_absent( parameters_store const& params, runtime::arguments_store& args )
{
    env_detail::fetch_absent( params, args, &env_detail::sys_read_var );
}

} // namespace env
} // namespace runtime
} // namespace boost

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

#endif // BOOST_TEST_UTILS_RUNTIME_ENV_FETCH_HPP

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        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : defines runtime parameters setup error
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_RUNTIME_INIT_ERROR_HPP
#define BOOST_TEST_UTILS_RUNTIME_INIT_ERROR_HPP

// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/fwd.hpp>

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

// Boost.Test
#include <boost/config.hpp>

// STL
#include <exception>
#include <vector>

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

namespace boost {
namespace runtime {

// ************************************************************************** //
// **************             runtime::param_error             ************** //
// ************************************************************************** //

class param_error : public std::exception {
public:
    ~param_error() BOOST_NOEXCEPT_OR_NOTHROW {}

    virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
    {
        return msg.c_str();
    }

    cstring     param_name;
    std::string msg;

protected:
    explicit    param_error( cstring param_name_ ) : param_name( param_name_) {}
};

//____________________________________________________________________________//

class init_error : public param_error {
protected:
    explicit    init_error( cstring param_name ) : param_error( param_name ) {}
    ~init_error() BOOST_NOEXCEPT_OR_NOTHROW {}
};

class input_error : public param_error {
protected:
    explicit    input_error( cstring param_name ) : param_error( param_name ) {}
    ~input_error() BOOST_NOEXCEPT_OR_NOTHROW {}
};

//____________________________________________________________________________//

template<typename Derived, typename Base>
class specific_param_error : public Base {
protected:
    explicit    specific_param_error( cstring param_name ) : Base( param_name ) {}
    ~specific_param_error() BOOST_NOEXCEPT_OR_NOTHROW {}

public:

//____________________________________________________________________________//

#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
    !defined(BOOST_NO_CXX11_REF_QUALIFIERS)

    Derived operator<<(char const* val) &&
    {
        this->msg.append( val );

        return reinterpret_cast<Derived&&>(*this);
    }

    //____________________________________________________________________________//

    template<typename T>
    Derived operator<<(T const& val) &&
    {
        this->msg.append( unit_test::utils::string_cast( val ) );

        return reinterpret_cast<Derived&&>(*this);
    }

    //____________________________________________________________________________//

#else

    Derived const& operator<<(char const* val) const
    {
        const_cast<specific_param_error<Derived, Base>&>(*this).msg.append( val );

        return static_cast<Derived const&>(*this);
    }

    //____________________________________________________________________________//

    template<typename T>
    Derived const& operator<<(T const& val) const
    {
        const_cast<specific_param_error<Derived, Base>&>(*this).msg.append( unit_test::utils::string_cast( val ) );

        return static_cast<Derived const&>(*this);
    }

    //____________________________________________________________________________//

#endif

};

// ************************************************************************** //
// **************           specific exception types           ************** //
// ************************************************************************** //

#define SPECIFIC_EX_TYPE( type, base )                  \
class type : public specific_param_error<type,base> {   \
public:                                                 \
    explicit type( cstring param_name = cstring() )     \
    : specific_param_error<type,base>( param_name )     \
    {}                                                  \
}                                                       \
/**/

SPECIFIC_EX_TYPE( invalid_cla_id, init_error );
SPECIFIC_EX_TYPE( duplicate_param, init_error );
SPECIFIC_EX_TYPE( conflicting_param, init_error );
SPECIFIC_EX_TYPE( unknown_param, init_error );
SPECIFIC_EX_TYPE( access_to_missing_argument, init_error );
SPECIFIC_EX_TYPE( arg_type_mismatch, init_error );
SPECIFIC_EX_TYPE( invalid_param_spec, init_error );

SPECIFIC_EX_TYPE( format_error, input_error );
SPECIFIC_EX_TYPE( duplicate_arg, input_error );
SPECIFIC_EX_TYPE( missing_req_arg, input_error );

#undef SPECIFIC_EX_TYPE

class ambiguous_param : public specific_param_error<ambiguous_param, input_error> {
public:
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
    explicit    ambiguous_param( std::vector<cstring>&& amb_candidates )
    : specific_param_error<ambiguous_param,input_error>( "" )
    , m_amb_candidates( std::move( amb_candidates ) ) {}
#else
    explicit    ambiguous_param( std::vector<cstring> const& amb_candidates )
    : specific_param_error<ambiguous_param,input_error>( "" )
    , m_amb_candidates( amb_candidates ) {}
#endif
    ~ambiguous_param() BOOST_NOEXCEPT_OR_NOTHROW {}

    std::vector<cstring> m_amb_candidates;
};

class unrecognized_param : public specific_param_error<unrecognized_param, input_error> {
public:
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
    explicit    unrecognized_param( std::vector<cstring>&& type_candidates )
    : specific_param_error<unrecognized_param,input_error>( "" )
    , m_typo_candidates( std::move( type_candidates ) ) {}
#else
    explicit    unrecognized_param( std::vector<cstring> const& type_candidates )
    : specific_param_error<unrecognized_param,input_error>( "" )
    , m_typo_candidates( type_candidates ) {}
#endif
    ~unrecognized_param() BOOST_NOEXCEPT_OR_NOTHROW {}

    std::vector<cstring> m_typo_candidates;
};

} // namespace runtime
} // namespace boost

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

#endif // BOOST_TEST_UTILS_RUNTIME_INIT_ERROR_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 : runtime parameters initialization final step
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_RUNTIME_FINALIZE_HPP
#define BOOST_TEST_UTILS_RUNTIME_FINALIZE_HPP

// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/parameter.hpp>
#include <boost/test/utils/runtime/argument.hpp>

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

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

namespace boost {
namespace runtime {

inline void
finalize_arguments( parameters_store const& params, runtime::arguments_store& args )
{
    BOOST_TEST_FOREACH( parameters_store::storage_type::value_type const&, v, params.all() ) {
        basic_param_ptr param = v.second;

        if( !args.has( param->p_name ) ) {
            if( param->p_has_default_value )
                param->produce_default( args );

            if( !args.has( param->p_name ) ) {
                BOOST_TEST_I_ASSRT( param->p_optional,
                    missing_req_arg( param->p_name ) << "Missing argument for required parameter " << param->p_name << "." );
            }
        }

        if( args.has( param->p_name ) && !!param->p_callback )
            param->p_callback( param->p_name );
    }
}

} // namespace runtime
} // namespace boost

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

#endif // BOOST_TEST_UTILS_RUNTIME_FINALIZE_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 : runtime parameters forward declaration
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_RUNTIME_FWD_HPP
#define BOOST_TEST_UTILS_RUNTIME_FWD_HPP

// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/test/utils/basic_cstring/io.hpp> // operator<<(boost::runtime::cstring)

// Boost
#include <boost/shared_ptr.hpp>

// STL
#include <map>

namespace boost {
namespace runtime {

typedef unit_test::const_string     cstring;

class argument;
typedef shared_ptr<argument> argument_ptr;

template<typename T> class typed_argument;

class basic_param;
typedef shared_ptr<basic_param> basic_param_ptr;

} // namespace runtime
} // namespace boost

#endif // BOOST_TEST_UTILS_RUNTIME_FWD_HPP


code:
//  (C) Copyright Gennadiy Rozental 2001.
//  Use, modification, and distribution are subject to the
//  Boost Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

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

#ifndef BOOST_TEST_UTILS_RUNTIME_MODIFIER_HPP
#define BOOST_TEST_UTILS_RUNTIME_MODIFIER_HPP

// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/fwd.hpp>

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

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

// New CLA API available only for some C++11 compilers
#if    !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) \
    && !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) \
    && !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) \
    && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
#define BOOST_TEST_CLA_NEW_API
#endif

namespace boost {
namespace runtime {

// ************************************************************************** //
// **************         environment variable modifiers       ************** //
// ************************************************************************** //

namespace {

#ifdef BOOST_TEST_CLA_NEW_API
auto const& description     = unit_test::static_constant<nfp::typed_keyword<cstring,struct description_t>>::value;
auto const& help            = unit_test::static_constant<nfp::typed_keyword<cstring,struct help_t>>::value;
auto const& env_var         = unit_test::static_constant<nfp::typed_keyword<cstring,struct env_var_t>>::value;
auto const& end_of_params   = unit_test::static_constant<nfp::typed_keyword<cstring,struct end_of_params_t>>::value;
auto const& negation_prefix = unit_test::static_constant<nfp::typed_keyword<cstring,struct neg_prefix_t>>::value;
auto const& value_hint      = unit_test::static_constant<nfp::typed_keyword<cstring,struct value_hint_t>>::value;
auto const& optional_value  = unit_test::static_constant<nfp::keyword<struct optional_value_t>>::value;
auto const& default_value   = unit_test::static_constant<nfp::keyword<struct default_value_t>>::value;
auto const& callback        = unit_test::static_constant<nfp::keyword<struct callback_t>>::value;

template<typename EnumType>
using enum_values = unit_test::static_constant<
  nfp::typed_keyword<std::initializer_list<std::pair<const cstring,EnumType>>, struct enum_values_t>
>;

#else

nfp::typed_keyword<cstring,struct description_t> description;
nfp::typed_keyword<cstring,struct help_t> help;
nfp::typed_keyword<cstring,struct env_var_t> env_var;
nfp::typed_keyword<cstring,struct end_of_params_t> end_of_params;
nfp::typed_keyword<cstring,struct neg_prefix_t> negation_prefix;
nfp::typed_keyword<cstring,struct value_hint_t> value_hint;
nfp::keyword<struct optional_value_t> optional_value;
nfp::keyword<struct default_value_t> default_value;
nfp::keyword<struct callback_t> callback;

template<typename EnumType>
struct enum_values_list {
    typedef std::pair<cstring,EnumType> ElemT;
    typedef std::vector<ElemT> ValuesT;

    enum_values_list const&
    operator()( cstring k, EnumType v ) const
    {
        const_cast<enum_values_list*>(this)->m_values.push_back( ElemT( k, v ) );

        return *this;
    }

    operator ValuesT const&() const { return m_values; }

private:
    ValuesT m_values;
};

template<typename EnumType>
struct enum_values : unit_test::static_constant<
  nfp::typed_keyword<enum_values_list<EnumType>, struct enum_values_t> >
{
};

#endif

} // local namespace

} // namespace runtime
} // namespace boost

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

#endif // BOOST_TEST_UTILS_RUNTIME_MODIFIER_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 : formal parameter definition
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_RUNTIME_PARAMETER_HPP
#define BOOST_TEST_UTILS_RUNTIME_PARAMETER_HPP

// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/fwd.hpp>
#include <boost/test/utils/runtime/modifier.hpp>
#include <boost/test/utils/runtime/argument.hpp>
#include <boost/test/utils/runtime/argument_factory.hpp>

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

// Boost
#include <boost/function/function2.hpp>
#include <boost/algorithm/cxx11/all_of.hpp>

// STL
#include <algorithm>

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

namespace boost {
namespace runtime {

// ************************************************************************** //
// **************           runtime::parameter_cla_id          ************** //
// ************************************************************************** //
// set of attributes identifying the parameter in the command line

struct parameter_cla_id {
    parameter_cla_id( cstring prefix, cstring tag, cstring value_separator, bool negatable )
    : m_prefix( prefix.begin(), prefix.size() )
    , m_tag( tag.begin(), tag.size() )
    , m_value_separator( value_separator.begin(), value_separator.size() )
    , m_negatable( negatable )
    {

        BOOST_TEST_I_ASSRT( algorithm::all_of( m_prefix.begin(), m_prefix.end(), valid_prefix_char ),
                            invalid_cla_id() << "Parameter " << m_tag
                                             << " has invalid characters in prefix." );

        BOOST_TEST_I_ASSRT( algorithm::all_of( m_tag.begin(), m_tag.end(), valid_name_char ),
                            invalid_cla_id() << "Parameter " << m_tag
                                             << " has invalid characters in name." );

        BOOST_TEST_I_ASSRT( algorithm::all_of( m_value_separator.begin(), m_value_separator.end(), valid_separator_char ),
                            invalid_cla_id() << "Parameter " << m_tag
                                             << " has invalid characters in value separator." );
    }

    static bool             valid_prefix_char( char c )
    {
        return c == '-' || c == '/' ;
    }
    static bool             valid_separator_char( char c )
    {
        return c == '=' || c == ':' || c == ' ' || c == '\0';
    }
    static bool             valid_name_char( char c )
    {
        return std::isalnum( c ) || c == '+' || c == '_' || c == '?';
    }

    std::string             m_prefix;
    std::string             m_tag;
    std::string             m_value_separator;
    bool                    m_negatable;
};

typedef std::vector<parameter_cla_id> param_cla_ids;

// ************************************************************************** //
// **************             runtime::basic_param             ************** //
// ************************************************************************** //

cstring const help_prefix("////");

class basic_param {
    typedef function<void (cstring)>            callback_type;
    typedef unit_test::readwrite_property<bool> bool_property;

protected:
    /// Constructor with modifiers
    template<typename Modifiers>
    basic_param( cstring name, bool is_optional, bool is_repeatable, Modifiers const& m )
    : p_name( name.begin(), name.end() )
    , p_description( nfp::opt_get( m, description, std::string() ) )
    , p_help( nfp::opt_get( m, runtime::help, std::string() ) )
    , p_env_var( nfp::opt_get( m, env_var, std::string() ) )
    , p_value_hint( nfp::opt_get( m, value_hint, std::string() ) )
    , p_optional( is_optional )
    , p_repeatable( is_repeatable )
    , p_has_optional_value( m.has( optional_value ) )
    , p_has_default_value( m.has( default_value ) || is_repeatable )
    , p_callback( nfp::opt_get( m, callback, callback_type() ) )
    {
        add_cla_id( help_prefix, name, ":" );
    }

public:
    virtual                 ~basic_param() {}

    // Pubic properties
    std::string const       p_name;
    std::string const       p_description;
    std::string const       p_help;
    std::string const       p_env_var;
    std::string const       p_value_hint;
    bool const              p_optional;
    bool const              p_repeatable;
    bool_property           p_has_optional_value;
    bool_property           p_has_default_value;
    callback_type const     p_callback;

    /// interface for cloning typed parameters
    virtual basic_param_ptr clone() const = 0;

    /// Access methods
    param_cla_ids const&    cla_ids() const { return m_cla_ids; }
    void                    add_cla_id( cstring prefix, cstring tag, cstring value_separator )
    {
        add_cla_id_impl( prefix, tag, value_separator, false, true );
    }

    /// interface for producing argument values for this parameter
    virtual void            produce_argument( cstring token, bool negative_form, arguments_store& store ) const = 0;
    virtual void            produce_default( arguments_store& store ) const = 0;

    /// interfaces for help message reporting
    virtual void            usage( std::ostream& ostr, cstring negation_prefix_ )
    {
        ostr     << "Parameter: " << p_name << '\n';
        if( !p_description.empty() )
            ostr << ' ' << p_description << '\n';

        ostr     << " Command line formats:\n";
        BOOST_TEST_FOREACH( parameter_cla_id const&, id, cla_ids() ) {
            if( id.m_prefix == help_prefix )
                continue;

            ostr << "   " << id.m_prefix;
            if( id.m_negatable )
                cla_name_help( ostr, id.m_tag, negation_prefix_ );
            else
                cla_name_help( ostr, id.m_tag, "" );

            bool optional_value_ = false;

            if( p_has_optional_value ) {
                optional_value_ = true;
                ostr << '[';
            }

            if( id.m_value_separator.empty() )
                ostr << ' ';
            else {
                ostr << id.m_value_separator;
            }

            value_help( ostr );

            if( optional_value_ )
                ostr << ']';

            ostr << '\n';
        }
        if( !p_env_var.empty() )
            ostr << " Environment variable: " << p_env_var << '\n';
    }

    virtual void            help( std::ostream& ostr, cstring negation_prefix_ )
    {
        usage( ostr, negation_prefix_ );

        if( !p_help.empty() )
            ostr << '\n' << p_help << '\n';
    }

protected:
    void                    add_cla_id_impl( cstring prefix,
                                             cstring tag,
                                             cstring value_separator,
                                             bool negatable,
                                             bool validate_value_separator )
    {
        BOOST_TEST_I_ASSRT( !tag.is_empty(),
                            invalid_cla_id() << "Parameter can't have an empty name." );

        BOOST_TEST_I_ASSRT( !prefix.is_empty(),
                            invalid_cla_id() << "Parameter " << tag
                                             << " can't have an empty prefix." );

        BOOST_TEST_I_ASSRT( !value_separator.is_empty(),
                            invalid_cla_id() << "Parameter " << tag
                                             << " can't have an empty value separator." );

        // We trim value separator from all the spaces, so token end will indicate separator
        value_separator.trim();
        BOOST_TEST_I_ASSRT( !validate_value_separator || !value_separator.is_empty() || !p_has_optional_value,
                            invalid_cla_id() << "Parameter " << tag
                                             << " with optional value attribute can't use space as value separator." );

        m_cla_ids.push_back( parameter_cla_id( prefix, tag, value_separator, negatable ) );
    }

private:
    /// interface for usage/help customization
    virtual void            cla_name_help( std::ostream& ostr, cstring cla_tag, cstring /* negation_prefix_ */) const
    {
        ostr << cla_tag;
    }
    virtual void            value_help( std::ostream& ostr ) const
    {
        if( p_value_hint.empty() )
            ostr << "<value>";
        else
            ostr << p_value_hint;
    }

    // Data members
    param_cla_ids       m_cla_ids;
};

// ************************************************************************** //
// **************              runtime::parameter              ************** //
// ************************************************************************** //

enum args_amount {
    OPTIONAL_PARAM,   // 0-1
    REQUIRED_PARAM,   // exactly 1
    REPEATABLE_PARAM  // 0-N
};

//____________________________________________________________________________//

template<typename ValueType, args_amount a = runtime::OPTIONAL_PARAM, bool is_enum = false>
class parameter : public basic_param {
public:
    /// Constructor with modifiers
#ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
    template<typename Modifiers=nfp::no_params_type>
    parameter( cstring name, Modifiers const& m = nfp::no_params )
#else
    template<typename Modifiers>
    parameter( cstring name, Modifiers const& m )
#endif
    : basic_param( name, a != runtime::REQUIRED_PARAM, a == runtime::REPEATABLE_PARAM, m )
    , m_arg_factory( m )
    {
        BOOST_TEST_I_ASSRT( !m.has( default_value ) || a == runtime::OPTIONAL_PARAM,
                            invalid_param_spec() << "Parameter " << name
                                                 << " is not optional and can't have default_value." );

        BOOST_TEST_I_ASSRT( !m.has( optional_value ) || !this->p_repeatable,
                            invalid_param_spec() << "Parameter " << name
                                                 << " is repeatable and can't have optional_value." );
    }

private:
    virtual basic_param_ptr clone() const
    {
        return basic_param_ptr( new parameter( *this ) );
    }
    virtual void    produce_argument( cstring token, bool , arguments_store& store ) const
    {
        m_arg_factory.produce_argument( token, this->p_name, store );
    }
    virtual void    produce_default( arguments_store& store ) const
    {
        if( !this->p_has_default_value )
            return;

        m_arg_factory.produce_default( this->p_name, store );
    }

    // Data members
    typedef argument_factory<ValueType, is_enum, a == runtime::REPEATABLE_PARAM> factory_t;
    factory_t       m_arg_factory;
};

//____________________________________________________________________________//

class option : public basic_param {
public:
    /// Constructor with modifiers
#ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
    template<typename Modifiers=nfp::no_params_type>
    option( cstring name, Modifiers const& m = nfp::no_params )
#else
    template<typename Modifiers>
    option( cstring name, Modifiers const& m )
#endif
    : basic_param( name, true, false, nfp::opt_append( nfp::opt_append( m, optional_value = true), default_value = false) )
    , m_arg_factory( nfp::opt_append( nfp::opt_append( m, optional_value = true), default_value = false) )
    {
    }

    void            add_cla_id( cstring prefix, cstring tag, cstring value_separator, bool negatable = false )
    {
        add_cla_id_impl( prefix, tag, value_separator, negatable, false );
    }

private:
    virtual basic_param_ptr clone() const
    {
        return basic_param_ptr( new option( *this ) );
    }

    virtual void    produce_argument( cstring token, bool negative_form, arguments_store& store ) const
    {
        if( token.empty() )
            store.set( p_name, !negative_form );
        else {
            BOOST_TEST_I_ASSRT( !negative_form,
                                format_error( p_name ) << "Can't set value to negative form of the argument." );

            m_arg_factory.produce_argument( token, p_name, store );
        }
    }

    virtual void    produce_default( arguments_store& store ) const
    {
        m_arg_factory.produce_default( p_name, store );
    }
    virtual void    cla_name_help( std::ostream& ostr, cstring cla_tag, cstring negation_prefix_ ) const
    {
        if( negation_prefix_.is_empty() )
            ostr << cla_tag;
        else
            ostr << '[' << negation_prefix_ << ']' << cla_tag;
    }
    virtual void    value_help( std::ostream& ostr ) const
    {
        if( p_value_hint.empty() )
            ostr << "<boolean value>";
        else
            ostr << p_value_hint;
    }

    // Data members
    typedef argument_factory<bool, false, false> factory_t;
    factory_t       m_arg_factory;
};

//____________________________________________________________________________//

template<typename EnumType, args_amount a = runtime::OPTIONAL_PARAM>
class enum_parameter : public parameter<EnumType, a, true> {
    typedef parameter<EnumType, a, true> base;
public:
    /// Constructor with modifiers
#ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
    template<typename Modifiers=nfp::no_params_type>
    enum_parameter( cstring name, Modifiers const& m = nfp::no_params )
#else
    template<typename Modifiers>
    enum_parameter( cstring name, Modifiers const& m )
#endif
    : base( name, m )
    {
#ifdef BOOST_TEST_CLA_NEW_API
        auto const& values = m[enum_values<EnumType>::value];
        auto it = values.begin();
#else
        std::vector<std::pair<cstring, EnumType> > const& values = m[enum_values<EnumType>::value];
        typename std::vector<std::pair<cstring, EnumType> >::const_iterator it = values.begin();
#endif
        while( it != values.end() ) {
            m_valid_names.push_back( it->first );
            ++it;
        }
    }

private:
    virtual basic_param_ptr clone() const
    {
        return basic_param_ptr( new enum_parameter( *this ) );
    }

    virtual void    value_help( std::ostream& ostr ) const
    {
        if( this->p_value_hint.empty() ) {
            ostr << "<";
            bool first = true;
            BOOST_TEST_FOREACH( cstring, name, m_valid_names ) {
                if( first )
                    first = false;
                else
                    ostr << '|';
                ostr << name;
            }
            ostr << ">";
        }
        else
            ostr << this->p_value_hint;
    }

    // Data members
    std::vector<cstring>    m_valid_names;
};

// ************************************************************************** //
// **************           runtime::parameters_store          ************** //
// ************************************************************************** //

class parameters_store {
    struct lg_compare {
        bool operator()( cstring lh, cstring rh ) const
        {
            return std::lexicographical_compare(lh.begin(), lh.end(),
                                                rh.begin(), rh.end());
        }
    };
public:

    typedef std::map<cstring, basic_param_ptr, lg_compare> storage_type;

    /// Adds parameter into the persistent store
    void                    add( basic_param const& in )
    {
        basic_param_ptr p = in.clone();

        BOOST_TEST_I_ASSRT( m_parameters.insert( std::make_pair( cstring(p->p_name), p ) ).second,
                            duplicate_param() << "Parameter " << p->p_name << " is duplicate." );
    }

    /// Returns true if there is no parameters registered
    bool                    is_empty() const    { return m_parameters.empty(); }
    /// Returns map of all the registered parameter
    storage_type const&     all() const         { return m_parameters; }
    /// Returns true if parameter with psecified name is registered
    bool                    has( cstring name ) const
    {
        return m_parameters.find( name ) != m_parameters.end();
    }
    /// Returns map of all the registered parameter
    basic_param_ptr         get( cstring name ) const
    {
        storage_type::const_iterator const& found = m_parameters.find( name );
        BOOST_TEST_I_ASSRT( found != m_parameters.end(),
                            unknown_param() << "Parameter " << name << " is unknown." );

        return found->second;
    }

private:
    // Data members
    storage_type            m_parameters;
};

} // namespace runtime
} // namespace boost

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

#endif // BOOST_TEST_UTILS_RUNTIME_PARAMETER_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 : simple helpers for creating cusom output manipulators
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_TRIVIAL_SIGNLETON_HPP
#define BOOST_TEST_UTILS_TRIVIAL_SIGNLETON_HPP

// Boost.Test
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>

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

//____________________________________________________________________________//

namespace boost {
namespace unit_test {

// ************************************************************************** //
// **************                   singleton                  ************** //
// ************************************************************************** //

template<typename Derived>
class singleton {
public:
    static Derived& instance() { static Derived the_inst; return the_inst; }

    BOOST_DELETED_FUNCTION(singleton(singleton const&))
    BOOST_DELETED_FUNCTION(singleton& operator=(singleton const&))

protected:
    BOOST_DEFAULTED_FUNCTION(singleton(), {})
    BOOST_DEFAULTED_FUNCTION(~singleton(), {})
};

//____________________________________________________________________________//

#define BOOST_TEST_SINGLETON_CONS( type )       \
friend class boost::unit_test::singleton<type>; \
type() {}                                       \
/**/

#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))

#define BOOST_TEST_SINGLETON_INST( inst ) \
template class unit_test::singleton< BOOST_JOIN( inst, _t ) > ; \
namespace { BOOST_JOIN( inst, _t)& inst = BOOST_JOIN( inst, _t)::instance(); }

#elif defined(__APPLE_CC__) && defined(__GNUC__) && __GNUC__ < 4
#define BOOST_TEST_SINGLETON_INST( inst ) \
static BOOST_JOIN( inst, _t)& inst = BOOST_JOIN (inst, _t)::instance();

#else

#define BOOST_TEST_SINGLETON_INST( inst ) \
namespace { BOOST_JOIN( inst, _t)& inst = BOOST_JOIN( inst, _t)::instance(); }

#endif

//____________________________________________________________________________//

} // namespace unit_test
} // namespace boost

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

#endif // BOOST_TEST_UTILS_TRIVIAL_SIGNLETON_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 : wraps strstream and stringstream (depends with one is present)
//                to provide the unified interface
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_WRAP_STRINGSTREAM_HPP
#define BOOST_TEST_UTILS_WRAP_STRINGSTREAM_HPP

// Boost.Test
#include <boost/test/detail/config.hpp>

// STL
#ifdef BOOST_NO_STRINGSTREAM
#include <strstream>        // for std::ostrstream
#else
#include <sstream>          // for std::ostringstream
#endif // BOOST_NO_STRINGSTREAM

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

//____________________________________________________________________________//

namespace boost {

// ************************************************************************** //
// **************            basic_wrap_stringstream           ************** //
// ************************************************************************** //

template<typename CharT>
class basic_wrap_stringstream {
public:
#if defined(BOOST_CLASSIC_IOSTREAMS)
    typedef std::ostringstream               wrapped_stream;
#elif defined(BOOST_NO_STRINGSTREAM)
    typedef std::basic_ostrstream<CharT>     wrapped_stream;
#else
    typedef std::basic_ostringstream<CharT>  wrapped_stream;
#endif // BOOST_NO_STRINGSTREAM
    // Access methods
    basic_wrap_stringstream&        ref();
    wrapped_stream&                 stream();
    std::basic_string<CharT> const& str();

private:
    // Data members
    wrapped_stream                  m_stream;
    std::basic_string<CharT>        m_str;
};

//____________________________________________________________________________//

template <typename CharT, typename T>
inline basic_wrap_stringstream<CharT>&
operator<<( basic_wrap_stringstream<CharT>& targ, T const& t )
{
    targ.stream() << t;
    return targ;
}

//____________________________________________________________________________//

template <typename CharT>
inline typename basic_wrap_stringstream<CharT>::wrapped_stream&
basic_wrap_stringstream<CharT>::stream()
{
    return m_stream;
}

//____________________________________________________________________________//

template <typename CharT>
inline basic_wrap_stringstream<CharT>&
basic_wrap_stringstream<CharT>::ref()
{
    return *this;
}

//____________________________________________________________________________//

template <typename CharT>
inline std::basic_string<CharT> const&
basic_wrap_stringstream<CharT>::str()
{

#ifdef BOOST_NO_STRINGSTREAM
    m_str.assign( m_stream.str(), m_stream.pcount() );
    m_stream.freeze( false );
#else
    m_str = m_stream.str();
#endif

    return m_str;
}

//____________________________________________________________________________//

template <typename CharT>
inline basic_wrap_stringstream<CharT>&
operator<<( basic_wrap_stringstream<CharT>& targ, basic_wrap_stringstream<CharT>& src )
{
    targ << src.str();
    return targ;
}

//____________________________________________________________________________//

#if BOOST_TEST_USE_STD_LOCALE

template <typename CharT>
inline basic_wrap_stringstream<CharT>&
operator<<( basic_wrap_stringstream<CharT>& targ, std::ios_base& (BOOST_TEST_CALL_DECL *man)(std::ios_base&) )
{
    targ.stream() << man;
    return targ;
}

//____________________________________________________________________________//

template<typename CharT,typename Elem,typename Tr>
inline basic_wrap_stringstream<CharT>&
operator<<( basic_wrap_stringstream<CharT>& targ, std::basic_ostream<Elem,Tr>& (BOOST_TEST_CALL_DECL *man)(std::basic_ostream<Elem, Tr>&) )
{
    targ.stream() << man;
    return targ;
}

//____________________________________________________________________________//

template<typename CharT,typename Elem,typename Tr>
inline basic_wrap_stringstream<CharT>&
operator<<( basic_wrap_stringstream<CharT>& targ, std::basic_ios<Elem, Tr>& (BOOST_TEST_CALL_DECL *man)(std::basic_ios<Elem, Tr>&) )
{
    targ.stream() << man;
    return targ;
}

//____________________________________________________________________________//

#endif

// ************************************************************************** //
// **************               wrap_stringstream              ************** //
// ************************************************************************** //

typedef basic_wrap_stringstream<char>       wrap_stringstream;
typedef basic_wrap_stringstream<wchar_t>    wrap_wstringstream;

}  // namespace boost

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

#endif  // BOOST_TEST_UTILS_WRAP_STRINGSTREAM_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 : common code used by any agent serving as OF_XML printer
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_XML_PRINTER_HPP
#define BOOST_TEST_UTILS_XML_PRINTER_HPP

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

// Boost
#include <boost/config.hpp>

// STL
#include <iostream>

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

//____________________________________________________________________________//

namespace boost {
namespace unit_test {
namespace utils {

// ************************************************************************** //
// **************               xml print helpers              ************** //
// ************************************************************************** //

inline void
print_escaped( std::ostream& where_to, const_string value )
{
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
    static std::map<char,char const*> const char_type{{
        {'<' , "lt"},
        {'>' , "gt"},
        {'&' , "amp"},
        {'\'', "apos"},
        {'"' , "quot"}
    }};
#else
    static std::map<char,char const*> char_type;

    if( char_type.empty() ) {
        char_type['<'] = "lt";
        char_type['>'] = "gt";
        char_type['&'] = "amp";
        char_type['\'']= "apos";
        char_type['"'] = "quot";
    }
#endif

    BOOST_TEST_FOREACH( char, c, value ) {
        std::map<char,char const*>::const_iterator found_ref = char_type.find( c );

        if( found_ref != char_type.end() )
            where_to << '&' << found_ref->second << ';';
        else
            where_to << c;
    }
}

//____________________________________________________________________________//

inline void
print_escaped( std::ostream& where_to, std::string const& value )
{
    print_escaped( where_to, const_string( value ) );
}

//____________________________________________________________________________//

template<typename T>
inline void
print_escaped( std::ostream& where_to, T const& value )
{
    where_to << value;
}

//____________________________________________________________________________//

inline void
print_escaped_cdata( std::ostream& where_to, const_string value )
{
    static const_string cdata_end( "]]>" );

    const_string::size_type pos = value.find( cdata_end );
    if( pos == const_string::npos )
        where_to << value;
    else {
        where_to << value.substr( 0, pos+2 ) << cdata_end
                 << BOOST_TEST_L( "<![CDATA[" ) << value.substr( pos+2 );
    }
}

//____________________________________________________________________________//

typedef custom_manip<struct attr_value_t> attr_value;

template<typename T>
inline std::ostream&
operator<<( custom_printer<attr_value> const& p, T const& value )
{
    *p << "=\"";
    print_escaped( *p, value );
    *p << '"';

    return *p;
}

//____________________________________________________________________________//

typedef custom_manip<struct cdata_t> cdata;

inline std::ostream&
operator<<( custom_printer<cdata> const& p, const_string value )
{
    *p << BOOST_TEST_L( "<![CDATA[" );
    print_escaped_cdata( *p, value );
    return  *p << BOOST_TEST_L( "]]>" );
}

//____________________________________________________________________________//

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

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

#endif // BOOST_TEST_UTILS_XML_PRINTER_HPP


code:
#ifndef BOOST_THREAD_CONDITION_HPP
#define BOOST_THREAD_CONDITION_HPP
//  (C) Copyright 2007 Anthony Williams
//
//  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)

#include <boost/thread/detail/config.hpp>

#if defined BOOST_THREAD_PROVIDES_CONDITION

#include <boost/thread/condition_variable.hpp>

namespace boost
{
    typedef condition_variable_any condition;
}

#endif
#endif


code:
#ifndef BOOST_THREAD_CONDITION_VARIABLE_HPP
#define BOOST_THREAD_CONDITION_VARIABLE_HPP

//  condition_variable.hpp
//
//  (C) Copyright 2007 Anthony Williams
//
//  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)

#include <boost/thread/detail/platform.hpp>
#if defined(BOOST_THREAD_PLATFORM_WIN32)
#include <boost/thread/win32/condition_variable.hpp>
#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
#include <boost/thread/pthread/condition_variable.hpp>
#else
#error "Boost threads unavailable on this platform"
#endif

#endif


code:
// Copyright (C) 2013 Vicente J. Botet Escriba
//
//  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)
//
// 2013/10 Vicente J. Botet Escriba
//   Creation.

#ifndef BOOST_CSBL_FUNCTIONAL_HPP
#define BOOST_CSBL_FUNCTIONAL_HPP

#include <boost/config.hpp>

#include <functional>

#if defined BOOST_THREAD_USES_BOOST_FUNCTIONAL || defined BOOST_NO_CXX11_HDR_FUNCTIONAL || defined BOOST_NO_CXX11_RVALUE_REFERENCES
#ifndef BOOST_THREAD_USES_BOOST_FUNCTIONAL
#define BOOST_THREAD_USES_BOOST_FUNCTIONAL
#endif
#include <boost/function.hpp>
#endif

namespace boost
{
  namespace csbl
  {
#if defined BOOST_THREAD_USES_BOOST_FUNCTIONAL
    using ::boost::function;
#else
    // D.8.1, base (deprecated):
    // 20.9.3, reference_wrapper:
    // 20.9.4, arithmetic operations:
    // 20.9.5, comparisons:
    // 20.9.6, logical operations:
    // 20.9.7, bitwise operations:
    // 20.9.8, negators:
    // 20.9.9, bind:
    // D.9, binders (deprecated):
    // D.8.2.1, adaptors (deprecated):
    // D.8.2.2, adaptors (deprecated):
    // 20.9.10, member function adaptors:
    // 20.9.11 polymorphic function wrappers:
    using ::std::function;
    // 20.9.12, hash function primary template:
#endif

  }
}
#endif // header


code:
// Copyright (C) 2013 Vicente J. Botet Escriba
//
//  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)
//
// 2013/10 Vicente J. Botet Escriba
//   Creation.

#ifndef BOOST_CSBL_MEMORY_ALLOCATOR_ARG_HPP
#define BOOST_CSBL_MEMORY_ALLOCATOR_ARG_HPP

#include <boost/thread/csbl/memory/config.hpp>

// 20.7.6, allocator argument tag
#if defined BOOST_NO_CXX11_ALLOCATOR
#include <boost/container/scoped_allocator.hpp>

namespace boost
{
  namespace csbl
  {
    using ::boost::container::allocator_arg_t;
    using ::boost::container::allocator_arg;
  }
}
#else
namespace boost
{
  namespace csbl
  {
    using ::std::allocator_arg_t;
    using ::std::allocator_arg;
  }
}
#endif // BOOST_NO_CXX11_ALLOCATOR
namespace boost
{
  using ::boost::csbl::allocator_arg_t;
  using ::boost::csbl::allocator_arg;
}
#endif // header


code:
// Copyright (C) 2013 Vicente J. Botet Escriba
//
//  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)
//
// 2013/10 Vicente J. Botet Escriba
//   Creation.

#ifndef BOOST_CSBL_MEMORY_ALLOCATOR_TRAITS_HPP
#define BOOST_CSBL_MEMORY_ALLOCATOR_TRAITS_HPP

#include <boost/thread/csbl/memory/config.hpp>

// 20.7.8, allocator traits
#if defined BOOST_NO_CXX11_ALLOCATOR
#include <boost/container/allocator_traits.hpp>

namespace boost
{
  namespace csbl
  {
    using ::boost::container::allocator_traits;
  }
}
#else
namespace boost
{
  namespace csbl
  {
    using ::std::allocator_traits;
  }
}
#endif // BOOST_NO_CXX11_POINTER_TRAITS

#endif // header


code:
// Copyright (C) 2013 Vicente J. Botet Escriba
//
//  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)
//
// 2013/10 Vicente J. Botet Escriba
//   Creation.

#ifndef BOOST_CSBL_MEMORY_CONFIG_HPP
#define BOOST_CSBL_MEMORY_CONFIG_HPP

#include <boost/config.hpp>

#include <memory>

#endif // header


code:
// Copyright (C) 2013 Vicente J. Botet Escriba
//
//  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)
//
// 2013/10 Vicente J. Botet Escriba
//   Creation.

#ifndef BOOST_CSBL_MEMORY_POINTER_TRAITS_HPP
#define BOOST_CSBL_MEMORY_POINTER_TRAITS_HPP

#include <boost/thread/csbl/memory/config.hpp>

// 20.7.3, pointer traits
#if defined BOOST_NO_CXX11_ALLOCATOR
#include <boost/intrusive/pointer_traits.hpp>

namespace boost
{
  namespace csbl
  {
    using ::boost::intrusive::pointer_traits;
  }
}
#else
namespace boost
{
  namespace csbl
  {
    using ::std::pointer_traits;
  }
}
#endif // BOOST_NO_CXX11_ALLOCATOR

#endif // header


code:
// Copyright (C) 2013 Vicente J. Botet Escriba
//
//  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)
//
// 2013/10 Vicente J. Botet Escriba
//   Creation.

#ifndef BOOST_CSBL_MEMORY_SCOPED_ALLOCATOR_HPP
#define BOOST_CSBL_MEMORY_SCOPED_ALLOCATOR_HPP

#include <boost/thread/csbl/memory/config.hpp>

// 20.7.7, uses_allocator
#if defined BOOST_NO_CXX11_ALLOCATOR
#include <boost/container/scoped_allocator.hpp>

namespace boost
{
  namespace csbl
  {
    using ::boost::container::uses_allocator;
  }
}
#else
namespace boost
{
  namespace csbl
  {
    using ::std::uses_allocator;
  }
}
#endif // BOOST_NO_CXX11_POINTER_TRAITS

#endif // header


code:
// Copyright (C) 2014 Vicente J. Botet Escriba
//
//  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)
//
// 2014/10 Vicente J. Botet Escriba
//   Creation.

#ifndef BOOST_CSBL_MEMORY_SHARED_PTR_HPP
#define BOOST_CSBL_MEMORY_SHARED_PTR_HPP

#include <boost/thread/csbl/memory/config.hpp>

#if defined BOOST_NO_CXX11_SMART_PTR

#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared.hpp>

namespace boost
{
  namespace csbl
  {
    using ::boost::shared_ptr;
    using ::boost::make_shared;
  }
}

#else

#include <boost/shared_ptr.hpp>

namespace boost
{
  namespace csbl
  {
    using std::shared_ptr;
    using std::make_shared;
  }
}

#endif
#endif // header


code:
// Copyright (C) 2013-2014 Vicente J. Botet Escriba
//
//  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)
//
// 2013/10 Vicente J. Botet Escriba
//   Creation using interprocess::unique_ptr.
// 2014/09 Vicente J. Botet Escriba
//   Adaptation to movelib::unique_ptr

#ifndef BOOST_CSBL_MEMORY_UNIQUE_PTR_HPP
#define BOOST_CSBL_MEMORY_UNIQUE_PTR_HPP

#include <boost/thread/csbl/memory/config.hpp>

#include <boost/move/unique_ptr.hpp>
#include <boost/move/make_unique.hpp>

namespace boost
{
  namespace csbl
  {
    using ::boost::movelib::unique_ptr;
    using ::boost::movelib::make_unique;

  }
}
#endif // header


code:
// Copyright (C) 2013 Vicente J. Botet Escriba
//
//  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)
//
// 2013/10 Vicente J. Botet Escriba
//   Creation.

#ifndef BOOST_CSBL_TUPLE_HPP
#define BOOST_CSBL_TUPLE_HPP

#include <boost/config.hpp>

#if defined BOOST_THREAD_USES_BOOST_TUPLE || defined BOOST_NO_CXX11_HDR_TUPLE || defined BOOST_NO_CXX11_RVALUE_REFERENCES
#include <boost/tuple/tuple.hpp>
#ifndef BOOST_THREAD_USES_BOOST_TUPLE
#define BOOST_THREAD_USES_BOOST_TUPLE
#endif

#else
#include <tuple>
#endif

namespace boost
{
  namespace csbl
  {
#if defined BOOST_THREAD_USES_BOOST_TUPLE
    using ::boost::tuple;
    using ::boost::get;
    using ::boost::make_tuple;
    //using ::boost::tuple_size;
#else
    // 20.4.2, class template tuple:
    using ::std::tuple;
    using ::std::get;
    using ::std::make_tuple;
    using ::std::tuple_size;
    // 20.4.2.4, tuple creation functions:
    // 20.4.2.5, tuple helper classes:
    // 20.4.2.6, element access:
    // 20.4.2.7, relational operators:
    // 20.4.2.8, allocator-related traits
    // 20.4.2.9, specialized algorithms:
#endif

  }
}
#endif // header


code:
// Copyright (C) 2013 Vicente J. Botet Escriba
//
//  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)
//
// 2013/10 Vicente J. Botet Escriba
//   Creation.

#ifndef BOOST_CSBL_VECTOR_HPP
#define BOOST_CSBL_VECTOR_HPP

#include <boost/config.hpp>

#if defined BOOST_THREAD_USES_BOOST_VECTOR || defined BOOST_NO_CXX11_RVALUE_REFERENCES || defined BOOST_MSVC
#ifndef BOOST_THREAD_USES_BOOST_VECTOR
#define BOOST_THREAD_USES_BOOST_VECTOR
#endif
#include <boost/container/vector.hpp>
#else
#include <vector>
#endif

namespace boost
{
  namespace csbl
  {
#if defined BOOST_THREAD_USES_BOOST_VECTOR
    using ::boost::container::vector;
#else
    using ::std::vector;
#endif

  }
}
#endif // header


code:
//  cv_status.hpp
//
// Copyright (C) 2011 Vicente J. Botet Escriba
//
//  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)

#ifndef BOOST_THREAD_CV_STATUS_HPP
#define BOOST_THREAD_CV_STATUS_HPP

#include <boost/core/scoped_enum.hpp>

namespace boost
{

  // enum class cv_status;
  BOOST_SCOPED_ENUM_DECLARE_BEGIN(cv_status)
  {
    no_timeout,
    timeout
  }
  BOOST_SCOPED_ENUM_DECLARE_END(cv_status)
}

#endif // header


code:
// Copyright (C) 2001-2003
// William E. Kempf
// Copyright (C) 2011-2013 Vicente J. Botet Escriba
//
//  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)

#ifndef BOOST_THREAD_CONFIG_WEK01032003_HPP
#define BOOST_THREAD_CONFIG_WEK01032003_HPP

#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/thread/detail/platform.hpp>

//#define BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
// ATTRIBUTE_MAY_ALIAS

#if defined(__GNUC__) && !defined(__INTEL_COMPILER)

  // GCC since 3.3 has may_alias attribute that helps to alleviate optimizer issues with
  // regard to violation of the strict aliasing rules.

  #define BOOST_THREAD_DETAIL_USE_ATTRIBUTE_MAY_ALIAS
  #define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
#else
  #define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS
#endif

#if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
#define BOOST_THREAD_ASSERT_PRECONDITION(EXPR, EX) \
        if (EXPR) {} else boost::throw_exception(EX)
#define BOOST_THREAD_VERIFY_PRECONDITION(EXPR, EX) \
        if (EXPR) {} else boost::throw_exception(EX)
#define BOOST_THREAD_THROW_ELSE_RETURN(EX, RET) \
        boost::throw_exception(EX)
#else
#define BOOST_THREAD_ASSERT_PRECONDITION(EXPR, EX)
#define BOOST_THREAD_VERIFY_PRECONDITION(EXPR, EX) \
        (void)(EXPR)
#define BOOST_THREAD_THROW_ELSE_RETURN(EX, RET) \
        return (RET)
#endif

// This compiler doesn't support Boost.Chrono
#if defined __IBMCPP__ && (__IBMCPP__ < 1100) \
  && ! defined BOOST_THREAD_DONT_USE_CHRONO
#define BOOST_THREAD_DONT_USE_CHRONO
#if ! defined BOOST_THREAD_USES_DATETIME
#define BOOST_THREAD_USES_DATETIME
#endif
#endif

// This compiler doesn't support Boost.Move
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) \
  && ! defined BOOST_THREAD_DONT_USE_MOVE
#define BOOST_THREAD_DONT_USE_MOVE
#endif

// This compiler doesn't support Boost.Container Allocators files
#if defined __SUNPRO_CC \
  && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
#define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
#endif

#if defined _WIN32_WCE && _WIN32_WCE==0x501 \
  && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
#define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
#endif

#if defined BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX || defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#define BOOST_THREAD_NO_CXX11_HDR_INITIALIZER_LIST
#define BOOST_THREAD_NO_MAKE_LOCK_GUARD
#define BOOST_THREAD_NO_MAKE_STRICT_LOCK
#define BOOST_THREAD_NO_MAKE_NESTED_STRICT_LOCK
#endif

#if defined(BOOST_NO_CXX11_HDR_TUPLE) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#define BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS
#define BOOST_THREAD_NO_SYNCHRONIZE
#elif defined _MSC_VER && _MSC_VER <= 1600
// C++ features supported by VC++ 10 (aka 2010)
#define BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS
#define BOOST_THREAD_NO_SYNCHRONIZE
#endif

/// BASIC_THREAD_ID
#if ! defined BOOST_THREAD_DONT_PROVIDE_BASIC_THREAD_ID \
 && ! defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
#define BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
#endif

/// RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
//#if defined BOOST_NO_CXX11_RVALUE_REFERENCES || defined BOOST_MSVC
#define BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
//#endif

// Default version
#if !defined BOOST_THREAD_VERSION
#define BOOST_THREAD_VERSION 2
#else
#if BOOST_THREAD_VERSION!=2  && BOOST_THREAD_VERSION!=3 && BOOST_THREAD_VERSION!=4 && BOOST_THREAD_VERSION!=5
#error "BOOST_THREAD_VERSION must be 2, 3, 4 or 5"
#endif
#endif

// CHRONO
// Uses Boost.Chrono by default if not stated the opposite defining BOOST_THREAD_DONT_USE_CHRONO
#if ! defined BOOST_THREAD_DONT_USE_CHRONO \
  && ! defined BOOST_THREAD_USES_CHRONO
#define BOOST_THREAD_USES_CHRONO
#endif

#if ! defined BOOST_THREAD_DONT_USE_ATOMIC \
  && ! defined BOOST_THREAD_USES_ATOMIC
#define BOOST_THREAD_USES_ATOMIC
//#define BOOST_THREAD_DONT_USE_ATOMIC
#endif

#if defined BOOST_THREAD_USES_ATOMIC
// Andrey Semashev
#define BOOST_THREAD_ONCE_ATOMIC
#else
//#elif ! defined BOOST_NO_CXX11_THREAD_LOCAL && ! defined BOOST_NO_THREAD_LOCAL && ! defined BOOST_THREAD_NO_UINT32_PSEUDO_ATOMIC
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2444.html#Appendix
#define BOOST_THREAD_ONCE_FAST_EPOCH
#endif
#if BOOST_THREAD_VERSION==2

// PROVIDE_PROMISE_LAZY
#if ! defined BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY \
  && ! defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
#define BOOST_THREAD_PROVIDES_PROMISE_LAZY
#endif

// PROVIDE_THREAD_EQ
#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_EQ \
  && ! defined BOOST_THREAD_PROVIDES_THREAD_EQ
#define BOOST_THREAD_PROVIDES_THREAD_EQ
#endif

#endif

#if BOOST_THREAD_VERSION>=3

// ONCE_CXX11
// fixme BOOST_THREAD_PROVIDES_ONCE_CXX11 doesn't works when thread.cpp is compiled BOOST_THREAD_VERSION 3
#if ! defined BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11 \
 && ! defined BOOST_THREAD_PROVIDES_ONCE_CXX11
#define BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11
#endif

// THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE \
 && ! defined BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
#define BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
#endif

// THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE \
 && ! defined BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
#define BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
#endif

// PROVIDE_FUTURE
#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE \
 && ! defined BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE
#endif

// FUTURE_CTOR_ALLOCATORS
#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS \
 && ! defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
#define BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
#endif

// SHARED_MUTEX_UPWARDS_CONVERSIONS
#if ! defined BOOST_THREAD_DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSIONS \
 && ! defined BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
#endif

// PROVIDE_EXPLICIT_LOCK_CONVERSION
#if ! defined BOOST_THREAD_DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION \
 && ! defined BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
#endif

// GENERIC_SHARED_MUTEX_ON_WIN
#if ! defined BOOST_THREAD_DONT_PROVIDE_GENERIC_SHARED_MUTEX_ON_WIN \
 && ! defined BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
#endif

// USE_MOVE
#if ! defined BOOST_THREAD_DONT_USE_MOVE \
 && ! defined BOOST_THREAD_USES_MOVE
#define BOOST_THREAD_USES_MOVE
#endif

#endif

// deprecated since version 4
#if BOOST_THREAD_VERSION < 4

// NESTED_LOCKS
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS \
 && ! defined BOOST_THREAD_DONT_PROVIDE_NESTED_LOCKS
#define BOOST_THREAD_PROVIDES_NESTED_LOCKS
#endif

// CONDITION
#if ! defined BOOST_THREAD_PROVIDES_CONDITION \
 && ! defined BOOST_THREAD_DONT_PROVIDE_CONDITION
#define BOOST_THREAD_PROVIDES_CONDITION
#endif

// USE_DATETIME
#if ! defined BOOST_THREAD_DONT_USE_DATETIME \
 && ! defined BOOST_THREAD_USES_DATETIME
#define BOOST_THREAD_USES_DATETIME
#endif
#endif

#if BOOST_THREAD_VERSION>=4

// SIGNATURE_PACKAGED_TASK
#if ! defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK \
 && ! defined BOOST_THREAD_DONT_PROVIDE_SIGNATURE_PACKAGED_TASK
#define BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
#endif

// VARIADIC_THREAD
#if ! defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD \
 && ! defined BOOST_THREAD_DONT_PROVIDE_VARIADIC_THREAD

#if ! defined(BOOST_NO_SFINAE_EXPR) && \
    ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
    ! defined(BOOST_NO_CXX11_DECLTYPE) && \
    ! defined(BOOST_NO_CXX11_DECLTYPE_N3276) && \
    ! defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) && \
    ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
    ! defined(BOOST_NO_CXX11_HDR_TUPLE)

#define BOOST_THREAD_PROVIDES_VARIADIC_THREAD
#endif
#endif

#if ! defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY \
 && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_WHEN_ALL_WHEN_ANY

#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
    ! defined(BOOST_NO_CXX11_HDR_TUPLE)

#define BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
#endif
#endif

//    ! defined(BOOST_NO_SFINAE_EXPR) &&
//    ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) &&
//    ! defined(BOOST_NO_CXX11_AUTO) &&
//    ! defined(BOOST_NO_CXX11_DECLTYPE) &&
//    ! defined(BOOST_NO_CXX11_DECLTYPE_N3276) &&

// MAKE_READY_AT_THREAD_EXIT
#if ! defined BOOST_THREAD_PROVIDES_MAKE_READY_AT_THREAD_EXIT \
 && ! defined BOOST_THREAD_DONT_PROVIDE_MAKE_READY_AT_THREAD_EXIT

//#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
#define BOOST_THREAD_PROVIDES_MAKE_READY_AT_THREAD_EXIT
//#endif
#endif

// FUTURE_CONTINUATION
#if ! defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION \
 && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CONTINUATION
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#endif

#if ! defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP \
 && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_UNWRAP
#define BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
#endif

// FUTURE_INVALID_AFTER_GET
#if ! defined BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET \
 && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET
#define BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
#endif

// NESTED_LOCKS
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS \
 && ! defined BOOST_THREAD_DONT_PROVIDE_NESTED_LOCKS
#define BOOST_THREAD_DONT_PROVIDE_NESTED_LOCKS
#endif

// CONDITION
#if ! defined BOOST_THREAD_PROVIDES_CONDITION \
 && ! defined BOOST_THREAD_DONT_PROVIDE_CONDITION
#define BOOST_THREAD_DONT_PROVIDE_CONDITION
#endif

#endif // BOOST_THREAD_VERSION>=4

#if BOOST_THREAD_VERSION>=5
//#define BOOST_THREAD_FUTURE_BLOCKING
#else
//#define BOOST_THREAD_FUTURE_BLOCKING
#define BOOST_THREAD_ASYNC_FUTURE_WAITS
#endif
// INTERRUPTIONS
#if ! defined BOOST_THREAD_PROVIDES_INTERRUPTIONS \
 && ! defined BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
#endif

// CORRELATIONS

// EXPLICIT_LOCK_CONVERSION.
#if defined BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
#define BOOST_THREAD_EXPLICIT_LOCK_CONVERSION explicit
#else
#define BOOST_THREAD_EXPLICIT_LOCK_CONVERSION
#endif

// BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN is defined if BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
#if defined BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS \
&& ! defined BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
#endif

// For C++11 call_once interface the compiler MUST support constexpr.
// Otherwise once_flag would be initialized during dynamic initialization stage, which is not thread-safe.
#if defined(BOOST_THREAD_PROVIDES_ONCE_CXX11)
#if defined(BOOST_NO_CXX11_CONSTEXPR)
#undef BOOST_THREAD_PROVIDES_ONCE_CXX11
#endif
#endif

#if defined(BOOST_THREAD_PLATFORM_WIN32) && defined BOOST_THREAD_DONT_USE_DATETIME
#undef BOOST_THREAD_DONT_USE_DATETIME
#define BOOST_THREAD_USES_DATETIME
#endif

#if defined(BOOST_THREAD_PLATFORM_WIN32) && defined BOOST_THREAD_DONT_USE_CHRONO
#undef BOOST_THREAD_DONT_USE_CHRONO
#define BOOST_THREAD_USES_CHRONO
#endif

// BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.55
// BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.55
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0

#if  ! defined BOOST_THREAD_PROVIDES_THREAD_EQ
#define BOOST_THREAD_PROVIDES_THREAD_EQ
#endif

#endif

//#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES || defined BOOST_THREAD_USES_MOVE
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_THREAD_FUTURE_USES_OPTIONAL
#endif

#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
#  pragma warn -8008 // Condition always true/false
#  pragma warn -8080 // Identifier declared but never used
#  pragma warn -8057 // Parameter never used
#  pragma warn -8066 // Unreachable code
#endif

#include <boost/thread/detail/platform.hpp>

#if defined(BOOST_THREAD_PLATFORM_WIN32)
#else
  #   if defined(BOOST_HAS_PTHREAD_DELAY_NP) || defined(BOOST_HAS_NANOSLEEP)
  #     define BOOST_THREAD_SLEEP_FOR_IS_STEADY
  #   endif
#endif

// provided for backwards compatibility, since this
// macro was used for several releases by mistake.
#if defined(BOOST_THREAD_DYN_DLL) && ! defined BOOST_THREAD_DYN_LINK
# define BOOST_THREAD_DYN_LINK
#endif

// compatibility with the rest of Boost's auto-linking code:
#if defined(BOOST_THREAD_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
# undef  BOOST_THREAD_USE_LIB
# if !defined(BOOST_THREAD_USE_DLL)
#  define BOOST_THREAD_USE_DLL
# endif
#endif

#if defined(BOOST_THREAD_BUILD_DLL)   //Build dll
#elif defined(BOOST_THREAD_BUILD_LIB) //Build lib
#elif defined(BOOST_THREAD_USE_DLL)   //Use dll
#elif defined(BOOST_THREAD_USE_LIB)   //Use lib
#else //Use default
#   if defined(BOOST_THREAD_PLATFORM_WIN32)
#       if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) \
      || defined(__MINGW32__) || defined(MINGW32) || defined(BOOST_MINGW32)
      //For compilers supporting auto-tss cleanup
            //with Boost.Threads lib, use Boost.Threads lib
#           define BOOST_THREAD_USE_LIB
#       else
            //For compilers not yet supporting auto-tss cleanup
            //with Boost.Threads lib, use Boost.Threads dll
#           define BOOST_THREAD_USE_DLL
#       endif
#   else
#       define BOOST_THREAD_USE_LIB
#   endif
#endif

#if defined(BOOST_HAS_DECLSPEC)
#   if defined(BOOST_THREAD_BUILD_DLL) //Build dll
#       define BOOST_THREAD_DECL BOOST_SYMBOL_EXPORT
//#       define BOOST_THREAD_DECL __declspec(dllexport)

#   elif defined(BOOST_THREAD_USE_DLL) //Use dll
#       define BOOST_THREAD_DECL BOOST_SYMBOL_IMPORT
//#       define BOOST_THREAD_DECL __declspec(dllimport)
#   else
#       define BOOST_THREAD_DECL
#   endif
#elif (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
#  define BOOST_THREAD_DECL BOOST_SYMBOL_VISIBLE

#else
#   define BOOST_THREAD_DECL
#endif // BOOST_HAS_DECLSPEC

//
// Automatically link to the correct build variant where possible.
//
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_THREAD_NO_LIB) && !defined(BOOST_THREAD_BUILD_DLL) && !defined(BOOST_THREAD_BUILD_LIB)
//
// Tell the autolink to link dynamically, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#if defined(BOOST_THREAD_USE_DLL)
#   define BOOST_DYN_LINK
#endif
//
// Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#if defined(BOOST_THREAD_LIB_NAME)
#    define BOOST_LIB_NAME BOOST_THREAD_LIB_NAME
#else
#    define BOOST_LIB_NAME boost_thread
#endif
//
// If we're importing code from a dll, then tell auto_link.hpp about it:
//
// And include the header that does the work:
//
#include <boost/config/auto_link.hpp>
#endif  // auto-linking disabled

#endif // BOOST_THREAD_CONFIG_WEK1032003_HPP

// Change Log:
//   22 Jan 05 Roland Schwarz (speedsnail)
//      Usage of BOOST_HAS_DECLSPEC macro.
//      Default again is static lib usage.
//      BOOST_DYN_LINK only defined when autolink included.


code:
// Copyright (C) 2012 Vicente J. Botet Escriba
//
//  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)

#ifndef BOOST_THREAD_DETAIL_DELETE_HPP
#define BOOST_THREAD_DETAIL_DELETE_HPP

#include <boost/config.hpp>

/**
 * BOOST_THREAD_DELETE_COPY_CTOR deletes the copy constructor when the compiler supports it or
 * makes it private.
 *
 * BOOST_THREAD_DELETE_COPY_ASSIGN deletes the copy assignment when the compiler supports it or
 * makes it private.
 */

#if ! defined BOOST_NO_CXX11_DELETED_FUNCTIONS && ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \
      CLASS(CLASS const&) = delete; \

#define BOOST_THREAD_DELETE_COPY_ASSIGN(CLASS) \
      CLASS& operator=(CLASS const&) = delete;

#else // BOOST_NO_CXX11_DELETED_FUNCTIONS
#if defined(BOOST_MSVC) && _MSC_VER >= 1600
#define BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \
    private: \
      CLASS(CLASS const&); \
    public:

#define BOOST_THREAD_DELETE_COPY_ASSIGN(CLASS) \
    private: \
      CLASS& operator=(CLASS const&); \
    public:
#else
#define BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \
    private: \
      CLASS(CLASS&); \
    public:

#define BOOST_THREAD_DELETE_COPY_ASSIGN(CLASS) \
    private: \
      CLASS& operator=(CLASS&); \
    public:
#endif
#endif // BOOST_NO_CXX11_DELETED_FUNCTIONS

/**
 * BOOST_THREAD_NO_COPYABLE deletes the copy constructor and assignment when the compiler supports it or
 * makes them private.
 */
#define BOOST_THREAD_NO_COPYABLE(CLASS) \
    BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \
    BOOST_THREAD_DELETE_COPY_ASSIGN(CLASS)

#endif // BOOST_THREAD_DETAIL_DELETE_HPP