code:
///////////////////////////////////////////////////////////////////////////////
/// \file proto_fwd.hpp
/// Forward declarations of all of proto's public types and functions.
//
//  Copyright 2008 Eric Niebler. 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_PROTO_FWD_HPP_EAN_04_01_2005
#define BOOST_PROTO_FWD_HPP_EAN_04_01_2005

#include <cstddef>
#include <climits>
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/punctuation/comma.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/ref.hpp>
#include <boost/mpl/long.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/mpl/aux_/config/ttp.hpp>
#include <boost/utility/result_of.hpp>

#ifndef BOOST_PROTO_MAX_ARITY
# define BOOST_PROTO_MAX_ARITY 10
#endif

#ifndef BOOST_PROTO_MAX_LOGICAL_ARITY
# define BOOST_PROTO_MAX_LOGICAL_ARITY 10
#endif

#ifndef BOOST_PROTO_MAX_FUNCTION_CALL_ARITY
# define BOOST_PROTO_MAX_FUNCTION_CALL_ARITY BOOST_PROTO_MAX_ARITY
#endif

#if BOOST_PROTO_MAX_ARITY < 3
# error BOOST_PROTO_MAX_ARITY must be at least 3
#endif

#if BOOST_PROTO_MAX_FUNCTION_CALL_ARITY > BOOST_PROTO_MAX_ARITY
# error BOOST_PROTO_MAX_FUNCTION_CALL_ARITY cannot be larger than BOOST_PROTO_MAX_ARITY
#endif

#ifndef BOOST_PROTO_DONT_USE_PREPROCESSED_FILES
  #if 10 < BOOST_PROTO_MAX_ARITY ||                                                                 \
      10 < BOOST_PROTO_MAX_LOGICAL_ARITY ||                                                         \
      10 < BOOST_PROTO_MAX_FUNCTION_CALL_ARITY
    #define BOOST_PROTO_DONT_USE_PREPROCESSED_FILES
  #endif
#endif

#ifndef BOOST_PROTO_BROKEN_CONST_OVERLOADS
# if BOOST_WORKAROUND(__GNUC__, == 3) \
  || BOOST_WORKAROUND(__EDG_VERSION__, BOOST_TESTED_AT(310))
#  define BOOST_PROTO_BROKEN_CONST_OVERLOADS
# endif
#endif

#ifndef BOOST_PROTO_BROKEN_CONST_QUALIFIED_FUNCTIONS
# if BOOST_WORKAROUND(__GNUC__, == 3) \
  || BOOST_WORKAROUND(__EDG_VERSION__, BOOST_TESTED_AT(310))
#  define BOOST_PROTO_BROKEN_CONST_QUALIFIED_FUNCTIONS
# endif
#endif

#ifdef BOOST_PROTO_BROKEN_CONST_OVERLOADS
# include <boost/utility/enable_if.hpp>
# include <boost/type_traits/is_const.hpp>
# define BOOST_PROTO_DISABLE_IF_IS_CONST(T)\
    , typename boost::disable_if_c<boost::is_const<T>::value, boost::proto::detail::undefined>::type * = 0
#else
# define BOOST_PROTO_DISABLE_IF_IS_CONST(T)
#endif

#ifdef BOOST_PROTO_BROKEN_CONST_QUALIFIED_FUNCTIONS
# include <boost/utility/enable_if.hpp>
# include <boost/type_traits/is_function.hpp>
# define BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T)\
    , typename boost::disable_if_c<boost::is_function<T>::value, boost::proto::detail::undefined>::type * = 0
#else
# define BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T)
#endif

#ifndef BOOST_PROTO_BROKEN_PTS
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
#  define BOOST_PROTO_BROKEN_PTS
# endif
#endif

#ifdef BOOST_NO_CXX11_DECLTYPE_N3276
# // Proto can only use the decltype-based result_of if N3276 has been
# // implemented by the compiler.
# // See http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3276.pdf
# ifndef BOOST_PROTO_USE_NORMAL_RESULT_OF
#  define BOOST_PROTO_USE_NORMAL_RESULT_OF
# endif
#endif

// Unless compiler support is there, use tr1_result_of instead of
// result_of to avoid the problems addressed by N3276.
#ifdef BOOST_PROTO_USE_NORMAL_RESULT_OF
# define BOOST_PROTO_RESULT_OF boost::result_of
#else
# define BOOST_PROTO_RESULT_OF boost::tr1_result_of
#endif

// If we're using the decltype-based result_of, we need to be a bit
// stricter about the return types of some functions.
#if defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_PROTO_USE_NORMAL_RESULT_OF)
# define BOOST_PROTO_STRICT_RESULT_OF
# define BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(X, Y) X
#else
# define BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(X, Y) Y
#endif

#ifdef BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING
# define BOOST_PROTO_EXTENDED_TEMPLATE_PARAMETERS_MATCHING
#endif

#if defined(_MSC_VER)
# define BOOST_PROTO_DISABLE_MSVC_C4522 __pragma(warning(disable : 4522))  // 'class' : multiple assignment operators specified
# define BOOST_PROTO_DISABLE_MSVC_C4714 __pragma(warning(disable : 4714))  // function 'xxx' marked as __forceinline not inlined
#else
# define BOOST_PROTO_DISABLE_MSVC_C4522
# define BOOST_PROTO_DISABLE_MSVC_C4714
#endif

namespace boost { namespace proto
{
    namespace detail
    {
        typedef char yes_type;
        typedef char (&no_type)[2];

        template<int N>
        struct sized_type
        {
            typedef char (&type)[N];
        };

        struct dont_care;
        struct undefined; // leave this undefined
        struct not_a_valid_type;

        struct private_type_
        {
            private_type_ operator ,(int) const;
        };

        template<typename T>
        struct uncvref
        {
            typedef T type;
        };

        template<typename T>
        struct uncvref<T const>
        {
            typedef T type;
        };

        template<typename T>
        struct uncvref<T &>
        {
            typedef T type;
        };

        template<typename T>
        struct uncvref<T const &>
        {
            typedef T type;
        };

        template<typename T, std::size_t N>
        struct uncvref<T const[N]>
        {
            typedef T type[N];
        };

        template<typename T, std::size_t N>
        struct uncvref<T (&)[N]>
        {
            typedef T type[N];
        };

        template<typename T, std::size_t N>
        struct uncvref<T const (&)[N]>
        {
            typedef T type[N];
        };

        struct ignore
        {
            ignore()
            {}

            template<typename T>
            ignore(T const &)
            {}
        };

        /// INTERNAL ONLY
        ///
        #define BOOST_PROTO_UNCVREF(X)                                                              \
            typename boost::proto::detail::uncvref<X>::type                                         \
            /**/

        struct _default;

        struct not_a_domain;
        struct not_a_grammar;
        struct not_a_generator;

        template<typename T, typename Void = void>
        struct is_transform_;

        template<typename T, typename Void = void>
        struct is_aggregate_;

        template<typename Expr>
        struct flat_view;
    }

    typedef detail::ignore const ignore;

    namespace argsns_
    {
        template<typename Arg0>
        struct term;

        #define M0(Z, N, DATA)                                                                      \
        template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename Arg)> struct BOOST_PP_CAT(list, N);          \
        /**/
        BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), M0, ~)
        #undef M0
    }

    using namespace argsns_;

    ///////////////////////////////////////////////////////////////////////////////
    // Operator tags
    namespace tagns_
    {
        namespace tag
        {
            struct terminal;
            struct unary_plus;
            struct negate;
            struct dereference;
            struct complement;
            struct address_of;
            struct logical_not;
            struct pre_inc;
            struct pre_dec;
            struct post_inc;
            struct post_dec;

            struct shift_left;
            struct shift_right;
            struct multiplies;
            struct divides;
            struct modulus;
            struct plus;
            struct minus;
            struct less;
            struct greater;
            struct less_equal;
            struct greater_equal;
            struct equal_to;
            struct not_equal_to;
            struct logical_or;
            struct logical_and;
            struct bitwise_and;
            struct bitwise_or;
            struct bitwise_xor;
            struct comma;
            struct mem_ptr;

            struct assign;
            struct shift_left_assign;
            struct shift_right_assign;
            struct multiplies_assign;
            struct divides_assign;
            struct modulus_assign;
            struct plus_assign;
            struct minus_assign;
            struct bitwise_and_assign;
            struct bitwise_or_assign;
            struct bitwise_xor_assign;
            struct subscript;
            struct member;
            struct if_else_;
            struct function;

            // Fusion tags
            template<typename Tag, typename Domain> struct proto_expr;
            template<typename Tag, typename Domain> struct proto_expr_iterator;
            template<typename Tag, typename Domain> struct proto_flat_view;
        }
    }

    using namespace tagns_;

    template<typename Expr>
    struct tag_of;

    ////////////////////////////////////////////////////////////////////////////////////////////////
    struct _;

    ////////////////////////////////////////////////////////////////////////////////////////////////
    struct default_generator;

    struct basic_default_generator;

    template<template<typename> class Extends>
    struct generator;

    template<template<typename> class Extends>
    struct pod_generator;

    struct by_value_generator;

    template<typename First, typename Second>
    struct compose_generators;

    template<typename Generator, typename Void = void>
    struct wants_basic_expr;

    template<typename Generator>
    struct use_basic_expr;

    ////////////////////////////////////////////////////////////////////////////////////////////////
    namespace domainns_
    {
        typedef detail::not_a_domain no_super_domain;

        template<
            typename Generator  = default_generator
          , typename Grammar    = proto::_
          , typename Super      = no_super_domain
        >
        struct domain;

        struct default_domain;

        struct basic_default_domain;

        struct deduce_domain;

        template<typename Domain, typename Tag, typename Args, bool WantsBasicExpr = wants_basic_expr<typename Domain::proto_generator>::value>
        struct base_expr;
    }

    using namespace domainns_;

    ////////////////////////////////////////////////////////////////////////////////////////////////
    namespace exprns_
    {
        template<typename Tag, typename Args, long Arity = Args::arity>
        struct basic_expr;

        template<typename Tag, typename Args, long Arity = Args::arity>
        struct expr;

        template<
            typename Expr
          , typename Derived
          , typename Domain = default_domain
          , long Arity = Expr::proto_arity_c
        >
        struct extends;

        template<typename This, typename Fun, typename Domain>
        struct virtual_member;

        struct is_proto_expr;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////

    using exprns_::expr;
    using exprns_::basic_expr;
    using exprns_::extends;
    using exprns_::is_proto_expr;

    template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G, void)>
    struct or_;

    template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G, void)>
    struct and_;

    template<typename Grammar>
    struct not_;

    template<typename Condition, typename Then = _, typename Else = not_<_> >
    struct if_;

    template<typename Cases, typename Transform = tag_of<_>()>
    struct switch_;

    template<typename T>
    struct exact;

    template<typename T>
    struct convertible_to;

    template<typename Grammar>
    struct vararg;

    struct pack;

    // Boost bug https://svn.boost.org/trac/boost/ticket/4602
    //int const N = INT_MAX;
    int const N = (INT_MAX >> 10);

    namespace context
    {
        struct null_context;

        template<typename Expr, typename Context, long Arity = Expr::proto_arity_c>
        struct null_eval;

        struct default_context;

        template<typename Expr, typename Context, typename Tag = typename Expr::proto_tag, long Arity = Expr::proto_arity_c>
        struct default_eval;

        template<typename Derived, typename DefaultCtx = default_context>
        struct callable_context;

        template<typename Expr, typename Context, long Arity = Expr::proto_arity_c>
        struct callable_eval;
    }

    using context::null_context;
    using context::null_eval;
    using context::default_context;
    using context::default_eval;
    using context::callable_context;
    using context::callable_eval;

    namespace utility
    {
        template<typename T, typename Domain = default_domain>
        struct literal;
    }

    using utility::literal;

    namespace result_of
    {
        template<typename T, typename Domain = default_domain>
        struct as_expr;

        template<typename T, typename Domain = default_domain>
        struct as_child;

        template<typename Expr, typename N = mpl::long_<0> >
        struct child;

        template<typename Expr, long N>
        struct child_c;

        template<typename Expr>
        struct left;

        template<typename Expr>
        struct right;

        template<typename Expr>
        struct deep_copy;

        template<typename Expr, typename Context>
        struct eval;

        template<
            typename Tag
          , typename DomainOrA0
            BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
                BOOST_PROTO_MAX_ARITY
              , typename A
              , = void BOOST_PP_INTERCEPT
            )
          , typename Void = void
        >
        struct make_expr;

        template<typename Tag, typename DomainOrSequence, typename SequenceOrVoid = void, typename Void = void>
        struct unpack_expr;

        template<typename T>
        struct as_env;

        template<typename Env, typename Tag>
        struct has_env_var;

        template<typename Env, typename Tag>
        struct env_var;
    }

    template<typename T, typename Void = void>
    struct is_expr;

    template<typename T, typename Void = void>
    struct is_domain;

    template<typename SubDomain, typename SuperDomain>
    struct is_sub_domain_of;

    template<typename T, typename Void = void>
    struct is_env;

    template<typename Expr>
    struct arity_of;

    template<typename T, typename Void = void>
    struct domain_of;

    template<typename Expr, typename Grammar>
    struct matches;

    // Generic expression metafunctions and
    // grammar elements
    template<typename Tag, typename Arg>
    struct unary_expr;

    template<typename Tag, typename Left, typename Right>
    struct binary_expr;

    template<typename Tag, BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_ARITY, typename A, void)>
    struct nary_expr;

    // Specific expression metafunctions and
    // grammar elements, for convenience
    template<typename T> struct terminal;
    template<typename T> struct unary_plus;
    template<typename T> struct negate;
    template<typename T> struct dereference;
    template<typename T> struct complement;
    template<typename T> struct address_of;
    template<typename T> struct logical_not;
    template<typename T> struct pre_inc;
    template<typename T> struct pre_dec;
    template<typename T> struct post_inc;
    template<typename T> struct post_dec;

    template<typename T, typename U> struct shift_left;
    template<typename T, typename U> struct shift_right;
    template<typename T, typename U> struct multiplies;
    template<typename T, typename U> struct divides;
    template<typename T, typename U> struct modulus;
    template<typename T, typename U> struct plus;
    template<typename T, typename U> struct minus;
    template<typename T, typename U> struct less;
    template<typename T, typename U> struct greater;
    template<typename T, typename U> struct less_equal;
    template<typename T, typename U> struct greater_equal;
    template<typename T, typename U> struct equal_to;
    template<typename T, typename U> struct not_equal_to;
    template<typename T, typename U> struct logical_or;
    template<typename T, typename U> struct logical_and;
    template<typename T, typename U> struct bitwise_and;
    template<typename T, typename U> struct bitwise_or;
    template<typename T, typename U> struct bitwise_xor;
    template<typename T, typename U> struct comma;
    template<typename T, typename U> struct mem_ptr;

    template<typename T, typename U> struct assign;
    template<typename T, typename U> struct shift_left_assign;
    template<typename T, typename U> struct shift_right_assign;
    template<typename T, typename U> struct multiplies_assign;
    template<typename T, typename U> struct divides_assign;
    template<typename T, typename U> struct modulus_assign;
    template<typename T, typename U> struct plus_assign;
    template<typename T, typename U> struct minus_assign;
    template<typename T, typename U> struct bitwise_and_assign;
    template<typename T, typename U> struct bitwise_or_assign;
    template<typename T, typename U> struct bitwise_xor_assign;
    template<typename T, typename U> struct subscript;
    template<typename T, typename U> struct member;
    template<typename T, typename U, typename V> struct if_else_;

    template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_ARITY, typename A, void)>
    struct function;

    namespace functional
    {
        struct left;
        struct right;
        struct eval;
        struct deep_copy;

        template<typename Domain = default_domain>
        struct as_expr;

        template<typename Domain = default_domain>
        struct as_child;

        template<typename N = mpl::long_<0> >
        struct child;

        template<long N>
        struct child_c;

        struct as_env;

        template<typename Tag>
        struct has_env_var;

        template<typename Tag>
        struct env_var;

        template<typename Tag, typename Domain = deduce_domain>
        struct make_expr;

        template<typename Tag, typename Domain = deduce_domain>
        struct unpack_expr;

        typedef make_expr<tag::terminal>            make_terminal;
        typedef make_expr<tag::unary_plus>          make_unary_plus;
        typedef make_expr<tag::negate>              make_negate;
        typedef make_expr<tag::dereference>         make_dereference;
        typedef make_expr<tag::complement>          make_complement;
        typedef make_expr<tag::address_of>          make_address_of;
        typedef make_expr<tag::logical_not>         make_logical_not;
        typedef make_expr<tag::pre_inc>             make_pre_inc;
        typedef make_expr<tag::pre_dec>             make_pre_dec;
        typedef make_expr<tag::post_inc>            make_post_inc;
        typedef make_expr<tag::post_dec>            make_post_dec;
        typedef make_expr<tag::shift_left>          make_shift_left;
        typedef make_expr<tag::shift_right>         make_shift_right;
        typedef make_expr<tag::multiplies>          make_multiplies;
        typedef make_expr<tag::divides>             make_divides;
        typedef make_expr<tag::modulus>             make_modulus;
        typedef make_expr<tag::plus>                make_plus;
        typedef make_expr<tag::minus>               make_minus;
        typedef make_expr<tag::less>                make_less;
        typedef make_expr<tag::greater>             make_greater;
        typedef make_expr<tag::less_equal>          make_less_equal;
        typedef make_expr<tag::greater_equal>       make_greater_equal;
        typedef make_expr<tag::equal_to>            make_equal_to;
        typedef make_expr<tag::not_equal_to>        make_not_equal_to;
        typedef make_expr<tag::logical_or>          make_logical_or;
        typedef make_expr<tag::logical_and>         make_logical_and;
        typedef make_expr<tag::bitwise_and>         make_bitwise_and;
        typedef make_expr<tag::bitwise_or>          make_bitwise_or;
        typedef make_expr<tag::bitwise_xor>         make_bitwise_xor;
        typedef make_expr<tag::comma>               make_comma;
        typedef make_expr<tag::mem_ptr>             make_mem_ptr;
        typedef make_expr<tag::assign>              make_assign;
        typedef make_expr<tag::shift_left_assign>   make_shift_left_assign;
        typedef make_expr<tag::shift_right_assign>  make_shift_right_assign;
        typedef make_expr<tag::multiplies_assign>   make_multiplies_assign;
        typedef make_expr<tag::divides_assign>      make_divides_assign;
        typedef make_expr<tag::modulus_assign>      make_modulus_assign;
        typedef make_expr<tag::plus_assign>         make_plus_assign;
        typedef make_expr<tag::minus_assign>        make_minus_assign;
        typedef make_expr<tag::bitwise_and_assign>  make_bitwise_and_assign;
        typedef make_expr<tag::bitwise_or_assign>   make_bitwise_or_assign;
        typedef make_expr<tag::bitwise_xor_assign>  make_bitwise_xor_assign;
        typedef make_expr<tag::subscript>           make_subscript;
        typedef make_expr<tag::if_else_>            make_if_else;
        typedef make_expr<tag::function>            make_function;

        struct flatten;
        struct make_pair;
        struct first;
        struct second;
        struct at;
        struct pop_front;
        struct push_front;
        struct pop_back;
        struct push_back;
        struct reverse;
    }

    typedef functional::flatten     _flatten;
    typedef functional::make_pair   _make_pair;
    typedef functional::first       _first;
    typedef functional::second      _second;
    typedef functional::pop_front   _at;
    typedef functional::pop_front   _pop_front;
    typedef functional::push_front  _push_front;
    typedef functional::pop_back    _pop_back;
    typedef functional::push_back   _push_back;
    typedef functional::reverse     _reverse;
    typedef functional::eval        _eval;
    struct _deep_copy;

    typedef functional::make_expr<tag::terminal>           _make_terminal;
    typedef functional::make_expr<tag::unary_plus>         _make_unary_plus;
    typedef functional::make_expr<tag::negate>             _make_negate;
    typedef functional::make_expr<tag::dereference>        _make_dereference;
    typedef functional::make_expr<tag::complement>         _make_complement;
    typedef functional::make_expr<tag::address_of>         _make_address_of;
    typedef functional::make_expr<tag::logical_not>        _make_logical_not;
    typedef functional::make_expr<tag::pre_inc>            _make_pre_inc;
    typedef functional::make_expr<tag::pre_dec>            _make_pre_dec;
    typedef functional::make_expr<tag::post_inc>           _make_post_inc;
    typedef functional::make_expr<tag::post_dec>           _make_post_dec;
    typedef functional::make_expr<tag::shift_left>         _make_shift_left;
    typedef functional::make_expr<tag::shift_right>        _make_shift_right;
    typedef functional::make_expr<tag::multiplies>         _make_multiplies;
    typedef functional::make_expr<tag::divides>            _make_divides;
    typedef functional::make_expr<tag::modulus>            _make_modulus;
    typedef functional::make_expr<tag::plus>               _make_plus;
    typedef functional::make_expr<tag::minus>              _make_minus;
    typedef functional::make_expr<tag::less>               _make_less;
    typedef functional::make_expr<tag::greater>            _make_greater;
    typedef functional::make_expr<tag::less_equal>         _make_less_equal;
    typedef functional::make_expr<tag::greater_equal>      _make_greater_equal;
    typedef functional::make_expr<tag::equal_to>           _make_equal_to;
    typedef functional::make_expr<tag::not_equal_to>       _make_not_equal_to;
    typedef functional::make_expr<tag::logical_or>         _make_logical_or;
    typedef functional::make_expr<tag::logical_and>        _make_logical_and;
    typedef functional::make_expr<tag::bitwise_and>        _make_bitwise_and;
    typedef functional::make_expr<tag::bitwise_or>         _make_bitwise_or;
    typedef functional::make_expr<tag::bitwise_xor>        _make_bitwise_xor;
    typedef functional::make_expr<tag::comma>              _make_comma;
    typedef functional::make_expr<tag::mem_ptr>            _make_mem_ptr;
    typedef functional::make_expr<tag::assign>             _make_assign;
    typedef functional::make_expr<tag::shift_left_assign>  _make_shift_left_assign;
    typedef functional::make_expr<tag::shift_right_assign> _make_shift_right_assign;
    typedef functional::make_expr<tag::multiplies_assign>  _make_multiplies_assign;
    typedef functional::make_expr<tag::divides_assign>     _make_divides_assign;
    typedef functional::make_expr<tag::modulus_assign>     _make_modulus_assign;
    typedef functional::make_expr<tag::plus_assign>        _make_plus_assign;
    typedef functional::make_expr<tag::minus_assign>       _make_minus_assign;
    typedef functional::make_expr<tag::bitwise_and_assign> _make_bitwise_and_assign;
    typedef functional::make_expr<tag::bitwise_or_assign>  _make_bitwise_or_assign;
    typedef functional::make_expr<tag::bitwise_xor_assign> _make_bitwise_xor_assign;
    typedef functional::make_expr<tag::subscript>          _make_subscript;
    typedef functional::make_expr<tag::if_else_>           _make_if_else;
    typedef functional::make_expr<tag::function>           _make_function;

    template<typename T>
    struct is_callable;

    template<typename T>
    struct is_transform;

    template<typename T>
    struct is_aggregate;

    #define BOOST_PROTO_UNEXPR() typedef int proto_is_expr_;
    #define BOOST_PROTO_CALLABLE() typedef void proto_is_callable_;
    #define BOOST_PROTO_AGGREGATE() typedef void proto_is_aggregate_;
    #define BOOST_PROTO_USE_BASIC_EXPR() typedef void proto_use_basic_expr_;

    struct callable
    {
        BOOST_PROTO_CALLABLE()
    };

    namespace envns_
    {
        struct key_not_found;

        struct empty_env;

        typedef int empty_state;

        template<typename Tag, typename Value, typename Base = empty_env>
        struct env;

        struct data_type;

        struct transforms_type;
    }

    using envns_::key_not_found;
    using envns_::empty_env;
    using envns_::empty_state;
    using envns_::env;
    using envns_::data_type;
    using envns_::transforms_type;

    struct external_transform;

    template<typename PrimitiveTransform = void, typename X = void>
    struct transform;

    template<typename Grammar, typename Fun = Grammar>
    struct when;

    template<typename Fun>
    struct otherwise;

    template<typename Fun>
    struct call;

    template<typename Fun>
    struct make;

    template<typename PrimitiveTransform>
    struct protect;

    template<typename T>
    struct noinvoke;

    template<typename Fun>
    struct lazy;

    template<typename Sequence, typename State, typename Fun>
    struct fold;

    template<typename Sequence, typename State, typename Fun>
    struct reverse_fold;

    // Q: can we replace fold_tree with fold<flatten(_), state, fun> ?
    // A: once segmented Fusion works well.
    template<typename Sequence, typename State, typename Fun>
    struct fold_tree;

    template<typename Sequence, typename State, typename Fun>
    struct reverse_fold_tree;

    template<typename Grammar, typename Domain = deduce_domain>
    struct pass_through;

    template<typename Grammar = detail::_default>
    struct _default;

    struct _expr;
    struct _state;
    struct _data;

    struct _value;

    struct _void;

    template<typename T, T I>
    struct integral_c;

    template<char I>
    struct char_;

    template<int I>
    struct int_;

    template<long I>
    struct long_;

    template<std::size_t I>
    struct size_t;

    template<int I>
    struct _child_c;

    typedef _child_c<0> _child0;
    typedef _child_c<1> _child1;
    typedef _child0     _child;
    typedef _child0     _left;
    typedef _child1     _right;

    // _child2, _child3, _child4, ...
    #define M0(Z, N, DATA) typedef _child_c<N> BOOST_PP_CAT(_child, N);
    BOOST_PP_REPEAT_FROM_TO(
        2
      , BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY)
      , M0
      , ~
    )
    #undef M0

    struct _byref;
    struct _byval;

    template<typename Tag>
    struct _env_var;

    struct _env;

    template<typename T>
    struct is_extension;

    namespace exops = exprns_;

}} // namespace boost::proto

#endif


code:
/* boost random/detail/enable_warnings.hpp header file
 *
 * Copyright Steven Watanabe 2009
 * 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$
 *
 */

// No #include guard.  This header is intended to be included multiple times.

#ifdef BOOST_MSVC
#pragma warning(pop)
#endif

#if defined(BOOST_GCC) && BOOST_GCC >= 40600
#pragma GCC diagnostic pop
#endif

license: mit


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 Horners rule
#ifndef BOOST_MATH_TOOLS_POLY_RAT_3_HPP
#define BOOST_MATH_TOOLS_POLY_RAT_3_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)
{
   if(x <= 1)
     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
   else
   {
      V z = 1 / x;
      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
   }
}

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)
{
   if(x <= 1)
     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
   else
   {
      V z = 1 / x;
      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
   }
}

}}}} // namespaces

#endif // include guard


code:
/*
 [auto_generated]
 boost/numeric/odeint/util/n_ary_helper.hpp

 Macros to generate scale_sumN and for_eachN functors.

 Copyright 2013 Karsten Ahnert
 Copyright 2013 Mario Mulansky
 Copyright 2013 Pascal Germroth

 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_UTIL_N_ARY_HELPER_HPP_INCLUDED
#define BOOST_NUMERIC_ODEINT_UTIL_N_ARY_HELPER_HPP_INCLUDED

#include <boost/preprocessor/repetition.hpp>

// like BOOST_PP_ENUM_SHIFTED but with a comma in front like _TRAILING
#define BOOST_ODEINT_ENUM_TRAILING_SHIFTED_PARAMS(count, param) \
    BOOST_PP_COMMA_IF(BOOST_PP_DEC(count)) \
    BOOST_PP_ENUM_SHIFTED_PARAMS(count, param)

#define BOOST_ODEINT_ENUM_TRAILING_SHIFTED_BINARY_PARAMS(count, p1, p2) \
    BOOST_PP_COMMA_IF(BOOST_PP_DEC(count)) \
    BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS(count, p1, p2)

// like BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS(n, p1, p2) but p2 is shifted left.
// generate "p1 ## 0 = p2, p1 ## 1 = p3 ## 0, p1 ## 2 = p3 ## 1"
#define BOOST_ODEINT_ENUM_LSHIFTED_BINARY_PARAMS(count, p1, p2, p3) \
    BOOST_PP_ENUM(count, BOOST_ODEINT_ENUM_LSHIFTED_BINARY_PARAMS_, (p1, p2, p3))
#define BOOST_ODEINT_ENUM_LSHIFTED_BINARY_PARAMS_(z, n, data) \
    BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, data), n) \
    BOOST_PP_IF(n, \
        BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 2, data), BOOST_PP_DEC(n)), \
        BOOST_PP_TUPLE_ELEM(3, 1, data))

// like BOOST_PP_ENUM_BINARY_PARAMS(n, p1, p2) but with statements.
// "p1 ## 0 p2 ## 0 ; p1 ## 1 p2 ## 1 ; ..."
#define BOOST_ODEINT_ENUM_BINARY_STATEMENTS(count, p1, p2) \
    BOOST_PP_REPEAT(count, BOOST_ODEINT_ENUM_BINARY_STATEMENTS_, (p1, p2))
#define BOOST_ODEINT_ENUM_BINARY_STATEMENTS_(z, n, data) \
    BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, data), n) \
    BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, data), n) ;

// like BOOST_PP_ENUM_BINARY_PARAMS(n, p1, p2) but p2 is in parens.
// "p1 ## 0 (p2 ## 0) , p1 ## 1 (p2 ## 1) , ..."
#define BOOST_ODEINT_ENUM_UNARY_CALLS(count, p1, p2) \
    BOOST_PP_ENUM(count, BOOST_ODEINT_ENUM_UNARY_CALLS_, (p1, p2))
#define BOOST_ODEINT_ENUM_SHIFTED_UNARY_CALLS(count, p1, p2) \
    BOOST_PP_ENUM_SHIFTED(count, BOOST_ODEINT_ENUM_UNARY_CALLS_, (p1, p2))
#define BOOST_ODEINT_ENUM_TRAILING_SHIFTED_UNARY_CALLS(count, p1, p2) \
    BOOST_PP_COMMA_IF(BOOST_PP_DEC(count)) \
    BOOST_PP_ENUM_SHIFTED(count, BOOST_ODEINT_ENUM_UNARY_CALLS_, (p1, p2))
#define BOOST_ODEINT_ENUM_UNARY_CALLS_(z, n, data) \
      BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, data), n) \
    ( BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, data), n) )

// maximum arity + 1 for scale_sum and for_each
#define BOOST_ODEINT_N_ARY_MAX 16

// generate scale_sum1 to scale_sumN, operator body generated by macro(N)
#define BOOST_ODEINT_GEN_SCALE_SUM(macro) \
    BOOST_PP_REPEAT_FROM_TO(1, BOOST_ODEINT_N_ARY_MAX, BOOST_ODEINT_GEN_SCALE_SUM_, macro)
#define BOOST_ODEINT_GEN_SCALE_SUM_(z, n, macro) \
    template< BOOST_ODEINT_ENUM_LSHIFTED_BINARY_PARAMS(n, class Fac, = double, = Fac) > \
    struct BOOST_PP_CAT(scale_sum, n) \
    { \
        BOOST_ODEINT_ENUM_BINARY_STATEMENTS(n, const Fac, m_alpha) \
        \
        BOOST_PP_CAT(scale_sum, n) \
        ( BOOST_PP_ENUM_BINARY_PARAMS(n, Fac, alpha) ) \
        : BOOST_ODEINT_ENUM_UNARY_CALLS(n, m_alpha, alpha) {} \
        \
        template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), class T) > \
        void operator()( T0 &t0 \
            BOOST_ODEINT_ENUM_TRAILING_SHIFTED_BINARY_PARAMS(BOOST_PP_INC(n), const T, &t) \
        ) const \
        { macro(n) } \
        typedef void result_type; \
    };

// generate for_each1 to for_eachN, body generated by macro(N)
#define BOOST_ODEINT_GEN_FOR_EACH(macro) \
    BOOST_PP_REPEAT_FROM_TO(1, BOOST_ODEINT_N_ARY_MAX, BOOST_ODEINT_GEN_FOR_EACH_, macro)
#define BOOST_ODEINT_GEN_FOR_EACH_(z, n, macro) \
    template< BOOST_PP_ENUM_PARAMS(n, class S) , class Op > \
    static void for_each##n ( BOOST_PP_ENUM_BINARY_PARAMS(n, S, &s) , Op op ) \
    { macro(n) }

#endif


code:
#ifndef TRACE_FILE_HPP_
#define TRACE_FILE_HPP_

#include "pimpl_h.hpp"

class QString;

class TraceFile final
{
public:
  explicit TraceFile (QString const& TraceFile_file_path);
  ~TraceFile ();

  // copying not allowed
  TraceFile (TraceFile const&) = delete;
  TraceFile& operator = (TraceFile const&) = delete;

private:
  class impl;
  pimpl<impl> m_;
};

#endif


code:
/*
 [auto_generated]
  boost/numeric/odeint/iterator/detail/adaptive_iterator_impl.hpp

  [begin_description]
  tba.
  [end_description]

  Copyright 2009-2012 Karsten Ahnert
  Copyright 2009-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_ITERATOR_DETAIL_ADAPTIVE_ITERATOR_IMPL_HPP_DEFINED
#define BOOST_NUMERIC_ODEINT_ITERATOR_DETAIL_ADAPTIVE_ITERATOR_IMPL_HPP_DEFINED

#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/throw_exception.hpp>

#include <boost/numeric/odeint/util/unit_helper.hpp>
#include <boost/numeric/odeint/util/copy.hpp>
#include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
#include <boost/numeric/odeint/iterator/detail/ode_iterator_base.hpp>

namespace boost {
namespace numeric {
namespace odeint {

    template< class Iterator , class Stepper , class System , class State , typename Tag , typename StepperTag >
    class adaptive_iterator_impl;

    /*
     * Specilization for controlled steppers
     */
    /**
     * \brief ODE Iterator with adaptive step size control. The value type of this iterator is the state type of the stepper.
     *
     * Implements an ODE iterator with adaptive step size control. Uses controlled steppers. adaptive_iterator is a model
     * of single-pass iterator.
     *
     * The value type of this iterator is the state type of the stepper. Hence one can only access the state and not the current time.
     *
     * \tparam Stepper The stepper type which should be used during the iteration.
     * \tparam System The type of the system function (ODE) which should be solved.
     */
    template< class Iterator , class Stepper , class System , class State , typename Tag >
    class adaptive_iterator_impl< Iterator , Stepper , System , State , Tag , controlled_stepper_tag >
        : public detail::ode_iterator_base< Iterator , Stepper , System , State , Tag >
    {
    private:

        typedef Stepper stepper_type;
        typedef System system_type;
        typedef typename boost::numeric::odeint::unwrap_reference< stepper_type >::type unwrapped_stepper_type;
        typedef State state_type;
        typedef typename traits::time_type< stepper_type >::type time_type;
        typedef typename traits::value_type< stepper_type >::type ode_value_type;
        #ifndef DOXYGEN_SKIP
        typedef detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > base_type;
        #endif

    public:

        /**
         * \brief Constructs an adaptive_iterator. This constructor should be used to construct the begin iterator.
         *
         * \param stepper The stepper to use during the iteration.
         * \param sys The system function (ODE) to solve.
         * \param s The initial state. adaptive_iterator stores a reference of s and changes its value during the iteration.
         * \param t The initial time.
         * \param t_end The end time, at which the iteration should stop.
         * \param dt The initial time step.
         */
        adaptive_iterator_impl( stepper_type stepper , system_type sys , state_type &s , time_type t , time_type t_end , time_type dt )
            : base_type( stepper , sys , t , dt ) , m_t_end( t_end ) , m_state( &s )
        {
            if( detail::less_with_sign( this->m_t_end , this->m_t , this->m_dt ) )
                this->m_at_end = true;
        }

        /**
         * \brief Constructs an adaptive_iterator. This constructor should be used to construct the end iterator.
         *
         * \param stepper The stepper to use during the iteration.
         * \param sys The system function (ODE) to solve.
         * \param s The initial state. adaptive_iterator store a reference of s and changes its value during the iteration.
         */
        adaptive_iterator_impl( stepper_type stepper , system_type sys , state_type &s )
            : base_type( stepper , sys ) , m_state( &s ) { }

    protected:

        friend class boost::iterator_core_access;

        void increment()
        {
            if( detail::less_with_sign( this->m_t , this->m_t_end , this->m_dt) )
            {
                if( detail::less_with_sign( this->m_t_end ,
                                            static_cast<time_type>(this->m_t + this->m_dt) ,
                                            this->m_dt ) )
                {
                    this->m_dt = this->m_t_end - this->m_t;
                }
                unwrapped_stepper_type &stepper = this->m_stepper;
                const size_t max_attempts = 1000;
                size_t trials = 0;
                controlled_step_result res = success;
                do
                {
                    res = stepper.try_step( this->m_system , *( this->m_state ) , this->m_t , this->m_dt );
                    ++trials;
                }
                while( ( res == fail ) && ( trials < max_attempts ) );
                if( trials == max_attempts )
                {
                    BOOST_THROW_EXCEPTION( std::overflow_error( "Adaptive iterator : Maximal number of iterations reached. A step size could not be found." ));
                }
            } else {
                this->m_at_end = true;
            }
        }
    public:
        const state_type& get_state() const
        {
            return *this->m_state;
        }

    private:
        time_type m_t_end;
        state_type* m_state;
    };

    /*
     * Specilization for dense outputer steppers
     */
    /**
     * \brief ODE Iterator with adaptive step size control. The value type of this iterator is the state type of the stepper.
     *
     * Implements an ODE iterator with adaptive step size control. Uses dense-output steppers. adaptive_iterator is a model
     * of single-pass iterator.
     *
     * The value type of this iterator is the state type of the stepper. Hence one can only access the state and not the current time.
     *
     * \tparam Stepper The stepper type which should be used during the iteration.
     * \tparam System The type of the system function (ODE) which should be solved.
     */
    template< class Iterator , class Stepper , class System , class State , typename Tag >
    class adaptive_iterator_impl< Iterator , Stepper , System , State , Tag , dense_output_stepper_tag >
        : public detail::ode_iterator_base< Iterator , Stepper , System , State , Tag >
    {
    private:

        typedef Stepper stepper_type;
        typedef System system_type;
        typedef typename boost::numeric::odeint::unwrap_reference< stepper_type >::type unwrapped_stepper_type;
        typedef State state_type;
        typedef typename traits::time_type< stepper_type >::type time_type;
        typedef typename traits::value_type< stepper_type >::type ode_value_type;
        #ifndef DOXYGEN_SKIP
        typedef detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > base_type;
        #endif

   public:

        /**
         * \brief Constructs an adaptive_iterator. This constructor should be used to construct the begin iterator.
         *
         * \param stepper The stepper to use during the iteration.
         * \param sys The system function (ODE) to solve.
         * \param s The initial state.
         * \param t The initial time.
         * \param t_end The end time, at which the iteration should stop.
         * \param dt The initial time step.
         */
        adaptive_iterator_impl( stepper_type stepper , system_type sys , state_type &s , time_type t , time_type t_end , time_type dt )
            : base_type( stepper , sys , t , dt ) , m_t_end( t_end )
        {
            if( detail::less_eq_with_sign( this->m_t , this->m_t_end , this->m_dt ) )
            {
                unwrapped_stepper_type &st = this->m_stepper;
                st.initialize( s , this->m_t , this->m_dt );
            } else {
                this->m_at_end = true;
            }
        }

        /**
         * \brief Constructs an adaptive_iterator. This constructor should be used to construct the end iterator.
         *
         * \param stepper The stepper to use during the iteration.
         * \param sys The system function (ODE) to solve.
         * \param s The initial state.
         */
        adaptive_iterator_impl( stepper_type stepper , system_type sys , state_type& /* s */ )
            : base_type( stepper , sys ) { }

    protected:

        friend class boost::iterator_core_access;

        void increment()
        {
            unwrapped_stepper_type &stepper = this->m_stepper;
            if( detail::less_with_sign( this->m_t ,
                                        this->m_t_end ,
                                        stepper.current_time_step() ) )
            {
                if( detail::less_with_sign( this->m_t_end ,
                                            static_cast<time_type>(this->m_t + stepper.current_time_step()) ,
                                            stepper.current_time_step() ) )
                {
                    // make stpper to end exactly at t_end
                    stepper.initialize( stepper.current_state() , stepper.current_time() ,
                                        static_cast<time_type>(this->m_t_end-this->m_t) );
                }
                stepper.do_step( this->m_system );
                this->m_t = stepper.current_time();
            } else { // we have reached t_end
                this->m_at_end = true;
            }
        }

    public:
        const state_type& get_state() const
        {
            const unwrapped_stepper_type &stepper = this->m_stepper;
            return stepper.current_state();
        }

    private:
        time_type m_t_end;
    };

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

#endif // BOOST_NUMERIC_ODEINT_ITERATOR_DETAIL_ADAPTIVE_ITERATOR_IMPL_HPP_DEFINED


code:
// Copyright David Abrahams 2002.
// 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 DESTROY_DWA2002221_HPP
# define DESTROY_DWA2002221_HPP

# include <boost/type_traits/is_array.hpp>
# include <boost/detail/workaround.hpp>
namespace boost { namespace python { namespace detail {

template <bool array> struct value_destroyer;

template <>
struct value_destroyer<false>
{
    template <class T>
    static void execute(T const volatile* p)
    {
        p->~T();
    }
};

template <>
struct value_destroyer<true>
{
    template <class A, class T>
    static void execute(A*, T const volatile* const first)
    {
        for (T const volatile* p = first; p != first + sizeof(A)/sizeof(T); ++p)
        {
            value_destroyer<
                boost::is_array<T>::value
            >::execute(p);
        }
    }

    template <class T>
    static void execute(T const volatile* p)
    {
        execute(p, *p);
    }
};

template <class T>
inline void destroy_referent_impl(void* p, T& (*)())
{
    // note: cv-qualification needed for MSVC6
    // must come *before* T for metrowerks
    value_destroyer<
         (boost::is_array<T>::value)
    >::execute((const volatile T*)p);
}

template <class T>
inline void destroy_referent(void* p, T(*)() = 0)
{
    destroy_referent_impl(p, (T(*)())0);
}

}}} // namespace boost::python::detail

#endif // DESTROY_DWA2002221_HPP


code:
// NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION

// Copyright Aleksey Gurtovoy 2000-2004
//
// 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/mpl for documentation.

// $Id$
// $Date$
// $Revision$

#if defined(BOOST_PP_IS_ITERATING)

#include <boost/preprocessor/enum_params.hpp>
#include <boost/preprocessor/enum_shifted_params.hpp>
#include <boost/preprocessor/dec.hpp>
#include <boost/preprocessor/cat.hpp>

#define i BOOST_PP_FRAME_ITERATION(1)

#if i == 1

template<
      typename T
    , BOOST_PP_ENUM_PARAMS(i, T C)
    >
struct list1_c
    : l_item<
          long_<1>
        , integral_c<T,C0>
        , l_end
        >
{
    typedef list1_c type;
    typedef T value_type;
};

#else

#   define MPL_AUX_LIST_C_TAIL(list, i, C) \
    BOOST_PP_CAT(BOOST_PP_CAT(list,BOOST_PP_DEC(i)),_c)<T, \
      BOOST_PP_ENUM_SHIFTED_PARAMS(i, C) \
    > \
    /**/

template<
      typename T
    , BOOST_PP_ENUM_PARAMS(i, T C)
    >
struct BOOST_PP_CAT(BOOST_PP_CAT(list,i),_c)
    : l_item<
          long_<i>
        , integral_c<T,C0>
        , MPL_AUX_LIST_C_TAIL(list,i,C)
        >
{
    typedef BOOST_PP_CAT(BOOST_PP_CAT(list,i),_c) type;
    typedef T value_type;
};

#   undef MPL_AUX_LIST_C_TAIL

#endif // i == 1

#undef i

#endif // BOOST_PP_IS_ITERATING


code:
/* boost random/uniform_real.hpp header file
 *
 * Copyright Jens Maurer 2000-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 for most recent version including documentation.
 *
 * $Id$
 *
 * Revision history
 *  2001-04-08  added min<max assertion (N. Becker)
 *  2001-02-18  moved to individual header files
 */

#ifndef BOOST_RANDOM_UNIFORM_REAL_HPP
#define BOOST_RANDOM_UNIFORM_REAL_HPP

#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/random/uniform_real_distribution.hpp>

namespace boost {

/**
 * The distribution function uniform_real models a random distribution.
 * On each invocation, it returns a random floating-point value uniformly
 * distributed in the range [min..max).
 *
 * This class is deprecated.  Please use @c uniform_real_distribution in
 * new code.
 */
template<class RealType = double>
class uniform_real : public random::uniform_real_distribution<RealType>
{
    typedef random::uniform_real_distribution<RealType> base_type;
public:

    class param_type : public base_type::param_type
    {
    public:
        typedef uniform_real distribution_type;
        /**
         * Constructs the parameters of a uniform_real distribution.
         *
         * Requires: min <= max
         */
        explicit param_type(RealType min_arg = RealType(0.0),
                            RealType max_arg = RealType(1.0))
          : base_type::param_type(min_arg, max_arg)
        {}
    };

    /**
     * Constructs a uniform_real object. @c min and @c max are the
     * parameters of the distribution.
     *
     * Requires: min <= max
     */
    explicit uniform_real(RealType min_arg = RealType(0.0),
                          RealType max_arg = RealType(1.0))
      : base_type(min_arg, max_arg)
    {
        BOOST_ASSERT(min_arg < max_arg);
    }

    /** Constructs a uniform_real distribution from its parameters. */
    explicit uniform_real(const param_type& parm)
      : base_type(parm)
    {}

    /** Returns the parameters of the distribution */
    param_type param() const { return param_type(this->a(), this->b()); }
    /** Sets the parameters of the distribution. */
    void param(const param_type& parm) { this->base_type::param(parm); }
};

} // namespace boost

#endif // BOOST_RANDOM_UNIFORM_REAL_HPP


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_SI_ACTIVITY_HPP
#define BOOST_UNITS_SI_ACTIVITY_HPP

#include <boost/units/systems/si/base.hpp>
#include <boost/units/physical_dimensions/activity.hpp>

namespace boost {

namespace units {

namespace si {

typedef unit<activity_dimension,si::system>  activity;

BOOST_UNITS_STATIC_CONSTANT(becquerel,activity);
BOOST_UNITS_STATIC_CONSTANT(becquerels,activity);

} // namespace si

} // namespace units

} // namespace boost

#endif // BOOST_UNITS_SI_ACTIVITY_HPP


code:
{
   <QApplication>
   Memcheck:Cond
   ...
   fun:_ZN19QApplicationPrivate9constructEv
   fun:main
}
{
   <gtk::g_cclosure_marshal>
   Memcheck:Cond
   ...
   fun:g_cclosure_marshal_VOID__OBJECTv
}
{
   <QScrollBar::paintEvent>
   Memcheck:Cond
   ...
   fun:_ZN10QScrollBar10paintEventEP11QPaintEvent
}
{
   <QtWidgets>
   Memcheck:Cond
   ...
   fun:gtk_adjustment_configure
   obj:/usr/lib/*/libQt5Widgets*
   obj:/usr/lib/*/libQt5Widgets*
}
{
   <QCoreApplication::exec>
   Memcheck:Cond
   ...
   fun:_ZN16QCoreApplication4execEv
   fun:main
}
{
   <ld>
   Memcheck:Leak
   ...
   obj:/lib/*/ld-*
   ...
}
{
   <gtk-theme-engine>
   Memcheck:Leak
   ...
   fun:gtk_theme_engine_get
}
{
   <libgio>
   Memcheck:Leak
   ...
   obj:/usr/lib/*/libgio-*
   ...
}
{
   <gtk-x11>
   Memcheck:Leak
   ...
   obj:/usr/lib/*/libgtk-x11-*
   ...
}
{
   <gtk-x11>
   Memcheck:Cond
   ...
   obj:/usr/lib/*/libgtk-x11-*
   ...
}
{
   <QStyleFactory::create>
   Memcheck:Leak
   ...
   fun:_ZN13QStyleFactory6createERK7QString
   fun:_ZN12QApplication5styleEv
   ...
}
{
   <raico_blur_create>
   Memcheck:Leak
   ...
   fun:raico_blur_create
   ...
}
{
   <pango-leaks>
   Memcheck:Leak
   ...
   fun:pango*
   ...
}
{
   <dbus>
   Memcheck:Leak
   ...
   fun:*dbus*
   ...
}
{
   <QtWidgets-leak>
   Memcheck:Leak
   ...
   fun:*QPaintEvent
   fun:_ZN7QWidget5eventEP6QEvent
}
{
   <libglib>
   Memcheck:Leak
   ...
   obj:/lib/*/libglib-*
}
{
   <libpango>
   Memcheck:Leak
   ...
   obj:/usr/lib/*/libpango*
   ...
}
{
   <gdk-x11>
   Memcheck:Leak
   ...
   obj:/usr/lib/*/libgdk-x11*
   ...
}
{
   <libpixbufloader-svg>
   Memcheck:Leak
   ...
   obj:/usr/lib/*/gdk-pixbuf*/*/loaders/libpixbufloader-svg.so
}
{
   <libdconfsettings>
   Memcheck:Leak
   ...
   obj:/usr/lib/*/gio/modules/libdconfsettings.so
   ...
}
{
   <libibus>
   Memcheck:Leak
   obj:/usr/lib/*/libibus-*
   ...
}
{
   <libpulse>
   Memcheck:Leak
   ...
   obj:/usr/lib/*/libpulse*
   ...
}
{
   <Qt::start_thread>
   Memcheck:Leak
   ...
   fun:start_thread
   fun:clone
}
{
   <QCoreApplication>
   Memcheck:Leak
   ...
   fun:_ZN16QCoreApplicationC1ER23QCoreApplicationPrivate
}
{
   <QFontMetrics>
   Memcheck:Leak
   ...
   fun:_ZNK13QFontMetricsF7leadingEv
   obj:/usr/lib/*/libQt5Gui*
}
{
   <QAudioDeviceInfo::defaultInputDevice>
   Memcheck:Leak
   ...
   fun:_ZN16QAudioDeviceInfo18defaultInputDeviceEv
   ...
}
{
   <libfontconfig>
   Memcheck:Leak
   ...
   obj:/usr/lib/*/libfontconfig*.so.1.8.0
   ...
}
{
   <QFontDatabase::findFont>
   Memcheck:Leak
   ...
   fun:_ZN13QFontDatabase8findFontEiPK12QFontPrivateRK8QFontDefb
   ...
}
{
   <QSerialPort::availablePorts>
   Memcheck:Leak
   ...
   fun:_ZN15QSerialPortInfo14availablePortsEv
   ...
}
{
   <main_context_dispatch>
   Memcheck:Leak
   ...
   fun:g_main_context_dispatch
   ...
}
{
   <hb_shape_full>
   Memcheck:Leak
   ...
   fun:hb_shape_full
   ...
}
{
   <QPlatformWindow>
   Memcheck:Leak
   ...
   fun:_ZN15QPlatformWindowC1EP7QWindow
   ...
}
{
   <QSurfaceFormat>
   Memcheck:Leak
   ...
   fun:_ZN14QSurfaceFormatC1Ev
   ...
}
{
   <QWindow::create>
   Memcheck:Leak
   ...
   fun:_ZN7QWindow6createEv
   ...
}
{
   <QWidgetPrivate::syncBackingStore>
   Memcheck:Leak
   ...
   fun:_ZN14QWidgetPrivate16syncBackingStoreEv
}
{
   <QWindow::setVisible>
   Memcheck:Leak
   ...
   fun:_ZN7QWindow10setVisibleEb
   ...
}
{
   <QMimData>
   Memcheck:Leak
   ...
   fun:_ZN9QMimeDataC1Ev
   ...
}
{
   <QWindowPrivate::setCursor>
   Memcheck:Leak
   ...
   fun:_ZN14QWindowPrivate9setCursorEPK7QCursor
   ...
}
{
   <libfreetype>
   Memcheck:Leak
   ...
   obj:/usr/lib/*/libfreetype*
   ...
}
{
   <libdbus>
   Memcheck:Leak
   ...
   obj:*/lib/*/libdbus*
   ...
}
{
   <libcairo-leak>
   Memcheck:Leak
   ...
   obj:/usr/lib/*/libcairo*
   ...
}
{
   <cairo>
   Memcheck:Cond
   ...
   obj:/usr/lib/*/libcairo*
   ...
}
{
   <QFactoryLoader::instance>
   Memcheck:Leak
   ...
   fun:_ZNK14QFactoryLoader8instanceEi
   ...
}
{
   <QThreadStorageData::get>
   Memcheck:Leak
   ...
   fun:_ZNK18QThreadStorageData3getEv
   ...
}
{
   <register_types>
   Memcheck:Leak
   ...
   fun:_Z14register_typesv
   ...
}
{
   <libibus>
   Memcheck:Leak
   ...
   obj:/usr/lib/*/libibus*
   ...
}
{
   <QPlatformintegrationFactory::create>
   Memcheck:Leak
   ...
   fun:_ZN27QPlatformIntegrationFactory6createERK7QStringRK11QStringListRiPPcS2_
   ...
}
{
   <QPlatformInputContextFactory::create>
   Memcheck:Leak
   ...
   fun:_ZN28QPlatformInputContextFactory6createEv*
   ...
}
{
   <QProcess::start>
   Memcheck:Leak
   ...
   fun:_ZN8QProcess5startERK7QStringRK11QStringList6QFlagsIN9QIODevice12OpenModeFlagEE
   ...
}
{
   <libicuuc>
   Memcheck:Leak
   ...
   obj:/usr/lib/*/libicuuc*
   ...
}
{
   <X11>
   Memcheck:Leak
   ...
   obj:/usr/lib/*/libX11*
   ...
}
{
   <libxml2>
   Memcheck:Leak
   ...
   obj:/usr/lib/*/libxml2*
   ...
}
{
   <librsvg>
   Memcheck:Cond
   obj:/usr/lib/*/librsvg*
   ...
}
{
   <libxcb>
   Memcheck:Leak
   ...
   obj:/usr/lib/*/libxcb*
   ...
}
{
   <QFont::fromString>
   Memcheck:Leak
   ...
   fun:_ZN5QFont10fromStringERK7QString
   ...
}
{
   <QFontDatabase::load>
   Memcheck:Leak
   ...
   fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei
   ...
}


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_ARITHMETIC_DETAIL_DIV_BASE_HPP
# define BOOST_PREPROCESSOR_ARITHMETIC_DETAIL_DIV_BASE_HPP
#
# include <boost/preprocessor/arithmetic/inc.hpp>
# include <boost/preprocessor/arithmetic/sub.hpp>
# include <boost/preprocessor/comparison/less_equal.hpp>
# include <boost/preprocessor/config/config.hpp>
# include <boost/preprocessor/control/while.hpp>
# include <boost/preprocessor/tuple/elem.hpp>
# include <boost/preprocessor/tuple/rem.hpp>
#
# /* BOOST_PP_DIV_BASE */
#
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
#    define BOOST_PP_DIV_BASE(x, y) BOOST_PP_WHILE(BOOST_PP_DIV_BASE_P, BOOST_PP_DIV_BASE_O, (0, x, y))
# else
#    define BOOST_PP_DIV_BASE(x, y) BOOST_PP_DIV_BASE_I(x, y)
#    define BOOST_PP_DIV_BASE_I(x, y) BOOST_PP_WHILE(BOOST_PP_DIV_BASE_P, BOOST_PP_DIV_BASE_O, (0, x, y))
# endif
#
# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
#    define BOOST_PP_DIV_BASE_P(d, rxy) BOOST_PP_DIV_BASE_P_IM(d, BOOST_PP_TUPLE_REM_3 rxy)
#    define BOOST_PP_DIV_BASE_P_IM(d, im) BOOST_PP_DIV_BASE_P_I(d, im)
# else
#    define BOOST_PP_DIV_BASE_P(d, rxy) BOOST_PP_DIV_BASE_P_I(d, BOOST_PP_TUPLE_ELEM(3, 0, rxy), BOOST_PP_TUPLE_ELEM(3, 1, rxy), BOOST_PP_TUPLE_ELEM(3, 2, rxy))
# endif
#
# define BOOST_PP_DIV_BASE_P_I(d, r, x, y) BOOST_PP_LESS_EQUAL_D(d, y, x)
#
# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
#    define BOOST_PP_DIV_BASE_O(d, rxy) BOOST_PP_DIV_BASE_O_IM(d, BOOST_PP_TUPLE_REM_3 rxy)
#    define BOOST_PP_DIV_BASE_O_IM(d, im) BOOST_PP_DIV_BASE_O_I(d, im)
# else
#    define BOOST_PP_DIV_BASE_O(d, rxy) BOOST_PP_DIV_BASE_O_I(d, BOOST_PP_TUPLE_ELEM(3, 0, rxy), BOOST_PP_TUPLE_ELEM(3, 1, rxy), BOOST_PP_TUPLE_ELEM(3, 2, rxy))
# endif
#
# define BOOST_PP_DIV_BASE_O_I(d, r, x, y) (BOOST_PP_INC(r), BOOST_PP_SUB_D(d, x, y), y)
#
# /* BOOST_PP_DIV_BASE_D */
#
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
#    define BOOST_PP_DIV_BASE_D(d, x, y) BOOST_PP_WHILE_ ## d(BOOST_PP_DIV_BASE_P, BOOST_PP_DIV_BASE_O, (0, x, y))
# else
#    define BOOST_PP_DIV_BASE_D(d, x, y) BOOST_PP_DIV_BASE_D_I(d, x, y)
#    define BOOST_PP_DIV_BASE_D_I(d, x, y) BOOST_PP_WHILE_ ## d(BOOST_PP_DIV_BASE_P, BOOST_PP_DIV_BASE_O, (0, x, y))
# endif
#
# endif


code:
// Copyright 2005-2009 Daniel James.
// 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)

//  Based on Peter Dimov's proposal
//  http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
//  issue 6.18.

#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP)
#define BOOST_FUNCTIONAL_HASH_FWD_HPP

#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif

#include <cstddef>
#include <boost/detail/workaround.hpp>

namespace boost
{
    template <class T> struct hash;

    template <class T> void hash_combine(std::size_t& seed, T const& v);

    template <class It> std::size_t hash_range(It, It);
    template <class It> void hash_range(std::size_t&, It, It);

#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
    template <class T> inline std::size_t hash_range(T*, T*);
    template <class T> inline void hash_range(std::size_t&, T*, T*);
#endif
}

#endif


code:
subroutine genwspr_fsk8(msg,msgsent,itone)

! Encode a WSPR-LF 8-FSK message, producing array itone().

  use crc
  include 'wspr_fsk8_params.f90'

  character*22 msg,msgsent
  character*60 cbits
  integer*1,target :: idat(9)
  integer*1 msgbits(KK),codeword(3*ND)
  integer itone(NN)
  integer icos7(0:6)
  data icos7/2,5,6,0,4,1,3/                  !Costas 7x7 tone pattern

  idat=0
  call wqencode(msg,ntype0,idat)             !Source encoding
  id7=idat(7)
  if(id7.lt.0) id7=id7+256
  id7=id7/64
  icrc=crc10(c_loc(idat),9)                  !Compute the 10-bit CRC
  idat(8)=icrc/256                           !Insert CRC into idat(8:9)
  idat(9)=iand(icrc,255)
  call wqdecode(idat,msgsent,itype)

  write(cbits,1004) idat(1:6),id7,icrc
1004 format(6b8.8,b2.2,b10.10)
  read(cbits,1006) msgbits
1006 format(60i1)

!  call chkcrc10(msgbits,nbadcrc)
!  print*,msgsent,itype,crc10_check(c_loc(idat),9),nbadcrc

  call encode300(msgbits,codeword)      !Encode the test message

! Message structure: S7 D100 S7
  itone(1:7)=icos7
  itone(NN-6:NN)=icos7
  do j=1,ND
     i=3*j -2
     itone(j+7)=codeword(i)*4 + codeword(i+1)*2 + codeword(i+2)
  enddo

  return
end subroutine genwspr_fsk8


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

    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_FUSION_CONTAINER_MAP_DETAIL_BEGIN_IMPL_HPP
#define BOOST_FUSION_CONTAINER_MAP_DETAIL_BEGIN_IMPL_HPP

#include <boost/fusion/support/config.hpp>
#include <boost/fusion/iterator/basic_iterator.hpp>

namespace boost { namespace fusion { namespace extension
{
    template <typename>
    struct begin_impl;

    template <>
    struct begin_impl<map_tag>
    {
        template <typename Seq>
        struct apply
        {
            typedef
                basic_iterator<
                    map_iterator_tag
                  , typename Seq::category
                  , Seq
                  , 0
                >
            type;

            BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
            static type
            call(Seq& seq)
            {
                return type(seq,0);
            }
        };
    };
}}}

#endif


code:
// Copyright (C) 2006 Douglas Gregor <doug.gregor -at- gmail.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)

//  Authors: Douglas Gregor

/** @file serialize.hpp
 *
 *  This file provides Boost.Serialization support for Python objects
 *  within Boost.MPI. Python objects can be serialized in one of two
 *  ways. The default serialization method involves using the Python
 *  "pickle" module to pickle the Python objects, transmits the
 *  pickled representation, and unpickles the result when
 *  received. For C++ types that have been exposed to Python and
 *  registered with register_serialized(), objects are directly
 *  serialized for transmissing, skipping the pickling step.
 */
#ifndef BOOST_MPI_PYTHON_SERIALIZE_HPP
#define BOOST_MPI_PYTHON_SERIALIZE_HPP

#include <boost/mpi/python/config.hpp>

#include <boost/python/object.hpp>
#include <boost/python/str.hpp>
#include <boost/python/extract.hpp>

#include <memory>
#include <map>

#include <boost/function/function3.hpp>

#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>

#include <boost/serialization/split_free.hpp>
#include <boost/serialization/array.hpp>

#include <boost/assert.hpp>

#include <boost/type_traits/is_fundamental.hpp>

#define BOOST_MPI_PYTHON_FORWARD_ONLY
#include <boost/mpi/python.hpp>

/************************************************************************
 * Boost.Python Serialization Section                                   *
 ************************************************************************/
#if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)
/**
 * @brief Declare IArchive and OArchive as a Boost.Serialization
 * archives that can be used for Python objects.
 *
 * This macro can only be expanded from the global namespace. It only
 * requires that Archiver be forward-declared. IArchiver and OArchiver
 * will only support Serialization of Python objects by pickling
 * them. If the Archiver type should also support "direct"
 * serialization (for C++ types), use
 * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE instead.
 */
#  define BOOST_PYTHON_SERIALIZATION_ARCHIVE(IArchiver, OArchiver)        \
namespace boost { namespace python { namespace api {    \
  template<typename R, typename T>                      \
  struct enable_binary< IArchiver , R, T> {};           \
                                                        \
  template<typename R, typename T>                      \
  struct enable_binary< OArchiver , R, T> {};           \
} } }
# else
#  define BOOST_PYTHON_SERIALIZATION_ARCHIVE(IArchiver, OArchiver)
#endif

/**
 * @brief Declare IArchiver and OArchiver as a Boost.Serialization
 * archives that can be used for Python objects and C++ objects
 * wrapped in Python.
 *
 * This macro can only be expanded from the global namespace. It only
 * requires that IArchiver and OArchiver be forward-declared. However,
 * note that you will also need to write
 * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE_IMPL(IArchiver,
 * OArchiver) in one of your translation units.

DPG PICK UP HERE
 */
#define BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE(IArchiver, OArchiver) \
BOOST_PYTHON_SERIALIZATION_ARCHIVE(IArchiver, OArchiver)                \
namespace boost { namespace python { namespace detail {                 \
template<>                                                              \
BOOST_MPI_PYTHON_DECL direct_serialization_table< IArchiver , OArchiver >& \
 get_direct_serialization_table< IArchiver , OArchiver >();             \
}                                                                       \
                                                                        \
template<>                                                              \
struct has_direct_serialization< IArchiver , OArchiver> : mpl::true_ { }; \
                                                                        \
template<>                                                              \
struct output_archiver< IArchiver > { typedef OArchiver type; };        \
                                                                        \
template<>                                                              \
struct input_archiver< OArchiver > { typedef IArchiver type; };         \
} }

/**
 * @brief Define the implementation for Boost.Serialization archivers
 * that can be used for Python objects and C++ objects wrapped in
 * Python.
 *
 * This macro can only be expanded from the global namespace. It only
 * requires that IArchiver and OArchiver be forward-declared. Before
 * using this macro, you will need to declare IArchiver and OArchiver
 * as direct serialization archives with
 * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE(IArchiver, OArchiver).
 */
#define BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE_IMPL(IArchiver, OArchiver) \
namespace boost { namespace python { namespace detail {                 \
template                                                                \
  class BOOST_MPI_PYTHON_DECL direct_serialization_table< IArchiver , OArchiver >; \
                                                                        \
template<>                                                              \
 BOOST_MPI_PYTHON_DECL                                                  \
 direct_serialization_table< IArchiver , OArchiver >&                   \
 get_direct_serialization_table< IArchiver , OArchiver >( )             \
{                                                                       \
  static direct_serialization_table< IArchiver, OArchiver > table;      \
  return table;                                                         \
}                                                                       \
} } }

namespace boost { namespace python {

/**
 * INTERNAL ONLY
 *
 * Provides access to the Python "pickle" module from within C++.
 */
class BOOST_MPI_PYTHON_DECL pickle {
  struct data_t;

public:
  static str dumps(object obj, int protocol = -1);
  static object loads(str s);

private:
  static void initialize_data();

  static data_t* data;
};

/**
 * @brief Whether the input/output archiver pair has "direct"
 * serialization for C++ objects exposed in Python.
 *
 * Users do not typically need to specialize this trait, as it will be
 * specialized as part of the macro
 * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE.
 */
template<typename IArchiver, typename OArchiver>
struct has_direct_serialization : mpl::false_ { };

/**
 *  @brief A metafunction that determines the output archiver for the
 *  given input archiver.
 *
 * Users do not typically need to specialize this trait, as it will be
 * specialized as part of the macro
 * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE.
 */
template<typename IArchiver> struct output_archiver { };

/**
 *  @brief A metafunction that determines the input archiver for the
 *  given output archiver.
 *
 * Users do not typically need to specialize this trait, as it will be
 * specialized as part of the macro
 * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE.
 *
 */
template<typename OArchiver> struct input_archiver { };

namespace detail {

  /**
   * INTERNAL ONLY
   *
   * This class contains the direct-serialization code for the given
   * IArchiver/OArchiver pair. It is intended to be used as a
   * singleton class, and will be accessed when (de-)serializing a
   * Boost.Python object with an archiver that supports direct
   * serializations. Do not create instances of this class directly:
   * instead, use get_direct_serialization_table.
   */
  template<typename IArchiver, typename OArchiver>
  class BOOST_MPI_PYTHON_DECL direct_serialization_table
  {
  public:
    typedef boost::function3<void, OArchiver&, const object&, const unsigned int>
      saver_t;
    typedef boost::function3<void, IArchiver&, object&, const unsigned int>
      loader_t;

    typedef std::map<PyTypeObject*, std::pair<int, saver_t> > savers_t;
    typedef std::map<int, loader_t> loaders_t;

    /**
     * Retrieve the saver (serializer) associated with the Python
     * object @p obj.
     *
     *   @param obj The object we want to save. Only its (Python) type
     *   is important.
     *
     *   @param descriptor The value of the descriptor associated to
     *   the returned saver. Will be set to zero if no saver was found
     *   for @p obj.
     *
     *   @returns a function object that can be used to serialize this
     *   object (and other objects of the same type), if possible. If
     *   no saver can be found, returns an empty function object..
     */
    saver_t saver(const object& obj, int& descriptor)
    {
      typename savers_t::iterator pos = savers.find(obj.ptr()->ob_type);
      if (pos != savers.end()) {
        descriptor = pos->second.first;
        return pos->second.second;
      }
      else {
        descriptor = 0;
        return saver_t();
      }
    }

    /**
     * Retrieve the loader (deserializer) associated with the given
     * descriptor.
     *
     *  @param descriptor The descriptor number provided by saver()
     *  when determining the saver for this type.
     *
     *  @returns a function object that can be used to deserialize an
     *  object whose type is the same as that corresponding to the
     *  descriptor. If the descriptor is unknown, the return value
     *  will be an empty function object.
     */
    loader_t loader(int descriptor)
    {
      typename loaders_t::iterator pos = loaders.find(descriptor);
      if (pos != loaders.end())
        return pos->second;
      else
        return loader_t();
    }

    /**
     * Register the type T for direct serialization.
     *
     *  @param value A sample value of the type @c T. This may be used
     *  to compute the Python type associated with the C++ type @c T.
     *
     *  @param type The Python type associated with the C++ type @c
     *  T. If not provided, it will be computed from the same value @p
     *  value.
     */
    template<typename T>
    void register_type(const T& value = T(), PyTypeObject* type = 0)
    {
      // If the user did not provide us with a Python type, figure it
      // out for ourselves.
      if (!type) {
        object obj(value);
        type = obj.ptr()->ob_type;
      }

      register_type(default_saver<T>(), default_loader<T>(type), value, type);
    }

    /**
     * Register the type T for direct serialization.
     *
     *  @param saver A function object that will serialize a
     *  Boost.Python object (that represents a C++ object of type @c
     *  T) to an @c OArchive.
     *
     *  @param loader A function object that will deserialize from an
     *  @c IArchive into a Boost.Python object that represents a C++
     *  object of type @c T.
     *
     *  @param value A sample value of the type @c T. This may be used
     *  to compute the Python type associated with the C++ type @c T.
     *
     *  @param type The Python type associated with the C++ type @c
     *  T. If not provided, it will be computed from the same value @p
     *  value.
     */
    template<typename T>
    void register_type(const saver_t& saver, const loader_t& loader,
                       const T& value = T(), PyTypeObject* type = 0)
    {
      // If the user did not provide us with a Python type, figure it
      // out for ourselves.
      if (!type) {
        object obj(value);
        type = obj.ptr()->ob_type;
      }

      int descriptor = savers.size() + 1;
      if (savers.find(type) != savers.end())
        return;

      savers[type] = std::make_pair(descriptor, saver);
      loaders[descriptor] = loader;
    }

  protected:
    template<typename T>
    struct default_saver {
      void operator()(OArchiver& ar, const object& obj, const unsigned int) {
        T value = extract<T>(obj)();
        ar << value;
      }
    };

    template<typename T>
    struct default_loader {
      default_loader(PyTypeObject* type) : type(type) { }

      void operator()(IArchiver& ar, object& obj, const unsigned int) {
        // If we can, extract the object in place.
        if (!is_fundamental<T>::value && obj && obj.ptr()->ob_type == type) {
          ar >> extract<T&>(obj)();
        } else {
          T value;
          ar >> value;
          obj = object(value);
        }
      }

    private:
      PyTypeObject* type;
    };

    savers_t savers;
    loaders_t loaders;
  };

  /**
   * @brief Retrieve the direct-serialization table for an
   * IArchiver/OArchiver pair.
   *
   * This function is responsible for returning a reference to the
   * singleton direct-serialization table. Its primary template is
   * left undefined, to force the use of an explicit specialization
   * with a definition in a single translation unit. Use the macro
   * BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE_IMPL to define this
   * explicit specialization.
   */
  template<typename IArchiver, typename OArchiver>
  direct_serialization_table<IArchiver, OArchiver>&
  get_direct_serialization_table();
} // end namespace detail

/**
 * @brief Register the type T for direct serialization.
 *
 * The @c register_serialized function registers a C++ type for direct
 * serialization with the given @c IArchiver/@c OArchiver pair. Direct
 * serialization elides the use of the Python @c pickle package when
 * serializing Python objects that represent C++ values. Direct
 * serialization can be beneficial both to improve serialization
 * performance (Python pickling can be very inefficient) and to permit
 * serialization for Python-wrapped C++ objects that do not support
 * pickling.
 *
 *  @param value A sample value of the type @c T. This may be used
 *  to compute the Python type associated with the C++ type @c T.
 *
 *  @param type The Python type associated with the C++ type @c
 *  T. If not provided, it will be computed from the same value @p
 *  value.
 */
template<typename IArchiver, typename OArchiver, typename T>
void
register_serialized(const T& value = T(), PyTypeObject* type = 0)
{
  detail::direct_serialization_table<IArchiver, OArchiver>& table =
    detail::get_direct_serialization_table<IArchiver, OArchiver>();
  table.register_type(value, type);
}

namespace detail {

/// Save a Python object by pickling it.
template<typename Archiver>
void
save_impl(Archiver& ar, const boost::python::object& obj,
          const unsigned int /*version*/,
          mpl::false_ /*has_direct_serialization*/)
{
  boost::python::str py_string = boost::python::pickle::dumps(obj);
  int len = boost::python::extract<int>(py_string.attr("__len__")());
  const char* string = boost::python::extract<const char*>(py_string);
  ar << len << boost::serialization::make_array(string, len);
}

/// Try to save a Python object by directly serializing it; fall back
/// on pickling if required.
template<typename Archiver>
void
save_impl(Archiver& ar, const boost::python::object& obj,
          const unsigned int version,
          mpl::true_ /*has_direct_serialization*/)
{
  typedef Archiver OArchiver;
  typedef typename input_archiver<OArchiver>::type IArchiver;
  typedef typename direct_serialization_table<IArchiver, OArchiver>::saver_t
    saver_t;

  direct_serialization_table<IArchiver, OArchiver>& table =
    get_direct_serialization_table<IArchiver, OArchiver>();

  int descriptor = 0;
  if (saver_t saver = table.saver(obj, descriptor)) {
    ar << descriptor;
    saver(ar, obj, version);
  } else {
    // Pickle it
    ar << descriptor;
    detail::save_impl(ar, obj, version, mpl::false_());
  }
}

/// Load a Python object by unpickling it
template<typename Archiver>
void
load_impl(Archiver& ar, boost::python::object& obj,
          const unsigned int /*version*/,
          mpl::false_ /*has_direct_serialization*/)
{
  int len;
  ar >> len;

  std::auto_ptr<char> string(new char[len]);
  ar >> boost::serialization::make_array(string.get(), len);
  boost::python::str py_string(string.get(), len);
  obj = boost::python::pickle::loads(py_string);
}

/// Try to load a Python object by directly deserializing it; fall back
/// on unpickling if required.
template<typename Archiver>
void
load_impl(Archiver& ar, boost::python::object& obj,
          const unsigned int version,
          mpl::true_ /*has_direct_serialization*/)
{
  typedef Archiver IArchiver;
  typedef typename output_archiver<IArchiver>::type OArchiver;
  typedef typename direct_serialization_table<IArchiver, OArchiver>::loader_t
    loader_t;

  direct_serialization_table<IArchiver, OArchiver>& table =
    get_direct_serialization_table<IArchiver, OArchiver>();

  int descriptor;
  ar >> descriptor;

  if (descriptor) {
    loader_t loader = table.loader(descriptor);
    BOOST_ASSERT(loader);

    loader(ar, obj, version);
  } else {
    // Unpickle it
    detail::load_impl(ar, obj, version, mpl::false_());
  }
}

} // end namespace detail

template<typename Archiver>
void
save(Archiver& ar, const boost::python::object& obj,
     const unsigned int version)
{
  typedef Archiver OArchiver;
  typedef typename input_archiver<OArchiver>::type IArchiver;

  detail::save_impl(ar, obj, version,
                    has_direct_serialization<IArchiver, OArchiver>());
}

template<typename Archiver>
void
load(Archiver& ar, boost::python::object& obj,
     const unsigned int version)
{
  typedef Archiver IArchiver;
  typedef typename output_archiver<IArchiver>::type OArchiver;

  detail::load_impl(ar, obj, version,
                    has_direct_serialization<IArchiver, OArchiver>());
}

template<typename Archive>
inline void
serialize(Archive& ar, boost::python::object& obj, const unsigned int version)
{
  boost::serialization::split_free(ar, obj, version);
}

} } // end namespace boost::python

/************************************************************************
 * Boost.MPI-Specific Section                                           *
 ************************************************************************/
namespace boost { namespace mpi {
 class packed_iarchive;
 class packed_oarchive;
} } // end namespace boost::mpi

BOOST_PYTHON_DIRECT_SERIALIZATION_ARCHIVE(
  ::boost::mpi::packed_iarchive,
  ::boost::mpi::packed_oarchive)

namespace boost { namespace mpi { namespace python {

template<typename T>
void
register_serialized(const T& value, PyTypeObject* type)
{
  using boost::python::register_serialized;
  register_serialized<packed_iarchive, packed_oarchive>(value, type);
}

} } } // end namespace boost::mpi::python

#endif // BOOST_MPI_PYTHON_SERIALIZE_HPP