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 : supplies offline implementation for the Test Tools
// ***************************************************************************

#ifndef BOOST_TEST_TEST_TOOLS_IPP_012205GER
#define BOOST_TEST_TEST_TOOLS_IPP_012205GER

// Boost.Test
#include <boost/test/unit_test_log.hpp>
#include <boost/test/tools/context.hpp>
#include <boost/test/tools/output_test_stream.hpp>

#include <boost/test/tools/detail/fwd.hpp>
#include <boost/test/tools/detail/print_helper.hpp>

#include <boost/test/framework.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/execution_monitor.hpp> // execution_aborted

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

#include <boost/test/utils/algorithm.hpp>

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

// STL
#include <fstream>
#include <string>
#include <cstring>
#include <cctype>
#include <cwchar>
#include <stdexcept>
#include <vector>
#include <utility>
#include <ios>

// !! should we use #include <cstdarg>
#include <stdarg.h>

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

//____________________________________________________________________________//

# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::strcmp; using ::strlen; using ::isprint; }
#if !defined( BOOST_NO_CWCHAR )
namespace std { using ::wcscmp; }
#endif
# endif

namespace boost {
namespace test_tools {
namespace tt_detail {

// ************************************************************************** //
// **************                print_log_value               ************** //
// ************************************************************************** //

void
print_log_value<char>::operator()( std::ostream& ostr, char t )
{
    if( (std::isprint)( static_cast<unsigned char>(t) ) )
        ostr << '\'' << t << '\'';
    else
        ostr << std::hex
#if BOOST_TEST_USE_STD_LOCALE
        << std::showbase
#else
        << "0x"
#endif
        << static_cast<int>(t);
}

//____________________________________________________________________________//

void
print_log_value<unsigned char>::operator()( std::ostream& ostr, unsigned char t )
{
    ostr << std::hex
        // showbase is only available for new style streams:
#if BOOST_TEST_USE_STD_LOCALE
        << std::showbase
#else
        << "0x"
#endif
        << static_cast<int>(t);
}

//____________________________________________________________________________//

void
print_log_value<char const*>::operator()( std::ostream& ostr, char const* t )
{
    ostr << ( t ? t : "null string" );
}

//____________________________________________________________________________//

void
print_log_value<wchar_t const*>::operator()( std::ostream& ostr, wchar_t const* t )
{
    ostr << ( t ? t : L"null string" );
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************            TOOL BOX Implementation           ************** //
// ************************************************************************** //

using ::boost::unit_test::lazy_ostream;

static char const* check_str [] = { " == ", " != ", " < " , " <= ", " > " , " >= " };
static char const* rever_str [] = { " != ", " == ", " >= ", " > " , " <= ", " < "  };

template<typename OutStream>
void
format_report( OutStream& os, assertion_result const& pr, unit_test::lazy_ostream const& assertion_descr,
               tool_level tl, check_type ct,
               std::size_t num_args, va_list args,
               char const*  prefix, char const*  suffix )
{
    using namespace unit_test;

    switch( ct ) {
    case CHECK_PRED:
        os << prefix << assertion_descr << suffix;

        if( !pr.has_empty_message() )
            os << ". " << pr.message();
        break;

    case CHECK_BUILT_ASSERTION: {
        os << prefix << assertion_descr << suffix;

        if( tl != PASS ) {
            const_string details_message = pr.message();

            if( !details_message.is_empty() ) {
                os << details_message;
            }
        }
        break;
    }

    case CHECK_MSG:
        if( tl == PASS )
            os << prefix << "'" << assertion_descr << "'" << suffix;
        else
            os << assertion_descr;

        if( !pr.has_empty_message() )
            os << ". " << pr.message();
        break;

    case CHECK_EQUAL:
    case CHECK_NE:
    case CHECK_LT:
    case CHECK_LE:
    case CHECK_GT:
    case CHECK_GE: {
        char const*         arg1_descr  = va_arg( args, char const* );
        lazy_ostream const* arg1_val    = va_arg( args, lazy_ostream const* );
        char const*         arg2_descr  = va_arg( args, char const* );
        lazy_ostream const* arg2_val    = va_arg( args, lazy_ostream const* );

        os << prefix << arg1_descr << check_str[ct-CHECK_EQUAL] << arg2_descr << suffix;

        if( tl != PASS )
            os << " [" << *arg1_val << rever_str[ct-CHECK_EQUAL] << *arg2_val << "]" ;

        if( !pr.has_empty_message() )
            os << ". " << pr.message();
        break;
    }

    case CHECK_CLOSE:
    case CHECK_CLOSE_FRACTION: {
        char const*         arg1_descr  = va_arg( args, char const* );
        lazy_ostream const* arg1_val    = va_arg( args, lazy_ostream const* );
        char const*         arg2_descr  = va_arg( args, char const* );
        lazy_ostream const* arg2_val    = va_arg( args, lazy_ostream const* );
        /* toler_descr = */               va_arg( args, char const* );
        lazy_ostream const* toler_val   = va_arg( args, lazy_ostream const* );

        os << "difference{" << pr.message()
                            << "} between " << arg1_descr << "{" << *arg1_val
                            << "} and "               << arg2_descr << "{" << *arg2_val
                            << ( tl == PASS ? "} doesn't exceed " : "} exceeds " )
                            << *toler_val;
        if( ct == CHECK_CLOSE )
            os << "%";
        break;
    }
    case CHECK_SMALL: {
        char const*         arg1_descr  = va_arg( args, char const* );
        lazy_ostream const* arg1_val    = va_arg( args, lazy_ostream const* );
        /* toler_descr = */               va_arg( args, char const* );
        lazy_ostream const* toler_val   = va_arg( args, lazy_ostream const* );

        os << "absolute value of " << arg1_descr << "{" << *arg1_val << "}"
                                   << ( tl == PASS ? " doesn't exceed " : " exceeds " )
                                   << *toler_val;

        if( !pr.has_empty_message() )
            os << ". " << pr.message();
        break;
    }

    case CHECK_PRED_WITH_ARGS: {
        std::vector< std::pair<char const*, lazy_ostream const*> > args_copy;
        args_copy.reserve( num_args );
        for( std::size_t i = 0; i < num_args; ++i ) {
            char const* desc = va_arg( args, char const* );
            lazy_ostream const* value = va_arg( args, lazy_ostream const* );
            args_copy.push_back( std::make_pair( desc, value ) );
        }

        os << prefix << assertion_descr;

        // print predicate call description
        os << "( ";
        for( std::size_t i = 0; i < num_args; ++i ) {
            os << args_copy[i].first;

            if( i != num_args-1 )
                os << ", ";
        }
        os << " )" << suffix;

        if( tl != PASS ) {
            os << " for ( ";
            for( std::size_t i = 0; i < num_args; ++i ) {
                os << *args_copy[i].second;

                if( i != num_args-1 )
                    os << ", ";
            }
            os << " )";
        }

        if( !pr.has_empty_message() )
            os << ". " << pr.message();
        break;
    }

    case CHECK_EQUAL_COLL: {
        char const* left_begin_descr    = va_arg( args, char const* );
        char const* left_end_descr      = va_arg( args, char const* );
        char const* right_begin_descr   = va_arg( args, char const* );
        char const* right_end_descr     = va_arg( args, char const* );

        os << prefix << "{ " << left_begin_descr  << ", " << left_end_descr  << " } == { "
                             << right_begin_descr << ", " << right_end_descr << " }"
           << suffix;

        if( !pr.has_empty_message() )
            os << ". " << pr.message();
        break;
    }

    case CHECK_BITWISE_EQUAL: {
        char const* left_descr    = va_arg( args, char const* );
        char const* right_descr   = va_arg( args, char const* );

        os << prefix << left_descr  << " =.= " << right_descr << suffix;

        if( !pr.has_empty_message() )
            os << ". " << pr.message();
        break;
    }
    }
}

//____________________________________________________________________________//

bool
report_assertion( assertion_result const&   ar,
                  lazy_ostream const&       assertion_descr,
                  const_string              file_name,
                  std::size_t               line_num,
                  tool_level                tl,
                  check_type                ct,
                  std::size_t               num_args, ... )
{
    using namespace unit_test;

    BOOST_TEST_I_ASSRT( framework::current_test_case_id() != INV_TEST_UNIT_ID,
                        std::runtime_error( "Can't use testing tools outside of test case implementation." ) );

    if( !!ar )
        tl = PASS;

    log_level    ll;
    char const*  prefix;
    char const*  suffix;

    switch( tl ) {
    case PASS:
        ll      = log_successful_tests;
        prefix  = "check ";
        suffix  = " has passed";
        break;
    case WARN:
        ll      = log_warnings;
        prefix  = "condition ";
        suffix  = " is not satisfied";
        break;
    case CHECK:
        ll      = log_all_errors;
        prefix  = "check ";
        suffix  = " has failed";
        break;
    case REQUIRE:
        ll      = log_fatal_errors;
        prefix  = "critical check ";
        suffix  = " has failed";
        break;
    default:
        return true;
    }

    unit_test_log << unit_test::log::begin( file_name, line_num ) << ll;
    va_list args;
    va_start( args, num_args );

    format_report( unit_test_log, ar, assertion_descr, tl, ct, num_args, args, prefix, suffix );

    va_end( args );
    unit_test_log << unit_test::log::end();

    switch( tl ) {
    case PASS:
        framework::assertion_result( AR_PASSED );
        return true;

    case WARN:
        framework::assertion_result( AR_TRIGGERED );
        return false;

    case CHECK:
        framework::assertion_result( AR_FAILED );
        return false;

    case REQUIRE:
        framework::assertion_result( AR_FAILED );

        framework::test_unit_aborted( framework::current_test_case() );

        BOOST_TEST_I_THROW( execution_aborted() );
    }

    return true;
}

//____________________________________________________________________________//

assertion_result
format_assertion_result( const_string expr_val, const_string details )
{
    assertion_result res(false);

    bool starts_new_line = first_char( expr_val ) == '\n';

    if( !starts_new_line && !expr_val.is_empty() )
        res.message().stream() << " [" << expr_val << "]";

    if( !details.is_empty() ) {
        if( first_char(details) != '[' )
            res.message().stream() << ". ";
        else
            res.message().stream() << " ";

        res.message().stream() << details;
    }

    if( starts_new_line )
        res.message().stream() << "." << expr_val;

    return res;
}

//____________________________________________________________________________//

BOOST_TEST_DECL std::string
prod_report_format( assertion_result const& ar, unit_test::lazy_ostream const& assertion_descr, check_type ct, std::size_t num_args, ... )
{
    std::ostringstream msg_buff;

    va_list args;
    va_start( args, num_args );

    format_report( msg_buff, ar, assertion_descr, CHECK, ct, num_args, args, "assertion ", " failed" );

    va_end( args );

    return msg_buff.str();
}

//____________________________________________________________________________//

assertion_result
equal_impl( char const* left, char const* right )
{
    return (left && right) ? std::strcmp( left, right ) == 0 : (left == right);
}

//____________________________________________________________________________//

#if !defined( BOOST_NO_CWCHAR )

assertion_result
equal_impl( wchar_t const* left, wchar_t const* right )
{
    return (left && right) ? std::wcscmp( left, right ) == 0 : (left == right);
}

#endif // !defined( BOOST_NO_CWCHAR )

//____________________________________________________________________________//

bool
is_defined_impl( const_string symbol_name, const_string symbol_value )
{
    symbol_value.trim_left( 2 );
    return symbol_name != symbol_value;
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************                 context_frame                ************** //
// ************************************************************************** //

context_frame::context_frame( ::boost::unit_test::lazy_ostream const& context_descr )
: m_frame_id( unit_test::framework::add_context( context_descr, true ) )
{
}

//____________________________________________________________________________//

context_frame::~context_frame()
{
    unit_test::framework::clear_context( m_frame_id );
}

//____________________________________________________________________________//

context_frame::operator bool()
{
    return true;
}

//____________________________________________________________________________//

} // namespace tt_detail

// ************************************************************************** //
// **************               output_test_stream             ************** //
// ************************************************************************** //

struct output_test_stream::Impl
{
    std::fstream    m_pattern;
    bool            m_match_or_save;
    bool            m_text_or_binary;
    std::string     m_synced_string;

    char            get_char()
    {
        char res;
        do {
            m_pattern.get( res );
        } while( m_text_or_binary && res == '\r' && !m_pattern.fail() && !m_pattern.eof() );

        return res;
    }

    void            check_and_fill( assertion_result& res )
    {
        if( !res.p_predicate_value )
            res.message() << "Output content: \"" << m_synced_string << '\"';
    }
};

//____________________________________________________________________________//

output_test_stream::output_test_stream( const_string pattern_file_name, bool match_or_save, bool text_or_binary )
: m_pimpl( new Impl )
{
    if( !pattern_file_name.is_empty() ) {
        std::ios::openmode m = match_or_save ? std::ios::in : std::ios::out;
        if( !text_or_binary )
            m |= std::ios::binary;

        m_pimpl->m_pattern.open( pattern_file_name.begin(), m );

        if( !m_pimpl->m_pattern.is_open() )
            BOOST_TEST_FRAMEWORK_MESSAGE( "Can't open pattern file " << pattern_file_name << " for " << (match_or_save ? "reading" : "writing") );
    }

    m_pimpl->m_match_or_save    = match_or_save;
    m_pimpl->m_text_or_binary   = text_or_binary;
}

//____________________________________________________________________________//

output_test_stream::~output_test_stream()
{
    delete m_pimpl;
}

//____________________________________________________________________________//

assertion_result
output_test_stream::is_empty( bool flush_stream )
{
    sync();

    assertion_result res( m_pimpl->m_synced_string.empty() );

    m_pimpl->check_and_fill( res );

    if( flush_stream )
        flush();

    return res;
}

//____________________________________________________________________________//

assertion_result
output_test_stream::check_length( std::size_t length_, bool flush_stream )
{
    sync();

    assertion_result res( m_pimpl->m_synced_string.length() == length_ );

    m_pimpl->check_and_fill( res );

    if( flush_stream )
        flush();

    return res;
}

//____________________________________________________________________________//

assertion_result
output_test_stream::is_equal( const_string arg, bool flush_stream )
{
    sync();

    assertion_result res( const_string( m_pimpl->m_synced_string ) == arg );

    m_pimpl->check_and_fill( res );

    if( flush_stream )
        flush();

    return res;
}

//____________________________________________________________________________//

std::string pretty_print_log(std::string str) {

    static const std::string to_replace[] = { "\r", "\n" };
    static const std::string replacement[] = { "\\r", "\\n" };

    return unit_test::utils::replace_all_occurrences_of(
        str,
        to_replace, to_replace + sizeof(to_replace)/sizeof(to_replace[0]),
        replacement, replacement + sizeof(replacement)/sizeof(replacement[0]));
}

assertion_result
output_test_stream::match_pattern( bool flush_stream )
{
    const std::string::size_type n_chars_presuffix = 10;
    sync();

    assertion_result result( true );

    const std::string stream_string_repr = get_stream_string_representation();

    if( !m_pimpl->m_pattern.is_open() ) {
        result = false;
        result.message() << "Pattern file can't be opened!";
    }
    else {
        if( m_pimpl->m_match_or_save ) {

            int offset = 0;
            std::vector<char> last_elements;
            for ( std::string::size_type i = 0; static_cast<int>(i + offset) < static_cast<int>(stream_string_repr.length()); ++i ) {
                char c = m_pimpl->get_char();

                if( last_elements.size() <= n_chars_presuffix ) {
                    last_elements.push_back( c );
                }
                else {
                    last_elements[ i % last_elements.size() ] = c;
                }

                bool is_same = !m_pimpl->m_pattern.fail() &&
                         !m_pimpl->m_pattern.eof()  &&
                         (stream_string_repr[i+offset] == c);

                if( !is_same ) {

                    result = false;

                    std::string::size_type prefix_size  = (std::min)( i + offset, n_chars_presuffix );

                    std::string::size_type suffix_size  = (std::min)( stream_string_repr.length() - i - offset,
                                                                      n_chars_presuffix );

                    // try to log area around the mismatch
                    std::string substr = stream_string_repr.substr(0, i+offset);
                    std::size_t line = std::count(substr.begin(), substr.end(), '\n');
                    std::size_t column = i + offset - substr.rfind('\n');

                    result.message()
                        << "Mismatch at position " << i
                        << " (line " << line
                        << ", column " << column
                        << "): '" << pretty_print_log(std::string(1, stream_string_repr[i+offset])) << "' != '" << pretty_print_log(std::string(1, c)) << "' :\n";

                    // we already escape this substring because we need its actual size for the pretty print
                    // of the difference location.
                    std::string sub_str_prefix(pretty_print_log(stream_string_repr.substr( i + offset - prefix_size, prefix_size )));

                    // we need this substring as is because we compute the best matching substrings on it.
                    std::string sub_str_suffix(stream_string_repr.substr( i + offset, suffix_size));
                    result.message() << "... " << sub_str_prefix + pretty_print_log(sub_str_suffix) << " ..." << '\n';

                    result.message() << "... ";
                    for( std::size_t j = 0; j < last_elements.size() ; j++ )
                        result.message() << pretty_print_log(std::string(1, last_elements[(i + j + 1) % last_elements.size()]));

                    std::vector<char> last_elements_ordered;
                    last_elements_ordered.push_back(c);
                    for( std::string::size_type counter = 0; counter < suffix_size - 1 ; counter++ ) {
                        char c2 = m_pimpl->get_char();

                        if( m_pimpl->m_pattern.fail() || m_pimpl->m_pattern.eof() )
                            break;

                        result.message() << pretty_print_log(std::string(1, c2));

                        last_elements_ordered.push_back(c2);
                    }

                    // tries to find the best substring matching in the remainder of the
                    // two strings
                    std::size_t max_nb_char_in_common = 0;
                    std::size_t best_pattern_start_index = 0;
                    std::size_t best_stream_start_index = 0;
                    for( std::size_t pattern_start_index = best_pattern_start_index;
                         pattern_start_index < last_elements_ordered.size();
                         pattern_start_index++ ) {
                        for( std::size_t stream_start_index = best_stream_start_index;
                             stream_start_index < sub_str_suffix.size();
                             stream_start_index++ ) {

                            std::size_t max_size = (std::min)( last_elements_ordered.size() - pattern_start_index, sub_str_suffix.size() - stream_start_index );
                            if( max_nb_char_in_common > max_size )
                                break; // safely break to go to the outer loop

                            std::size_t nb_char_in_common = 0;
                            for( std::size_t k = 0; k < max_size; k++) {
                                if( last_elements_ordered[pattern_start_index + k] == sub_str_suffix[stream_start_index + k] )
                                    nb_char_in_common ++;
                                else
                                    break; // we take fully macthing substring only
                            }

                            if( nb_char_in_common > max_nb_char_in_common ) {
                                max_nb_char_in_common = nb_char_in_common;
                                best_pattern_start_index = pattern_start_index;
                                best_stream_start_index = stream_start_index;
                            }
                        }
                    }

                    // indicates with more precision the location of the mismatchs in ascii arts ...
                    result.message() << " ...\n... ";
                    for( std::string::size_type j = 0; j < sub_str_prefix.size(); j++) {
                        result.message() << ' ';
                    }

                    for( std::size_t k = 0; k < (std::max)(best_pattern_start_index, best_stream_start_index); k++ ) { // 1 is for the current char c
                        std::string s1(pretty_print_log(std::string(1, last_elements_ordered[(std::min)(k, best_pattern_start_index)])));
                        std::string s2(pretty_print_log(std::string(1, sub_str_suffix[(std::min)(k, best_stream_start_index)])));
                        for( int h = (std::max)(s1.size(), s2.size()); h > 0; h--)
                          result.message() << "~";
                    }
                    result.message() << "\n";

                    // first char is a replicat of c, so we do not copy it.
                    for(std::string::size_type counter = 0; counter < last_elements_ordered.size() - 1 ; counter++)
                        last_elements[ (i + 1 + counter) % last_elements.size() ] = last_elements_ordered[counter + 1];

                    i += last_elements_ordered.size()-1;
                    offset += best_stream_start_index - best_pattern_start_index;

                }

            }

            // not needed anymore
            /*
            if(offset > 0 && false) {
                m_pimpl->m_pattern.ignore(
                    static_cast<std::streamsize>( offset ));
            }
            */
        }
        else {
            m_pimpl->m_pattern.write( stream_string_repr.c_str(),
                                      static_cast<std::streamsize>( stream_string_repr.length() ) );
            m_pimpl->m_pattern.flush();
        }
    }

    if( flush_stream )
        flush();

    return result;
}

//____________________________________________________________________________//

void
output_test_stream::flush()
{
    m_pimpl->m_synced_string.erase();

#ifndef BOOST_NO_STRINGSTREAM
    str( std::string() );
#else
    seekp( 0, std::ios::beg );
#endif
}

std::string
output_test_stream::get_stream_string_representation() const {
    return m_pimpl->m_synced_string;
}

//____________________________________________________________________________//

std::size_t
output_test_stream::length()
{
    sync();

    return m_pimpl->m_synced_string.length();
}

//____________________________________________________________________________//

void
output_test_stream::sync()
{
#ifdef BOOST_NO_STRINGSTREAM
    m_pimpl->m_synced_string.assign( str(), pcount() );
    freeze( false );
#else
    m_pimpl->m_synced_string = str();
#endif
}

//____________________________________________________________________________//

} // namespace test_tools
} // namespace boost

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

#endif // BOOST_TEST_TEST_TOOLS_IPP_012205GER


code:
# /* Copyright (C) 2001
#  * Housemarque Oy
#  * http://www.housemarque.com
#  *
#  * 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)
#  */
#
# /* Revised by Paul Mensonides (2002) */
#
# /* See http://www.boost.org for most recent version. */
#
# ifndef BOOST_PREPROCESSOR_SELECTION_MIN_HPP
# define BOOST_PREPROCESSOR_SELECTION_MIN_HPP
#
# include <boost/preprocessor/comparison/less_equal.hpp>
# include <boost/preprocessor/config/config.hpp>
# include <boost/preprocessor/control/iif.hpp>
#
# /* BOOST_PP_MIN */
#
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
#    define BOOST_PP_MIN(x, y) BOOST_PP_IIF(BOOST_PP_LESS_EQUAL(y, x), y, x)
# else
#    define BOOST_PP_MIN(x, y) BOOST_PP_MIN_I(x, y)
#    define BOOST_PP_MIN_I(x, y) BOOST_PP_IIF(BOOST_PP_LESS_EQUAL(y, x), y, x)
# endif
#
# /* BOOST_PP_MIN_D */
#
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
#    define BOOST_PP_MIN_D(d, x, y) BOOST_PP_IIF(BOOST_PP_LESS_EQUAL_D(d, y, x), y, x)
# else
#    define BOOST_PP_MIN_D(d, x, y) BOOST_PP_MIN_D_I(d, x, y)
#    define BOOST_PP_MIN_D_I(d, x, y) BOOST_PP_IIF(BOOST_PP_LESS_EQUAL_D(d, y, x), y, x)
# endif
#
# endif

license: mit


code:
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// basic_text_oprimitive.ipp:

// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org for updates, documentation, and revision history.

#include <cstddef> // NULL
#include <algorithm> // std::copy
#include <exception> // std::uncaught_exception
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
    using ::size_t;
} // namespace std
#endif

#include <boost/archive/basic_text_oprimitive.hpp>

#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/ostream_iterator.hpp>

namespace boost {
namespace archive {

// translate to base64 and copy in to buffer.
template<class OStream>
BOOST_ARCHIVE_OR_WARCHIVE_DECL void
basic_text_oprimitive<OStream>::save_binary(
    const void *address,
    std::size_t count
){
    typedef typename OStream::char_type CharType;

    if(0 == count)
        return;

    if(os.fail())
        boost::serialization::throw_exception(
            archive_exception(archive_exception::output_stream_error)
        );

    os.put('\n');

    typedef
        boost::archive::iterators::insert_linebreaks<
            boost::archive::iterators::base64_from_binary<
                boost::archive::iterators::transform_width<
                    const char *,
                    6,
                    8
                >
            >
            ,76
            ,const char // cwpro8 needs this
        >
        base64_text;

    boost::archive::iterators::ostream_iterator<CharType> oi(os);
    std::copy(
        base64_text(static_cast<const char *>(address)),
        base64_text(
            static_cast<const char *>(address) + count
        ),
        oi
    );

    std::size_t tail = count % 3;
    if(tail > 0){
        *oi++ = '=';
        if(tail < 2)
            *oi = '=';
    }
}

template<class OStream>
BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_text_oprimitive<OStream>::basic_text_oprimitive(
    OStream & os_,
    bool no_codecvt
) :
    os(os_),
    flags_saver(os_),
    precision_saver(os_),
#ifndef BOOST_NO_STD_LOCALE
    codecvt_null_facet(1),
    archive_locale(os.getloc(), & codecvt_null_facet),
    locale_saver(os)
{
    if(! no_codecvt){
        os_.flush();
        os_.imbue(archive_locale);
    }
    os_ << std::noboolalpha;
}
#else
{}
#endif

template<class OStream>
BOOST_ARCHIVE_OR_WARCHIVE_DECL
basic_text_oprimitive<OStream>::~basic_text_oprimitive(){
    if(std::uncaught_exception())
        return;
    os << std::endl;
}

} //namespace boost
} //namespace archive


code:
//  (C) Copyright John Maddock 2007.
//  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)
//
//  This file is machine generated, do not edit by hand

// Polynomial evaluation using second order Horners rule
#ifndef BOOST_MATH_TOOLS_RAT_EVAL_14_HPP
#define BOOST_MATH_TOOLS_RAT_EVAL_14_HPP

namespace boost{ namespace math{ namespace tools{ namespace detail{

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T*, const U*, const V&, const mpl::int_<0>*) BOOST_MATH_NOEXCEPT(V)
{
   return static_cast<V>(0);
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const mpl::int_<1>*) BOOST_MATH_NOEXCEPT(V)
{
   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<2>*) BOOST_MATH_NOEXCEPT(V)
{
   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<3>*) BOOST_MATH_NOEXCEPT(V)
{
   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<4>*) BOOST_MATH_NOEXCEPT(V)
{
   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<5>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
   {
      V x2 = x * x;
      V t[4];
      t[0] = a[4] * x2 + a[2];
      t[1] = a[3] * x2 + a[1];
      t[2] = b[4] * x2 + b[2];
      t[3] = b[3] * x2 + b[1];
      t[0] *= x2;
      t[2] *= x2;
      t[0] += static_cast<V>(a[0]);
      t[2] += static_cast<V>(b[0]);
      t[1] *= x;
      t[3] *= x;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
   else
   {
      V z = 1 / x;
      V z2 = 1 / (x * x);
      V t[4];
      t[0] = a[0] * z2 + a[2];
      t[1] = a[1] * z2 + a[3];
      t[2] = b[0] * z2 + b[2];
      t[3] = b[1] * z2 + b[3];
      t[0] *= z2;
      t[2] *= z2;
      t[0] += static_cast<V>(a[4]);
      t[2] += static_cast<V>(b[4]);
      t[1] *= z;
      t[3] *= z;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<6>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
   {
      V x2 = x * x;
      V t[4];
      t[0] = a[5] * x2 + a[3];
      t[1] = a[4] * x2 + a[2];
      t[2] = b[5] * x2 + b[3];
      t[3] = b[4] * x2 + b[2];
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[1]);
      t[1] += static_cast<V>(a[0]);
      t[2] += static_cast<V>(b[1]);
      t[3] += static_cast<V>(b[0]);
      t[0] *= x;
      t[2] *= x;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
   else
   {
      V z = 1 / x;
      V z2 = 1 / (x * x);
      V t[4];
      t[0] = a[0] * z2 + a[2];
      t[1] = a[1] * z2 + a[3];
      t[2] = b[0] * z2 + b[2];
      t[3] = b[1] * z2 + b[3];
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[4]);
      t[1] += static_cast<V>(a[5]);
      t[2] += static_cast<V>(b[4]);
      t[3] += static_cast<V>(b[5]);
      t[0] *= z;
      t[2] *= z;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<7>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
   {
      V x2 = x * x;
      V t[4];
      t[0] = a[6] * x2 + a[4];
      t[1] = a[5] * x2 + a[3];
      t[2] = b[6] * x2 + b[4];
      t[3] = b[5] * x2 + b[3];
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[2]);
      t[1] += static_cast<V>(a[1]);
      t[2] += static_cast<V>(b[2]);
      t[3] += static_cast<V>(b[1]);
      t[0] *= x2;
      t[2] *= x2;
      t[0] += static_cast<V>(a[0]);
      t[2] += static_cast<V>(b[0]);
      t[1] *= x;
      t[3] *= x;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
   else
   {
      V z = 1 / x;
      V z2 = 1 / (x * x);
      V t[4];
      t[0] = a[0] * z2 + a[2];
      t[1] = a[1] * z2 + a[3];
      t[2] = b[0] * z2 + b[2];
      t[3] = b[1] * z2 + b[3];
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[4]);
      t[1] += static_cast<V>(a[5]);
      t[2] += static_cast<V>(b[4]);
      t[3] += static_cast<V>(b[5]);
      t[0] *= z2;
      t[2] *= z2;
      t[0] += static_cast<V>(a[6]);
      t[2] += static_cast<V>(b[6]);
      t[1] *= z;
      t[3] *= z;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<8>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
   {
      V x2 = x * x;
      V t[4];
      t[0] = a[7] * x2 + a[5];
      t[1] = a[6] * x2 + a[4];
      t[2] = b[7] * x2 + b[5];
      t[3] = b[6] * x2 + b[4];
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[3]);
      t[1] += static_cast<V>(a[2]);
      t[2] += static_cast<V>(b[3]);
      t[3] += static_cast<V>(b[2]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[1]);
      t[1] += static_cast<V>(a[0]);
      t[2] += static_cast<V>(b[1]);
      t[3] += static_cast<V>(b[0]);
      t[0] *= x;
      t[2] *= x;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
   else
   {
      V z = 1 / x;
      V z2 = 1 / (x * x);
      V t[4];
      t[0] = a[0] * z2 + a[2];
      t[1] = a[1] * z2 + a[3];
      t[2] = b[0] * z2 + b[2];
      t[3] = b[1] * z2 + b[3];
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[4]);
      t[1] += static_cast<V>(a[5]);
      t[2] += static_cast<V>(b[4]);
      t[3] += static_cast<V>(b[5]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[6]);
      t[1] += static_cast<V>(a[7]);
      t[2] += static_cast<V>(b[6]);
      t[3] += static_cast<V>(b[7]);
      t[0] *= z;
      t[2] *= z;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<9>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
   {
      V x2 = x * x;
      V t[4];
      t[0] = a[8] * x2 + a[6];
      t[1] = a[7] * x2 + a[5];
      t[2] = b[8] * x2 + b[6];
      t[3] = b[7] * x2 + b[5];
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[4]);
      t[1] += static_cast<V>(a[3]);
      t[2] += static_cast<V>(b[4]);
      t[3] += static_cast<V>(b[3]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[2]);
      t[1] += static_cast<V>(a[1]);
      t[2] += static_cast<V>(b[2]);
      t[3] += static_cast<V>(b[1]);
      t[0] *= x2;
      t[2] *= x2;
      t[0] += static_cast<V>(a[0]);
      t[2] += static_cast<V>(b[0]);
      t[1] *= x;
      t[3] *= x;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
   else
   {
      V z = 1 / x;
      V z2 = 1 / (x * x);
      V t[4];
      t[0] = a[0] * z2 + a[2];
      t[1] = a[1] * z2 + a[3];
      t[2] = b[0] * z2 + b[2];
      t[3] = b[1] * z2 + b[3];
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[4]);
      t[1] += static_cast<V>(a[5]);
      t[2] += static_cast<V>(b[4]);
      t[3] += static_cast<V>(b[5]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[6]);
      t[1] += static_cast<V>(a[7]);
      t[2] += static_cast<V>(b[6]);
      t[3] += static_cast<V>(b[7]);
      t[0] *= z2;
      t[2] *= z2;
      t[0] += static_cast<V>(a[8]);
      t[2] += static_cast<V>(b[8]);
      t[1] *= z;
      t[3] *= z;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<10>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
   {
      V x2 = x * x;
      V t[4];
      t[0] = a[9] * x2 + a[7];
      t[1] = a[8] * x2 + a[6];
      t[2] = b[9] * x2 + b[7];
      t[3] = b[8] * x2 + b[6];
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[5]);
      t[1] += static_cast<V>(a[4]);
      t[2] += static_cast<V>(b[5]);
      t[3] += static_cast<V>(b[4]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[3]);
      t[1] += static_cast<V>(a[2]);
      t[2] += static_cast<V>(b[3]);
      t[3] += static_cast<V>(b[2]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[1]);
      t[1] += static_cast<V>(a[0]);
      t[2] += static_cast<V>(b[1]);
      t[3] += static_cast<V>(b[0]);
      t[0] *= x;
      t[2] *= x;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
   else
   {
      V z = 1 / x;
      V z2 = 1 / (x * x);
      V t[4];
      t[0] = a[0] * z2 + a[2];
      t[1] = a[1] * z2 + a[3];
      t[2] = b[0] * z2 + b[2];
      t[3] = b[1] * z2 + b[3];
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[4]);
      t[1] += static_cast<V>(a[5]);
      t[2] += static_cast<V>(b[4]);
      t[3] += static_cast<V>(b[5]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[6]);
      t[1] += static_cast<V>(a[7]);
      t[2] += static_cast<V>(b[6]);
      t[3] += static_cast<V>(b[7]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[8]);
      t[1] += static_cast<V>(a[9]);
      t[2] += static_cast<V>(b[8]);
      t[3] += static_cast<V>(b[9]);
      t[0] *= z;
      t[2] *= z;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<11>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
   {
      V x2 = x * x;
      V t[4];
      t[0] = a[10] * x2 + a[8];
      t[1] = a[9] * x2 + a[7];
      t[2] = b[10] * x2 + b[8];
      t[3] = b[9] * x2 + b[7];
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[6]);
      t[1] += static_cast<V>(a[5]);
      t[2] += static_cast<V>(b[6]);
      t[3] += static_cast<V>(b[5]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[4]);
      t[1] += static_cast<V>(a[3]);
      t[2] += static_cast<V>(b[4]);
      t[3] += static_cast<V>(b[3]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[2]);
      t[1] += static_cast<V>(a[1]);
      t[2] += static_cast<V>(b[2]);
      t[3] += static_cast<V>(b[1]);
      t[0] *= x2;
      t[2] *= x2;
      t[0] += static_cast<V>(a[0]);
      t[2] += static_cast<V>(b[0]);
      t[1] *= x;
      t[3] *= x;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
   else
   {
      V z = 1 / x;
      V z2 = 1 / (x * x);
      V t[4];
      t[0] = a[0] * z2 + a[2];
      t[1] = a[1] * z2 + a[3];
      t[2] = b[0] * z2 + b[2];
      t[3] = b[1] * z2 + b[3];
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[4]);
      t[1] += static_cast<V>(a[5]);
      t[2] += static_cast<V>(b[4]);
      t[3] += static_cast<V>(b[5]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[6]);
      t[1] += static_cast<V>(a[7]);
      t[2] += static_cast<V>(b[6]);
      t[3] += static_cast<V>(b[7]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[8]);
      t[1] += static_cast<V>(a[9]);
      t[2] += static_cast<V>(b[8]);
      t[3] += static_cast<V>(b[9]);
      t[0] *= z2;
      t[2] *= z2;
      t[0] += static_cast<V>(a[10]);
      t[2] += static_cast<V>(b[10]);
      t[1] *= z;
      t[3] *= z;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<12>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
   {
      V x2 = x * x;
      V t[4];
      t[0] = a[11] * x2 + a[9];
      t[1] = a[10] * x2 + a[8];
      t[2] = b[11] * x2 + b[9];
      t[3] = b[10] * x2 + b[8];
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[7]);
      t[1] += static_cast<V>(a[6]);
      t[2] += static_cast<V>(b[7]);
      t[3] += static_cast<V>(b[6]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[5]);
      t[1] += static_cast<V>(a[4]);
      t[2] += static_cast<V>(b[5]);
      t[3] += static_cast<V>(b[4]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[3]);
      t[1] += static_cast<V>(a[2]);
      t[2] += static_cast<V>(b[3]);
      t[3] += static_cast<V>(b[2]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[1]);
      t[1] += static_cast<V>(a[0]);
      t[2] += static_cast<V>(b[1]);
      t[3] += static_cast<V>(b[0]);
      t[0] *= x;
      t[2] *= x;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
   else
   {
      V z = 1 / x;
      V z2 = 1 / (x * x);
      V t[4];
      t[0] = a[0] * z2 + a[2];
      t[1] = a[1] * z2 + a[3];
      t[2] = b[0] * z2 + b[2];
      t[3] = b[1] * z2 + b[3];
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[4]);
      t[1] += static_cast<V>(a[5]);
      t[2] += static_cast<V>(b[4]);
      t[3] += static_cast<V>(b[5]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[6]);
      t[1] += static_cast<V>(a[7]);
      t[2] += static_cast<V>(b[6]);
      t[3] += static_cast<V>(b[7]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[8]);
      t[1] += static_cast<V>(a[9]);
      t[2] += static_cast<V>(b[8]);
      t[3] += static_cast<V>(b[9]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[10]);
      t[1] += static_cast<V>(a[11]);
      t[2] += static_cast<V>(b[10]);
      t[3] += static_cast<V>(b[11]);
      t[0] *= z;
      t[2] *= z;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<13>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
   {
      V x2 = x * x;
      V t[4];
      t[0] = a[12] * x2 + a[10];
      t[1] = a[11] * x2 + a[9];
      t[2] = b[12] * x2 + b[10];
      t[3] = b[11] * x2 + b[9];
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[8]);
      t[1] += static_cast<V>(a[7]);
      t[2] += static_cast<V>(b[8]);
      t[3] += static_cast<V>(b[7]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[6]);
      t[1] += static_cast<V>(a[5]);
      t[2] += static_cast<V>(b[6]);
      t[3] += static_cast<V>(b[5]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[4]);
      t[1] += static_cast<V>(a[3]);
      t[2] += static_cast<V>(b[4]);
      t[3] += static_cast<V>(b[3]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[2]);
      t[1] += static_cast<V>(a[1]);
      t[2] += static_cast<V>(b[2]);
      t[3] += static_cast<V>(b[1]);
      t[0] *= x2;
      t[2] *= x2;
      t[0] += static_cast<V>(a[0]);
      t[2] += static_cast<V>(b[0]);
      t[1] *= x;
      t[3] *= x;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
   else
   {
      V z = 1 / x;
      V z2 = 1 / (x * x);
      V t[4];
      t[0] = a[0] * z2 + a[2];
      t[1] = a[1] * z2 + a[3];
      t[2] = b[0] * z2 + b[2];
      t[3] = b[1] * z2 + b[3];
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[4]);
      t[1] += static_cast<V>(a[5]);
      t[2] += static_cast<V>(b[4]);
      t[3] += static_cast<V>(b[5]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[6]);
      t[1] += static_cast<V>(a[7]);
      t[2] += static_cast<V>(b[6]);
      t[3] += static_cast<V>(b[7]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[8]);
      t[1] += static_cast<V>(a[9]);
      t[2] += static_cast<V>(b[8]);
      t[3] += static_cast<V>(b[9]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[10]);
      t[1] += static_cast<V>(a[11]);
      t[2] += static_cast<V>(b[10]);
      t[3] += static_cast<V>(b[11]);
      t[0] *= z2;
      t[2] *= z2;
      t[0] += static_cast<V>(a[12]);
      t[2] += static_cast<V>(b[12]);
      t[1] *= z;
      t[3] *= z;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
}

template <class T, class U, class V>
inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<14>*) BOOST_MATH_NOEXCEPT(V)
{
   if(x <= 1)
   {
      V x2 = x * x;
      V t[4];
      t[0] = a[13] * x2 + a[11];
      t[1] = a[12] * x2 + a[10];
      t[2] = b[13] * x2 + b[11];
      t[3] = b[12] * x2 + b[10];
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[9]);
      t[1] += static_cast<V>(a[8]);
      t[2] += static_cast<V>(b[9]);
      t[3] += static_cast<V>(b[8]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[7]);
      t[1] += static_cast<V>(a[6]);
      t[2] += static_cast<V>(b[7]);
      t[3] += static_cast<V>(b[6]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[5]);
      t[1] += static_cast<V>(a[4]);
      t[2] += static_cast<V>(b[5]);
      t[3] += static_cast<V>(b[4]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[3]);
      t[1] += static_cast<V>(a[2]);
      t[2] += static_cast<V>(b[3]);
      t[3] += static_cast<V>(b[2]);
      t[0] *= x2;
      t[1] *= x2;
      t[2] *= x2;
      t[3] *= x2;
      t[0] += static_cast<V>(a[1]);
      t[1] += static_cast<V>(a[0]);
      t[2] += static_cast<V>(b[1]);
      t[3] += static_cast<V>(b[0]);
      t[0] *= x;
      t[2] *= x;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
   else
   {
      V z = 1 / x;
      V z2 = 1 / (x * x);
      V t[4];
      t[0] = a[0] * z2 + a[2];
      t[1] = a[1] * z2 + a[3];
      t[2] = b[0] * z2 + b[2];
      t[3] = b[1] * z2 + b[3];
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[4]);
      t[1] += static_cast<V>(a[5]);
      t[2] += static_cast<V>(b[4]);
      t[3] += static_cast<V>(b[5]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[6]);
      t[1] += static_cast<V>(a[7]);
      t[2] += static_cast<V>(b[6]);
      t[3] += static_cast<V>(b[7]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[8]);
      t[1] += static_cast<V>(a[9]);
      t[2] += static_cast<V>(b[8]);
      t[3] += static_cast<V>(b[9]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[10]);
      t[1] += static_cast<V>(a[11]);
      t[2] += static_cast<V>(b[10]);
      t[3] += static_cast<V>(b[11]);
      t[0] *= z2;
      t[1] *= z2;
      t[2] *= z2;
      t[3] *= z2;
      t[0] += static_cast<V>(a[12]);
      t[1] += static_cast<V>(a[13]);
      t[2] += static_cast<V>(b[12]);
      t[3] += static_cast<V>(b[13]);
      t[0] *= z;
      t[2] *= z;
      return (t[0] + t[1]) / (t[2] + t[3]);
   }
}

}}}} // namespaces

#endif // include guard


code:
/*=============================================================================
    Copyright (c) 2001-2011 Joel de Guzman

    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)
==============================================================================*/
#if !defined(FUSION_END_04052005_1141)
#define FUSION_END_04052005_1141

#include <boost/fusion/support/config.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/empty_base.hpp>
#include <boost/mpl/if.hpp>
#include <boost/fusion/sequence/intrinsic_fwd.hpp>
#include <boost/fusion/support/tag_of.hpp>
#include <boost/fusion/support/is_sequence.hpp>
#include <boost/fusion/support/is_segmented.hpp>
#include <boost/fusion/sequence/intrinsic/detail/segmented_end.hpp>

namespace boost { namespace fusion
{
    // Special tags:
    struct sequence_facade_tag;
    struct boost_tuple_tag; // boost::tuples::tuple tag
    struct boost_array_tag; // boost::array tag
    struct mpl_sequence_tag; // mpl sequence tag
    struct std_pair_tag; // std::pair tag

    namespace extension
    {
        template <typename Tag>
        struct end_impl
        {
            template <typename Sequence>
            struct apply
              : mpl::if_<
                    traits::is_segmented<Sequence>
                  , detail::segmented_end<Sequence>
                  , mpl::empty_base
                >::type
            {};
        };

        template <>
        struct end_impl<sequence_facade_tag>
        {
            template <typename Sequence>
            struct apply : Sequence::template end<Sequence> {};
        };

        template <>
        struct end_impl<boost_tuple_tag>;

        template <>
        struct end_impl<boost_array_tag>;

        template <>
        struct end_impl<mpl_sequence_tag>;

        template <>
        struct end_impl<std_pair_tag>;
    }

    namespace result_of
    {
        template <typename Sequence>
        struct end
            : extension::end_impl<typename detail::tag_of<Sequence>::type>::
                template apply<Sequence>
        {};
    }

    template <typename Sequence>
    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
    inline typename
        lazy_enable_if<
            traits::is_sequence<Sequence>
          , result_of::end<Sequence>
        >::type const
    end(Sequence& seq)
    {
        return result_of::end<Sequence>::call(seq);
    }

    template <typename Sequence>
    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
    inline typename
        lazy_enable_if<
            traits::is_sequence<Sequence>
          , result_of::end<Sequence const>
        >::type const
    end(Sequence const& seq)
    {
        return result_of::end<Sequence const>::call(seq);
    }
}}

#endif


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 simple text based progress monitor
// ***************************************************************************

#ifndef BOOST_TEST_PROGRESS_MONITOR_IPP_020105GER
#define BOOST_TEST_PROGRESS_MONITOR_IPP_020105GER

// Boost.Test
#include <boost/test/progress_monitor.hpp>
#include <boost/test/unit_test_parameters.hpp>

#include <boost/test/utils/setcolor.hpp>

#include <boost/test/tree/test_unit.hpp>
#include <boost/test/tree/test_case_counter.hpp>
#include <boost/test/tree/traverse.hpp>

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

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

//____________________________________________________________________________//

namespace boost {
namespace unit_test {

// ************************************************************************** //
// **************                progress_monitor              ************** //
// ************************************************************************** //

struct progress_display {
    progress_display( counter_t expected_count, std::ostream& os )
    : m_os(os)
    , m_count( 0 )
    , m_expected_count( expected_count )
    , m_next_tic_count( 0 )
    , m_tic( 0 )
    {

        m_os << "\n0%   10   20   30   40   50   60   70   80   90   100%"
             << "\n|----|----|----|----|----|----|----|----|----|----|"
             << std::endl;

        if( !m_expected_count )
            m_expected_count = 1;  // prevent divide by zero
    }

    unsigned long  operator+=( unsigned long increment )
    {
        if( (m_count += increment) < m_next_tic_count )
            return m_count;

        // use of floating point ensures that both large and small counts
        // work correctly.  static_cast<>() is also used several places
        // to suppress spurious compiler warnings.
        unsigned int tics_needed =  static_cast<unsigned int>(
            (static_cast<double>(m_count)/m_expected_count)*50.0 );

        do {
            m_os << '*' << std::flush;
        } while( ++m_tic < tics_needed );

        m_next_tic_count = static_cast<unsigned long>((m_tic/50.0) * m_expected_count);

        if( m_count == m_expected_count ) {
            if( m_tic < 51 )
                m_os << '*';

            m_os << std::endl;
        }

        return m_count;
    }
    unsigned long   operator++()           { return operator+=( 1 ); }
    unsigned long   count() const          { return m_count; }

private:
    BOOST_DELETED_FUNCTION(progress_display(progress_display const&))
    BOOST_DELETED_FUNCTION(progress_display& operator=(progress_display const&))

    std::ostream&   m_os;  // may not be present in all imps

    unsigned long   m_count;
    unsigned long   m_expected_count;
    unsigned long   m_next_tic_count;
    unsigned int    m_tic;
};

namespace {

struct progress_monitor_impl {
    // Constructor
    progress_monitor_impl()
    : m_stream( &std::cout )
    , m_color_output( false )
    {
    }

    std::ostream*                   m_stream;
    scoped_ptr<progress_display>    m_progress_display;
    bool                            m_color_output;
};

progress_monitor_impl& s_pm_impl() { static progress_monitor_impl the_inst; return the_inst; }

#define PM_SCOPED_COLOR() \
    BOOST_TEST_SCOPE_SETCOLOR( s_pm_impl().m_color_output, *s_pm_impl().m_stream, term_attr::BRIGHT, term_color::MAGENTA )

} // local namespace

//____________________________________________________________________________//

void
progress_monitor_t::test_start( counter_t test_cases_amount )
{
    s_pm_impl().m_color_output = runtime_config::get<bool>( runtime_config::COLOR_OUTPUT );

    PM_SCOPED_COLOR();

    s_pm_impl().m_progress_display.reset( new progress_display( test_cases_amount, *s_pm_impl().m_stream ) );
}

//____________________________________________________________________________//

void
progress_monitor_t::test_aborted()
{
    PM_SCOPED_COLOR();

    (*s_pm_impl().m_progress_display) += s_pm_impl().m_progress_display->count();
}

//____________________________________________________________________________//

void
progress_monitor_t::test_unit_finish( test_unit const& tu, unsigned long )
{
    PM_SCOPED_COLOR();

    if( tu.p_type == TUT_CASE )
        ++(*s_pm_impl().m_progress_display);
}

//____________________________________________________________________________//

void
progress_monitor_t::test_unit_skipped( test_unit const& tu, const_string /*reason*/ )
{
    PM_SCOPED_COLOR();

    test_case_counter tcc;
    traverse_test_tree( tu, tcc );

    (*s_pm_impl().m_progress_display) += tcc.p_count;
}

//____________________________________________________________________________//

void
progress_monitor_t::set_stream( std::ostream& ostr )
{
    s_pm_impl().m_stream = &ostr;
}

//____________________________________________________________________________//

#undef PM_SCOPED_COLOR

} // namespace unit_test
} // namespace boost

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

#endif // BOOST_TEST_PROGRESS_MONITOR_IPP_020105GER


code:
/*=============================================================================
    Copyright (c) 2001-2011 Joel de Guzman
    Copyright (c) 2006 Dan Marsden
    Copyright (c) 2009-2010 Christopher Schmidt
    Copyright (c) 2015 Kohei Takahashi

    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/preprocessor/cat.hpp>

#define FUSION_HASH #

#ifdef BOOST_FUSION_REVERSE_FOLD
#   ifdef BOOST_FUSION_ITER_FOLD
#       define BOOST_FUSION_FOLD_NAME reverse_iter_fold
#   else
#       define BOOST_FUSION_FOLD_NAME reverse_fold
#   endif

#   define BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION end
#   define BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION prior
#   define BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(IT)                   \
        typename fusion::result_of::prior<IT>::type
#   define BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(IT) fusion::prior(IT)
#else
#   ifdef BOOST_FUSION_ITER_FOLD
#       define BOOST_FUSION_FOLD_NAME iter_fold
#   else
#       define BOOST_FUSION_FOLD_NAME fold
#   endif

#   define BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION begin
#   define BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION next
#   define BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(IT) IT
#   define BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(IT) IT
#endif
#ifdef BOOST_FUSION_ITER_FOLD
#   define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(IT) IT&
#   define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(IT) IT
#else
#   define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(IT)                  \
        typename fusion::result_of::deref<IT>::type
#   define BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(IT) fusion::deref(IT)
#endif

#if (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500)
FUSION_HASH     define BOOST_FUSION_FOLD_IMPL_ENABLER(T) void
FUSION_HASH else
FUSION_HASH     define BOOST_FUSION_FOLD_IMPL_ENABLER(T) typename T::type
FUSION_HASH endif
#else
#   if BOOST_WORKAROUND(BOOST_MSVC, < 1500)
#       define BOOST_FUSION_FOLD_IMPL_ENABLER(T) void
#   else
#       define BOOST_FUSION_FOLD_IMPL_ENABLER(T) typename T::type
#   endif
#endif

namespace boost { namespace fusion
{
    namespace detail
    {
        template<int SeqSize, typename It, typename State, typename F, typename = void
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500)
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, < 1500) || \
    (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
          // Dirty hack: those compilers cannot choose exactly one partial specialization.
          , bool = SeqSize == 0
#endif
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
FUSION_HASH endif
#endif
        >
        struct BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)
        {};

        template<typename It, typename State, typename F>
        struct BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<0,It,State,F
          , typename boost::enable_if_has_type<BOOST_FUSION_FOLD_IMPL_ENABLER(State)>::type
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500)
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, < 1500) || \
    (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
          , true
#endif
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
FUSION_HASH endif
#endif
          >
        {
            typedef typename State::type type;
        };

        template<int SeqSize, typename It, typename State, typename F>
        struct BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<SeqSize,It,State,F
          , typename boost::enable_if_has_type<
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, >= 1500)
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1500) || \
    (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
                // Following SFINAE enables to avoid MSVC 9's partial specialization
                // ambiguous bug but MSVC 8 don't compile, and moreover MSVC 8 style
                // workaround won't work with MSVC 9.
                typename boost::disable_if_c<SeqSize == 0, State>::type::type
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
FUSION_HASH else
                BOOST_FUSION_FOLD_IMPL_ENABLER(State)
#endif
#else
                BOOST_FUSION_FOLD_IMPL_ENABLER(State)
#endif
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
FUSION_HASH endif
#endif
            >::type
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
FUSION_HASH if BOOST_WORKAROUND BOOST_PREVENT_MACRO_SUBSTITUTION (BOOST_MSVC, < 1500)
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, < 1500) || \
    (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
          , false
#endif
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
FUSION_HASH endif
#endif
          >
          : BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<
                SeqSize-1
              , typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<It>::type
              , boost::result_of<
                    F(
                        typename add_reference<typename State::type>::type,
                        BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(It const)
                    )
                >
              , F
            >
        {};

        template<typename It, typename State, typename F>
        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
        inline typename BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<
            0
          , It
          , State
          , F
        >::type
        BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)(mpl::int_<0>, It const&, typename State::type state, F&)
        {
            return state;
        }

        template<typename It, typename State, typename F, int SeqSize>
        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
        inline typename lazy_enable_if_c<
            SeqSize != 0
          , BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<
                SeqSize
              , It
              , State
              , F
            >
        >::type
        BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)(mpl::int_<SeqSize>, It const& it, typename State::type state, F& f)
        {
            return BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)<
                typename result_of::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION<It>::type
              , boost::result_of<
                    F(
                        typename add_reference<typename State::type>::type,
                        BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM(It const)
                    )
                >
              , F
            >(
                mpl::int_<SeqSize-1>()
              , fusion::BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION(it)
              , f(state, BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM(it))
              , f
            );
        }

        template<typename Seq, typename State, typename F
          , bool = traits::is_sequence<Seq>::value
          , bool = traits::is_segmented<Seq>::value>
        struct BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME)
        {};

        template<typename Seq, typename State, typename F>
        struct BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME)<Seq, State, F, true, false>
          : BOOST_PP_CAT(result_of_it_,BOOST_FUSION_FOLD_NAME)<
                result_of::size<Seq>::value
              , BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(
                    typename result_of::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION<Seq>::type
                )
              , add_reference<State>
              , F
            >
        {};

        template<typename Seq, typename State, typename F>
        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
        inline typename BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME)<Seq, State, F>::type
        BOOST_FUSION_FOLD_NAME(Seq& seq, State& state, F& f)
        {
            return BOOST_PP_CAT(it_,BOOST_FUSION_FOLD_NAME)<
                BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM(
                    typename result_of::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION<Seq>::type
                )
              , add_reference<State>
              , F
            >(
                typename result_of::size<Seq>::type()
              , BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM(
                    fusion::BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION(seq)
                )
              , state
              , f
            );
        }
    }

    namespace result_of
    {
        template<typename Seq, typename State, typename F>
        struct BOOST_FUSION_FOLD_NAME
          : detail::BOOST_PP_CAT(result_of_,BOOST_FUSION_FOLD_NAME)<Seq, State, F>
        {};
    }

    template<typename Seq, typename State, typename F>
    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
    inline typename result_of::BOOST_FUSION_FOLD_NAME<
        Seq
      , State const
      , F
    >::type
    BOOST_FUSION_FOLD_NAME(Seq& seq, State const& state, F f)
    {
        return detail::BOOST_FUSION_FOLD_NAME<Seq, State const, F>(seq, state, f);
    }

    template<typename Seq, typename State, typename F>
    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
    inline typename result_of::BOOST_FUSION_FOLD_NAME<
        Seq const
      , State const
      , F
    >::type
    BOOST_FUSION_FOLD_NAME(Seq const& seq, State const& state, F f)
    {
        return detail::BOOST_FUSION_FOLD_NAME<Seq const, State const, F>(seq, state, f);
    }

    template<typename Seq, typename State, typename F>
    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
    inline typename result_of::BOOST_FUSION_FOLD_NAME<
        Seq
      , State
      , F
    >::type
    BOOST_FUSION_FOLD_NAME(Seq& seq, State& state, F f)
    {
        return detail::BOOST_FUSION_FOLD_NAME<Seq, State, F>(seq, state, f);
    }

    template<typename Seq, typename State, typename F>
    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
    inline typename result_of::BOOST_FUSION_FOLD_NAME<
        Seq const
      , State
      , F
    >::type
    BOOST_FUSION_FOLD_NAME(Seq const& seq, State& state, F f)
    {
        return detail::BOOST_FUSION_FOLD_NAME<Seq const, State, F>(seq, state, f);
    }
}}

#undef BOOST_FUSION_FOLD_NAME
#undef BOOST_FUSION_FOLD_IMPL_ENABLER
#undef BOOST_FUSION_FOLD_IMPL_FIRST_IT_FUNCTION
#undef BOOST_FUSION_FOLD_IMPL_NEXT_IT_FUNCTION
#undef BOOST_FUSION_FOLD_IMPL_FIRST_IT_META_TRANSFORM
#undef BOOST_FUSION_FOLD_IMPL_FIRST_IT_TRANSFORM
#undef BOOST_FUSION_FOLD_IMPL_INVOKE_IT_META_TRANSFORM
#undef BOOST_FUSION_FOLD_IMPL_INVOKE_IT_TRANSFORM
#undef FUSION_HASH


code:
/*
 [auto_generated]
 boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp

 [begin_description]
 Base class for all steppers with an algebra and operations.
 [end_description]

 Copyright 2012-2013 Karsten Ahnert
 Copyright 2012 Mario Mulansky

 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_NUMERIC_ODEINT_STEPPER_BASE_ALGEBRA_STEPPER_BASE_HPP_INCLUDED
#define BOOST_NUMERIC_ODEINT_STEPPER_BASE_ALGEBRA_STEPPER_BASE_HPP_INCLUDED

namespace boost {
namespace numeric {
namespace odeint {

template< class Algebra , class Operations >
class algebra_stepper_base
{
public:

    typedef Algebra algebra_type;
    typedef Operations operations_type;

    algebra_stepper_base( const algebra_type &algebra = algebra_type() )
    : m_algebra( algebra ) { }

    algebra_type& algebra()
    {
        return m_algebra;
    }

    const algebra_type& algebra() const
    {
        return m_algebra;
    }

protected:

    algebra_type m_algebra;
};

/******* DOXYGEN *******/

/**
 * \class algebra_stepper_base
 * \brief Base class for all steppers with algebra and operations.
 *
 * This class serves a base class for all steppers with algebra and operations. It holds the
 * algebra and provides access to the algebra.  The operations are not instantiated, since they are
 * static classes inside the operations class.
 *
 * \tparam Algebra The type of the algebra. Must fulfill the Algebra Concept, at least partially to work
 * with the stepper.
 * \tparam Operations The type of the operations. Must fulfill the Operations Concept, at least partially
 * to work with the stepper.
 */

    /**
     * \fn algebra_stepper_base::algebra_stepper_base( const algebra_type &algebra = algebra_type() )
     * \brief Constructs a algebra_stepper_base and creates the algebra. This constructor can be used as a default
     * constructor if the algebra has a default constructor.
     * \param algebra The algebra_stepper_base stores and uses a copy of algebra.
     */

    /**
     * \fn algebra_type& algebra_stepper_base::algebra()
     * \return A reference to the algebra which is held by this class.
     */

    /**
     * \fn const algebra_type& algebra_stepper_base::algebra() const
     * \return A const reference to the algebra which is held by this class.
     */

} // odeint
} // numeric
} // boost

#endif // BOOST_NUMERIC_ODEINT_STEPPER_BASE_ALGEBRA_STEPPER_BASE_HPP_INCLUDED


code:
//  Copyright (c) 2011 John Maddock
//  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)

#ifndef BOOST_MATH_BESSEL_JN_SERIES_HPP
#define BOOST_MATH_BESSEL_JN_SERIES_HPP

#ifdef _MSC_VER
#pragma once
#endif

namespace boost { namespace math { namespace detail{

template <class T, class Policy>
struct bessel_j_small_z_series_term
{
   typedef T result_type;

   bessel_j_small_z_series_term(T v_, T x)
      : N(0), v(v_)
   {
      BOOST_MATH_STD_USING
      mult = x / 2;
      mult *= -mult;
      term = 1;
   }
   T operator()()
   {
      T r = term;
      ++N;
      term *= mult / (N * (N + v));
      return r;
   }
private:
   unsigned N;
   T v;
   T mult;
   T term;
};
//
// Series evaluation for BesselJ(v, z) as z -> 0.
// See http://functions.wolfram.com/Bessel-TypeFunctions/BesselJ/06/01/04/01/01/0003/
// Converges rapidly for all z << v.
//
template <class T, class Policy>
inline T bessel_j_small_z_series(T v, T x, const Policy& pol)
{
   BOOST_MATH_STD_USING
   T prefix;
   if(v < max_factorial<T>::value)
   {
      prefix = pow(x / 2, v) / boost::math::tgamma(v+1, pol);
   }
   else
   {
      prefix = v * log(x / 2) - boost::math::lgamma(v+1, pol);
      prefix = exp(prefix);
   }
   if(0 == prefix)
      return prefix;

   bessel_j_small_z_series_term<T, Policy> s(v, x);
   boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
   T zero = 0;
   T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter, zero);
#else
   T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter);
#endif
   policies::check_series_iterations<T>("boost::math::bessel_j_small_z_series<%1%>(%1%,%1%)", max_iter, pol);
   return prefix * result;
}

template <class T, class Policy>
struct bessel_y_small_z_series_term_a
{
   typedef T result_type;

   bessel_y_small_z_series_term_a(T v_, T x)
      : N(0), v(v_)
   {
      BOOST_MATH_STD_USING
      mult = x / 2;
      mult *= -mult;
      term = 1;
   }
   T operator()()
   {
      BOOST_MATH_STD_USING
      T r = term;
      ++N;
      term *= mult / (N * (N - v));
      return r;
   }
private:
   unsigned N;
   T v;
   T mult;
   T term;
};

template <class T, class Policy>
struct bessel_y_small_z_series_term_b
{
   typedef T result_type;

   bessel_y_small_z_series_term_b(T v_, T x)
      : N(0), v(v_)
   {
      BOOST_MATH_STD_USING
      mult = x / 2;
      mult *= -mult;
      term = 1;
   }
   T operator()()
   {
      T r = term;
      ++N;
      term *= mult / (N * (N + v));
      return r;
   }
private:
   unsigned N;
   T v;
   T mult;
   T term;
};
//
// Series form for BesselY as z -> 0,
// see: http://functions.wolfram.com/Bessel-TypeFunctions/BesselY/06/01/04/01/01/0003/
// This series is only useful when the second term is small compared to the first
// otherwise we get catestrophic cancellation errors.
//
// Approximating tgamma(v) by v^v, and assuming |tgamma(-z)| < eps we end up requiring:
// eps/2 * v^v(x/2)^-v > (x/2)^v or log(eps/2) > v log((x/2)^2/v)
//
template <class T, class Policy>
inline T bessel_y_small_z_series(T v, T x, T* pscale, const Policy& pol)
{
   BOOST_MATH_STD_USING
   static const char* function = "bessel_y_small_z_series<%1%>(%1%,%1%)";
   T prefix;
   T gam;
   T p = log(x / 2);
   T scale = 1;
   bool need_logs = (v >= max_factorial<T>::value) || (tools::log_max_value<T>() / v < fabs(p));
   if(!need_logs)
   {
      gam = boost::math::tgamma(v, pol);
      p = pow(x / 2, v);
      if(tools::max_value<T>() * p < gam)
      {
         scale /= gam;
         gam = 1;
         if(tools::max_value<T>() * p < gam)
         {
            return -policies::raise_overflow_error<T>(function, 0, pol);
         }
      }
      prefix = -gam / (constants::pi<T>() * p);
   }
   else
   {
      gam = boost::math::lgamma(v, pol);
      p = v * p;
      prefix = gam - log(constants::pi<T>()) - p;
      if(tools::log_max_value<T>() < prefix)
      {
         prefix -= log(tools::max_value<T>() / 4);
         scale /= (tools::max_value<T>() / 4);
         if(tools::log_max_value<T>() < prefix)
         {
            return -policies::raise_overflow_error<T>(function, 0, pol);
         }
      }
      prefix = -exp(prefix);
   }
   bessel_y_small_z_series_term_a<T, Policy> s(v, x);
   boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
   *pscale = scale;
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
   T zero = 0;
   T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter, zero);
#else
   T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter);
#endif
   policies::check_series_iterations<T>("boost::math::bessel_y_small_z_series<%1%>(%1%,%1%)", max_iter, pol);
   result *= prefix;

   if(!need_logs)
   {
      prefix = boost::math::tgamma(-v, pol) * boost::math::cos_pi(v) * p / constants::pi<T>();
   }
   else
   {
      int sgn;
      prefix = boost::math::lgamma(-v, &sgn, pol) + p;
      prefix = exp(prefix) * sgn / constants::pi<T>();
   }
   bessel_y_small_z_series_term_b<T, Policy> s2(v, x);
   max_iter = policies::get_max_series_iterations<Policy>();
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
   T b = boost::math::tools::sum_series(s2, boost::math::policies::get_epsilon<T, Policy>(), max_iter, zero);
#else
   T b = boost::math::tools::sum_series(s2, boost::math::policies::get_epsilon<T, Policy>(), max_iter);
#endif
   result -= scale * prefix * b;
   return result;
}

template <class T, class Policy>
T bessel_yn_small_z(int n, T z, T* scale, const Policy& pol)
{
   //
   // See http://functions.wolfram.com/Bessel-TypeFunctions/BesselY/06/01/04/01/02/
   //
   // Note that when called we assume that x < epsilon and n is a positive integer.
   //
   BOOST_MATH_STD_USING
   BOOST_ASSERT(n >= 0);
   BOOST_ASSERT((z < policies::get_epsilon<T, Policy>()));

   if(n == 0)
   {
      return (2 / constants::pi<T>()) * (log(z / 2) +  constants::euler<T>());
   }
   else if(n == 1)
   {
      return (z / constants::pi<T>()) * log(z / 2)
         - 2 / (constants::pi<T>() * z)
         - (z / (2 * constants::pi<T>())) * (1 - 2 * constants::euler<T>());
   }
   else if(n == 2)
   {
      return (z * z) / (4 * constants::pi<T>()) * log(z / 2)
         - (4 / (constants::pi<T>() * z * z))
         - ((z * z) / (8 * constants::pi<T>())) * (T(3)/2 - 2 * constants::euler<T>());
   }
   else
   {
      T p = pow(z / 2, n);
      T result = -((boost::math::factorial<T>(n - 1) / constants::pi<T>()));
      if(p * tools::max_value<T>() < result)
      {
         T div = tools::max_value<T>() / 8;
         result /= div;
         *scale /= div;
         if(p * tools::max_value<T>() < result)
         {
            return -policies::raise_overflow_error<T>("bessel_yn_small_z<%1%>(%1%,%1%)", 0, pol);
         }
      }
      return result / p;
   }
}

}}} // namespaces

#endif // BOOST_MATH_BESSEL_JN_SERIES_HPP


code:
# Makefile for Windows in JTSDK-PY environment

# Re-direct stdout and stderr:     cmd.exe              bash
#                              make > junk 2>&1      make &> junk

CC = gcc
FC = gfortran

FFLAGS = -O2 -DWIN32 -fbounds-check -fno-second-underscore -Wall \
       -Wno-conversion -Wno-character-truncation
CFLAGS = -I. -DWIN32 -DWin32 -DBIGSYM -DHAVE_STRUCT_TIMESPEC

# Default rules
%.o: %.c
	${CC} ${CFLAGS} -c $<
%.o: %.f
	${FC} ${FFLAGS} -c $<
%.o: %.F
	${FC} ${FFLAGS} -c $<
%.o: %.f90
	${FC} ${FFLAGS} -c $<
%.o: %.F90
	${FC} ${FFLAGS} -c $<

all:    libftrsd.a

OBJS1 = extract2.o ftrsd2.o init_rs_int.o encode_rs_int.o decode_rs_int.o
libftrsd.a: $(OBJS1)
	ar cr libftrsd.a $(OBJS1)
	ranlib libftrsd.a
	cp libftrsd.a ..

# Build rsdtest
OBJS2 = rsdtest.o
rsdtest: $(OBJS2) ../libjt.a
	$(FC) -o rsdtest $(OBJS2) libftrsd.a ../libjt.a ../libpthreadGC2.a

ftrsd: ftrsd.o encode_rs_int.o decode_rs_int.o init_rs_int.o
	gcc -g -o $@ $^

encode_rs_int.o: encode_rs.c
	gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^

decode_rs_int.o: decode_rs.c
	gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^

init_rs_int.o: init_rs.c
	gcc -DBIGSYM=1 $(CFLAGS) -c -o $@ $^

.PHONY : clean

clean:
	rm -rf *.o libjt.a rsdtest ftrsd


code:
#if !BOOST_PHOENIX_IS_ITERATING

#if !defined(BOOST_PHOENIX_DONT_USE_PREPROCESSED_FILES)

#include <boost/phoenix/operator/detail/cpp03/preprocessed/mem_fun_ptr_gen.hpp>

#else

#if defined(__WAVE__) && defined(BOOST_PHOENIX_CREATE_PREPROCESSED_FILES)
#pragma wave option(preserve: 2, line: 0, output: "preprocessed/mem_fun_ptr_gen_" BOOST_PHOENIX_LIMIT_STR ".hpp")
#endif

/*==============================================================================
    Copyright (c) 2001-2010 Joel de Guzman
    Copyright (c) 2010 Thomas Heller

    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)
==============================================================================*/

#if defined(__WAVE__) && defined(BOOST_PHOENIX_CREATE_PREPROCESSED_FILES)
#pragma wave option(preserve: 1)
#endif

    namespace detail {
        template <typename Object, typename MemPtr>
        struct mem_fun_ptr_gen
        {
            mem_fun_ptr_gen(Object const& obj_, MemPtr ptr_)
              : obj(obj_)
              , ptr(ptr_)
            {}

            typename phoenix::expression::mem_fun_ptr<Object, MemPtr>::type const
            operator()() const
            {
                return phoenix::expression::mem_fun_ptr<Object, MemPtr>::make(obj, ptr);
            }

#define BOOST_PHOENIX_ITERATION_PARAMS                                          \
        (3, (1, BOOST_PHOENIX_MEMBER_LIMIT,                                     \
        <boost/phoenix/operator/detail/cpp03/mem_fun_ptr_gen.hpp>))             \

#include BOOST_PHOENIX_ITERATE()

            Object const& obj;
            MemPtr ptr;

        };

        struct make_mem_fun_ptr_gen
            : proto::callable
        {
            template<typename Sig>
            struct result;

            template<typename This, typename Object, typename MemPtr>
            struct result<This(Object, MemPtr)>
            {
                typedef
                    mem_fun_ptr_gen<
                        typename remove_const<typename remove_reference<Object>::type>::type
                      , typename remove_const<typename remove_reference<MemPtr>::type>::type
                    >
                type;
            };

            template<typename Object, typename MemPtr>
            mem_fun_ptr_gen<Object, MemPtr> operator()(Object const & obj, MemPtr ptr) const
            {
                return mem_fun_ptr_gen<Object, MemPtr>(obj, ptr);
            }
        };
    }

#if defined(__WAVE__) && defined(BOOST_PHOENIX_CREATE_PREPROCESSED_FILES)
#pragma wave option(output: null)
#endif

#endif // BOOST_PHOENIX_DONT_USE_PREPROCESSED_FILES

#else
            template <BOOST_PHOENIX_typename_A>
            typename phoenix::expression::mem_fun_ptr<
                Object
              , MemPtr
              , BOOST_PHOENIX_A
            >::type const
            operator()(BOOST_PHOENIX_A_const_ref_a) const
            {
                return phoenix::expression::mem_fun_ptr<
                    Object
                  , MemPtr
                  , BOOST_PHOENIX_A
                >::make(obj, ptr, BOOST_PHOENIX_a);
            }
#endif


code:
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_UNITS_GET_SYSTEM_HPP
#define BOOST_UNITS_GET_SYSTEM_HPP

/// \file
/// \brief Get the system of a unit, absolute unit or quantity.

#include <boost/units/units_fwd.hpp>

namespace boost {

namespace units {

template<class T>
struct get_system {};

/// Get the system of a unit.
template<class Dim,class System>
struct get_system< unit<Dim,System> >
{
    typedef System type;
};

/// Get the system of an absolute unit.
template<class Unit>
struct get_system< absolute<Unit> >
{
    typedef typename get_system<Unit>::type type;
};

/// Get the system of a quantity.
template<class Unit,class Y>
struct get_system< quantity<Unit,Y> >
{
    typedef typename get_system<Unit>::type     type;
};

} // namespace units

} // namespace boost

#endif // BOOST_UNITS_GET_SYSTEM_HPP


code:
/* boost random/detail/polynomial.hpp header file
 *
 * Copyright Steven Watanabe 2014
 * Distributed under the Boost Software License, Version 1.0. (See
 * accompanying file LICENSE_1_0.txt or copy at
 * http://www.boost.org/LICENSE_1_0.txt)
 *
 * See http://www.boost.org for most recent version including documentation.
 *
 * $Id$
 */

#ifndef BOOST_RANDOM_DETAIL_POLYNOMIAL_HPP
#define BOOST_RANDOM_DETAIL_POLYNOMIAL_HPP

#include <cstddef>
#include <limits>
#include <vector>
#include <algorithm>
#include <boost/assert.hpp>
#include <boost/cstdint.hpp>

namespace boost {
namespace random {
namespace detail {

class polynomial_ops {
public:
    typedef unsigned long digit_t;

    static void add(std::size_t size, const digit_t * lhs,
                       const digit_t * rhs, digit_t * output)
    {
        for(std::size_t i = 0; i < size; ++i) {
            output[i] = lhs[i] ^ rhs[i];
        }
    }

    static void add_shifted_inplace(std::size_t size, const digit_t * lhs,
                                    digit_t * output, std::size_t shift)
    {
        if(shift == 0) {
            add(size, lhs, output, output);
            return;
        }
        std::size_t bits = std::numeric_limits<digit_t>::digits;
        digit_t prev = 0;
        for(std::size_t i = 0; i < size; ++i) {
            digit_t tmp = lhs[i];
            output[i] ^= (tmp << shift) | (prev >> (bits-shift));
            prev = tmp;
        }
        output[size] ^= (prev >> (bits-shift));
    }

    static void multiply_simple(std::size_t size, const digit_t * lhs,
                                   const digit_t * rhs, digit_t * output)
    {
        std::size_t bits = std::numeric_limits<digit_t>::digits;
        for(std::size_t i = 0; i < 2*size; ++i) {
            output[i] = 0;
        }
        for(std::size_t i = 0; i < size; ++i) {
            for(std::size_t j = 0; j < bits; ++j) {
                if((lhs[i] & (digit_t(1) << j)) != 0) {
                    add_shifted_inplace(size, rhs, output + i, j);
                }
            }
        }
    }

    // memory requirements: (size - cutoff) * 4 + next_smaller
    static void multiply_karatsuba(std::size_t size,
                               const digit_t * lhs, const digit_t * rhs,
                               digit_t * output)
    {
        if(size < 64) {
            multiply_simple(size, lhs, rhs, output);
            return;
        }
        // split in half
        std::size_t cutoff = size/2;
        multiply_karatsuba(cutoff, lhs, rhs, output);
        multiply_karatsuba(size - cutoff, lhs + cutoff, rhs + cutoff,
                              output + cutoff*2);
        std::vector<digit_t> local1(size - cutoff);
        std::vector<digit_t> local2(size - cutoff);
        // combine the digits for the inner multiply
        add(cutoff, lhs, lhs + cutoff, &local1[0]);
        if(size & 1) local1[cutoff] = lhs[size - 1];
        add(cutoff, rhs + cutoff, rhs, &local2[0]);
        if(size & 1) local2[cutoff] = rhs[size - 1];
        std::vector<digit_t> local3((size - cutoff) * 2);
        multiply_karatsuba(size - cutoff, &local1[0], &local2[0], &local3[0]);
        add(cutoff * 2, output, &local3[0], &local3[0]);
        add((size - cutoff) * 2, output + cutoff*2, &local3[0], &local3[0]);
        // Finally, add the inner result
        add((size - cutoff) * 2, output + cutoff, &local3[0], output + cutoff);
    }

    static void multiply_add_karatsuba(std::size_t size,
                                       const digit_t * lhs, const digit_t * rhs,
                                       digit_t * output)
    {
        std::vector<digit_t> buf(size * 2);
        multiply_karatsuba(size, lhs, rhs, &buf[0]);
        add(size * 2, &buf[0], output, output);
    }

    static void multiply(const digit_t * lhs, std::size_t lhs_size,
                         const digit_t * rhs, std::size_t rhs_size,
                         digit_t * output)
    {
        std::fill_n(output, lhs_size + rhs_size, digit_t(0));
        multiply_add(lhs, lhs_size, rhs, rhs_size, output);
    }

    static void multiply_add(const digit_t * lhs, std::size_t lhs_size,
                             const digit_t * rhs, std::size_t rhs_size,
                             digit_t * output)
    {
        // split into pieces that can be passed to
        // karatsuba multiply.
        while(lhs_size != 0) {
            if(lhs_size < rhs_size) {
                std::swap(lhs, rhs);
                std::swap(lhs_size, rhs_size);
            }

            multiply_add_karatsuba(rhs_size, lhs, rhs, output);

            lhs += rhs_size;
            lhs_size -= rhs_size;
            output += rhs_size;
        }
    }

    static void copy_bits(const digit_t * x, std::size_t low, std::size_t high,
                   digit_t * out)
    {
        const std::size_t bits = std::numeric_limits<digit_t>::digits;
        std::size_t offset = low/bits;
        x += offset;
        low -= offset*bits;
        high -= offset*bits;
        std::size_t n = (high-low)/bits;
        if(low == 0) {
            for(std::size_t i = 0; i < n; ++i) {
                out[i] = x[i];
            }
        } else {
            for(std::size_t i = 0; i < n; ++i) {
                out[i] = (x[i] >> low) | (x[i+1] << (bits-low));
            }
        }
        if((high-low)%bits) {
            digit_t low_mask = (digit_t(1) << ((high-low)%bits)) - 1;
            digit_t result = (x[n] >> low);
            if(low != 0 && (n+1)*bits < high) {
                result |= (x[n+1] << (bits-low));
            }
            out[n] = (result & low_mask);
        }
    }

    static void shift_left(digit_t * val, std::size_t size, std::size_t shift)
    {
        const std::size_t bits = std::numeric_limits<digit_t>::digits;
        BOOST_ASSERT(shift > 0);
        BOOST_ASSERT(shift < bits);
        digit_t prev = 0;
        for(std::size_t i = 0; i < size; ++i) {
            digit_t tmp = val[i];
            val[i] = (prev >> (bits - shift)) | (val[i] << shift);
            prev = tmp;
        }
    }

    static digit_t sqr(digit_t val) {
        const std::size_t bits = std::numeric_limits<digit_t>::digits;
        digit_t mask = (digit_t(1) << bits/2) - 1;
        for(std::size_t i = bits; i > 1; i /= 2) {
            val = ((val & ~mask) << i/2) | (val & mask);
            mask = mask & (mask >> i/4);
            mask = mask | (mask << i/2);
        }
        return val;
    }

    static void sqr(digit_t * val, std::size_t size)
    {
        const std::size_t bits = std::numeric_limits<digit_t>::digits;
        digit_t mask = (digit_t(1) << bits/2) - 1;
        for(std::size_t i = 0; i < size; ++i) {
            digit_t x = val[size - i - 1];
            val[(size - i - 1) * 2] = sqr(x & mask);
            val[(size - i - 1) * 2 + 1] = sqr(x >> bits/2);
        }
    }

    // optimized for the case when the modulus has few bits set.
    struct sparse_mod {
        sparse_mod(const digit_t * divisor, std::size_t divisor_bits)
        {
            const std::size_t bits = std::numeric_limits<digit_t>::digits;
            _remainder_bits = divisor_bits - 1;
            for(std::size_t i = 0; i < divisor_bits; ++i) {
                if(divisor[i/bits] & (digit_t(1) << i%bits)) {
                    _bit_indices.push_back(i);
                }
            }
            BOOST_ASSERT(_bit_indices.back() == divisor_bits - 1);
            _bit_indices.pop_back();
            if(_bit_indices.empty()) {
                _block_bits = divisor_bits;
                _lower_bits = 0;
            } else {
                _block_bits = divisor_bits - _bit_indices.back() - 1;
                _lower_bits = _bit_indices.back() + 1;
            }

            _partial_quotient.resize((_block_bits + bits - 1)/bits);
        }
        void operator()(digit_t * dividend, std::size_t dividend_bits)
        {
            const std::size_t bits = std::numeric_limits<digit_t>::digits;
            while(dividend_bits > _remainder_bits) {
                std::size_t block_start = (std::max)(dividend_bits - _block_bits, _remainder_bits);
                std::size_t block_size = (dividend_bits - block_start + bits - 1) / bits;
                copy_bits(dividend, block_start, dividend_bits, &_partial_quotient[0]);
                for(std::size_t i = 0; i < _bit_indices.size(); ++i) {
                    std::size_t pos = _bit_indices[i] + block_start - _remainder_bits;
                    add_shifted_inplace(block_size, &_partial_quotient[0], dividend + pos/bits, pos%bits);
                }
                add_shifted_inplace(block_size, &_partial_quotient[0], dividend + block_start/bits, block_start%bits);
                dividend_bits = block_start;
            }
        }
        std::vector<digit_t> _partial_quotient;
        std::size_t _remainder_bits;
        std::size_t _block_bits;
        std::size_t _lower_bits;
        std::vector<std::size_t> _bit_indices;
    };

    // base should have the same number of bits as mod
    // base, and mod should both be able to hold a power
    // of 2 >= mod_bits.  out needs to be twice as large.
    static void mod_pow_x(boost::uintmax_t exponent, const digit_t * mod, std::size_t mod_bits, digit_t * out)
    {
        const std::size_t bits = std::numeric_limits<digit_t>::digits;
        const std::size_t n = (mod_bits + bits - 1) / bits;
        const std::size_t highbit = mod_bits - 1;
        if(exponent == 0) {
            out[0] = 1;
            std::fill_n(out + 1, n - 1, digit_t(0));
            return;
        }
        boost::uintmax_t i = std::numeric_limits<boost::uintmax_t>::digits - 1;
        while(((boost::uintmax_t(1) << i) & exponent) == 0) {
            --i;
        }
        out[0] = 2;
        std::fill_n(out + 1, n - 1, digit_t(0));
        sparse_mod m(mod, mod_bits);
        while(i--) {
            sqr(out, n);
            m(out, 2 * mod_bits - 1);
            if((boost::uintmax_t(1) << i) & exponent) {
                shift_left(out, n, 1);
                if(out[highbit / bits] & (digit_t(1) << highbit%bits))
                    add(n, out, mod, out);
            }
        }
    }
};

class polynomial
{
    typedef polynomial_ops::digit_t digit_t;
public:
    polynomial() : _size(0) {}
    class reference {
    public:
        reference(digit_t &value, int idx)
            : _value(value), _idx(idx) {}
        operator bool() const { return (_value & (digit_t(1) << _idx)) != 0; }
        reference& operator=(bool b)
        {
            if(b) {
                _value |= (digit_t(1) << _idx);
            } else {
                _value &= ~(digit_t(1) << _idx);
            }
            return *this;
        }
        reference &operator^=(bool b)
        {
            _value ^= (digit_t(b) << _idx);
            return *this;
        }

        reference &operator=(const reference &other)
        {
            return *this = static_cast<bool>(other);
        }
    private:
        digit_t &_value;
        int _idx;
    };
    reference operator[](std::size_t i)
    {
        static const std::size_t bits = std::numeric_limits<digit_t>::digits;
        ensure_bit(i);
        return reference(_storage[i/bits], i%bits);
    }
    bool operator[](std::size_t i) const
    {
        static const std::size_t bits = std::numeric_limits<digit_t>::digits;
        if(i < size())
            return (_storage[i/bits] & (digit_t(1) << (i%bits))) != 0;
        else
            return false;
    }
    std::size_t size() const
    {
        return _size;
    }
    void resize(std::size_t n)
    {
        static const std::size_t bits = std::numeric_limits<digit_t>::digits;
        _storage.resize((n + bits - 1)/bits);
        // clear the high order bits in case we're shrinking.
        if(n%bits) {
            _storage.back() &= ((digit_t(1) << (n%bits)) - 1);
        }
        _size = n;
    }
    friend polynomial operator*(const polynomial &lhs, const polynomial &rhs);
    friend polynomial mod_pow_x(boost::uintmax_t exponent, polynomial mod);
private:
    std::vector<polynomial_ops::digit_t> _storage;
    std::size_t _size;
    void ensure_bit(std::size_t i)
    {
        if(i >= size()) {
            resize(i + 1);
        }
    }
    void normalize()
    {
        while(size() && (*this)[size() - 1] == 0)
            resize(size() - 1);
    }
};

inline polynomial operator*(const polynomial &lhs, const polynomial &rhs)
{
    polynomial result;
    result._storage.resize(lhs._storage.size() + rhs._storage.size());
    polynomial_ops::multiply(&lhs._storage[0], lhs._storage.size(),
                             &rhs._storage[0], rhs._storage.size(),
                             &result._storage[0]);
    result._size = lhs._size + rhs._size;
    return result;
}

inline polynomial mod_pow_x(boost::uintmax_t exponent, polynomial mod)
{
    polynomial result;
    mod.normalize();
    std::size_t mod_size = mod.size();
    result._storage.resize(mod._storage.size() * 2);
    result._size = mod.size() * 2;
    polynomial_ops::mod_pow_x(exponent, &mod._storage[0], mod_size, &result._storage[0]);
    result.resize(mod.size() - 1);
    return result;
}

}
}
}

#endif // BOOST_RANDOM_DETAIL_POLYNOMIAL_HPP


code:
/*=============================================================================
    Copyright (c) 1998-2003 Joel de Guzman
    Copyright (c) 2001 Daniel Nuffer
    Copyright (c) 2002 Hartmut Kaiser
    http://spirit.sourceforge.net/

    Use, modification and distribution is subject to the Boost Software
    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_POSITIVE_IPP)
#define BOOST_SPIRIT_POSITIVE_IPP

namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

    ///////////////////////////////////////////////////////////////////////////
    //
    //  positive class implementation
    //
    ///////////////////////////////////////////////////////////////////////////
    template <typename S>
    inline positive<S>
    operator+(parser<S> const& a)
    {
        return positive<S>(a.derived());
    }

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}} // namespace boost::spirit

#endif