code:
/* boost random/hyperexponential_distribution.hpp header file
 *
 * Copyright Marco Guazzone 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.
 *
 * Much of the code here taken by boost::math::hyperexponential_distribution.
 * To this end, we would like to thank Paul Bristow and John Maddock for their
 * valuable feedback.
 *
 * \author Marco Guazzone (marco.guazzone@gmail.com)
 */

#ifndef BOOST_RANDOM_HYPEREXPONENTIAL_DISTRIBUTION_HPP
#define BOOST_RANDOM_HYPEREXPONENTIAL_DISTRIBUTION_HPP

#include <boost/config.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/vector_io.hpp>
#include <boost/random/discrete_distribution.hpp>
#include <boost/random/exponential_distribution.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/size.hpp>
#include <boost/type_traits/has_pre_increment.hpp>
#include <cassert>
#include <cmath>
#include <cstddef>
#include <iterator>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
# include <initializer_list>
#endif // BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <iostream>
#include <limits>
#include <numeric>
#include <vector>

namespace boost { namespace random {

namespace hyperexp_detail {

template <typename T>
std::vector<T>& normalize(std::vector<T>& v)
{
    if (v.size() == 0)
    {
        return v;
    }

    const T sum = std::accumulate(v.begin(), v.end(), static_cast<T>(0));
    T final_sum = 0;

    const typename std::vector<T>::iterator end = --v.end();
    for (typename std::vector<T>::iterator it = v.begin();
         it != end;
         ++it)
    {
        *it /= sum;
        final_sum += *it;
    }
    *end = 1-final_sum; // avoids round off errors thus ensuring the probabilities really sum to 1

    return v;
}

template <typename RealT>
bool check_probabilities(std::vector<RealT> const& probabilities)
{
    const std::size_t n = probabilities.size();
    RealT sum = 0;
    for (std::size_t i = 0; i < n; ++i)
    {
        if (probabilities[i] < 0
            || probabilities[i] > 1
            || !(boost::math::isfinite)(probabilities[i]))
        {
            return false;
        }
        sum += probabilities[i];
    }

    //NOTE: the check below seems to fail on some architectures.
    //      So we commented it.
    //// - We try to keep phase probabilities correctly normalized in the distribution constructors
    //// - However in practice we have to allow for a very slight divergence from a sum of exactly 1:
    ////if (std::abs(sum-1) > (std::numeric_limits<RealT>::epsilon()*2))
    //// This is from Knuth "The Art of Computer Programming: Vol.2, 3rd Ed", and can be used to
    //// check is two numbers are approximately equal
    //const RealT one = 1;
    //const RealT tol = std::numeric_limits<RealT>::epsilon()*2.0;
    //if (std::abs(sum-one) > (std::max(std::abs(sum), std::abs(one))*tol))
    //{
    //    return false;
    //}

    return true;
}

template <typename RealT>
bool check_rates(std::vector<RealT> const& rates)
{
    const std::size_t n = rates.size();
    for (std::size_t i = 0; i < n; ++i)
    {
        if (rates[i] <= 0
            || !(boost::math::isfinite)(rates[i]))
        {
            return false;
        }
    }
    return true;
}

template <typename RealT>
bool check_params(std::vector<RealT> const& probabilities, std::vector<RealT> const& rates)
{
    if (probabilities.size() != rates.size())
    {
        return false;
    }

    return check_probabilities(probabilities)
           && check_rates(rates);
}

} // Namespace hyperexp_detail

/**
 * The hyperexponential distribution is a real-valued continuous distribution
 * with two parameters, the phase probability vector \c probs and the
 * rate vector \c rates.
 *
 * A \f$k\f$-phase hyperexponential distribution is a mixture of \f$k\f$
 * exponential distributions.
 * For this reason, it is also referred to as mixed exponential
 * distribution or parallel \f$k\f$-phase exponential
 * distribution.
 *
 * A \f$k\f$-phase hyperexponential distribution is characterized by two
 * parameters, namely a phase probability vector \f$\mathbf{\alpha}=(\alpha_1,\ldots,\alpha_k)\f$ and a rate vector \f$\mathbf{\lambda}=(\lambda_1,\ldots,\lambda_k)\f$.
 *
 * A \f$k\f$-phase hyperexponential distribution is frequently used in
 * queueing theory to model the distribution of the superposition of
 * \f$k\f$ independent events, like, for instance, the  service time distribution
 * of a queueing station with \f$k\f$ servers in parallel where the \f$i\f$-th
 * server is chosen with probability \f$\alpha_i\f$ and its service time
 * distribution is an exponential distribution with rate \f$\lambda_i\f$
 * (Allen,1990; Papadopolous et al.,1993; Trivedi,2002).
 *
 * For instance, CPUs service-time distribution in a computing system has often
 * been observed to possess such a distribution (Rosin,1965).
 * Also, the arrival of different types of customer to a single queueing station
 * is often modeled as a hyperexponential distribution (Papadopolous et al.,1993).
 * Similarly, if a product manufactured in several parallel assemply lines and
 * the outputs are merged, the failure density of the overall product is likely
 * to be hyperexponential (Trivedi,2002).
 *
 * Finally, since the hyperexponential distribution exhibits a high Coefficient
 * of Variation (CoV), that is a CoV > 1, it is especially suited to fit
 * empirical data with large CoV (Feitelson,2014; Wolski et al.,2013) and to
 * approximate long-tail probability distributions (Feldmann et al.,1998).
 *
 * See (Boost,2014) for more information and examples.
 *
 * A \f$k\f$-phase hyperexponential distribution has a probability density
 * function
 * \f[
 *  f(x) = \sum_{i=1}^k \alpha_i \lambda_i e^{-x\lambda_i}
 * \f]
 * where:
 * - \f$k\f$ is the number of phases and also the size of the input
 *   vector parameters,
 * - \f$\mathbf{\alpha}=(\alpha_1,\ldots,\alpha_k)\f$ is the phase probability
 *   vector parameter, and
 * - \f$\mathbf{\lambda}=(\lambda_1,\ldots,\lambda_k)\f$ is the rate vector
 *   parameter.
 * .
 *
 * Given a \f$k\f$-phase hyperexponential distribution with phase probability
 * vector \f$\mathbf{\alpha}\f$ and rate vector \f$\mathbf{\lambda}\f$, the
 * random variate generation algorithm consists of the following steps (Tyszer,1999):
 * -# Generate a random variable \f$U\f$ uniformly distribution on the interval \f$(0,1)\f$.
 * -# Use \f$U\f$ to select the appropriate \f$\lambda_i\f$ (e.g., the
 *  alias method can possibly be used for this step).
 * -# Generate an exponentially distributed random variable \f$X\f$ with rate parameter \f$\lambda_i\f$.
 * -# Return \f$X\f$.
 * .
 *
 * References:
 * -# A.O. Allen, Probability, Statistics, and Queuing Theory with Computer Science Applications, Second Edition, Academic Press, 1990.
 * -# Boost C++ Libraries, Boost.Math / Statistical Distributions: Hyperexponential Distribution, Online: http://www.boost.org/doc/libs/release/libs/math/doc/html/dist.html , 2014.
 * -# D.G. Feitelson, Workload Modeling for Computer Systems Performance Evaluation, Cambridge University Press, 2014
 * -# A. Feldmann and W. Whitt, Fitting mixtures of exponentials to long-tail distributions to analyze network performance models, Performance Evaluation 31(3-4):245, doi:10.1016/S0166-5316(97)00003-5, 1998.
 * -# H.T. Papadopolous, C. Heavey and J. Browne, Queueing Theory in Manufacturing Systems Analysis and Design, Chapman & Hall/CRC, 1993, p. 35.
 * -# R.F. Rosin, Determining a computing center environment, Communications of the ACM 8(7):463-468, 1965.
 * -# K.S. Trivedi, Probability and Statistics with Reliability, Queueing, and Computer Science Applications, John Wiley & Sons, Inc., 2002.
 * -# J. Tyszer, Object-Oriented Computer Simulation of Discrete-Event Systems, Springer, 1999.
 * -# Wikipedia, Hyperexponential Distribution, Online: http://en.wikipedia.org/wiki/Hyperexponential_distribution , 2014.
 * -# Wolfram Mathematica, Hyperexponential Distribution, Online: http://reference.wolfram.com/language/ref/HyperexponentialDistribution.html , 2014.
 * .
 *
 * \author Marco Guazzone (marco.guazzone@gmail.com)
 */
template<class RealT = double>
class hyperexponential_distribution
{
    public: typedef RealT result_type;
    public: typedef RealT input_type;

    /**
     * The parameters of a hyperexponential distribution.
     *
     * Stores the phase probability vector and the rate vector
     * of the hyperexponential distribution.
     *
     * \author Marco Guazzone (marco.guazzone@gmail.com)
     */
    public: class param_type
    {
        public: typedef hyperexponential_distribution distribution_type;

        /**
         * Constructs a \c param_type with the default parameters
         * of the distribution.
         */
        public: param_type()
        : probs_(1, 1),
          rates_(1, 1)
        {
        }

        /**
         * Constructs a \c param_type from the phase probability vector
         * and rate vector parameters of the distribution.
         *
         * The phase probability vector parameter is given by the range
         * defined by [\a prob_first, \a prob_last) iterator pair, and the
         * rate vector parameter is given by the range defined by
         * [\a rate_first, \a rate_last) iterator pair.
         *
         * \tparam ProbIterT Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
         * \tparam RateIterT Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
         *
         * \param prob_first The iterator to the beginning of the range of non-negative real elements representing the phase probabilities; if elements don't sum to 1, they are normalized.
         * \param prob_last The iterator to the ending of the range of non-negative real elements representing the phase probabilities; if elements don't sum to 1, they are normalized.
         * \param rate_first The iterator to the beginning of the range of non-negative real elements representing the rates.
         * \param rate_last The iterator to the ending of the range of non-negative real elements representing the rates.
         *
         * References:
         * -# ISO, ISO/IEC 14882-2014: Information technology - Programming languages - C++, 2014
         * .
         */
        public: template <typename ProbIterT, typename RateIterT>
                param_type(ProbIterT prob_first, ProbIterT prob_last,
                           RateIterT rate_first, RateIterT rate_last)
        : probs_(prob_first, prob_last),
          rates_(rate_first, rate_last)
        {
            hyperexp_detail::normalize(probs_);

            assert( hyperexp_detail::check_params(probs_, rates_) );
        }

        /**
         * Constructs a \c param_type from the phase probability vector
         * and rate vector parameters of the distribution.
         *
         * The phase probability vector parameter is given by the range
         * defined by \a prob_range, and the rate vector parameter is
         * given by the range defined by \a rate_range.
         *
         * \tparam ProbRangeT Must meet the requirements of Range concept.
         * \tparam RateRangeT Must meet the requirements of Range concept.
         *
         * \param prob_range The range of non-negative real elements representing the phase probabilities; if elements don't sum to 1, they are normalized.
         * \param rate_range The range of positive real elements representing the rates.
         *
         * \note
         *  The final \c disable_if parameter is an implementation detail that
         *  differentiates between this two argument constructor and the
         *  iterator-based two argument constructor described below.
         */
        //  We SFINAE this out of existance if either argument type is
        //  incrementable as in that case the type is probably an iterator:
        public: template <typename ProbRangeT, typename RateRangeT>
                param_type(ProbRangeT const& prob_range,
                           RateRangeT const& rate_range,
                           typename boost::disable_if_c<boost::has_pre_increment<ProbRangeT>::value || boost::has_pre_increment<RateRangeT>::value>::type* = 0)
        : probs_(boost::begin(prob_range), boost::end(prob_range)),
          rates_(boost::begin(rate_range), boost::end(rate_range))
        {
            hyperexp_detail::normalize(probs_);

            assert( hyperexp_detail::check_params(probs_, rates_) );
        }

        /**
         * Constructs a \c param_type from the rate vector parameter of
         * the distribution and with equal phase probabilities.
         *
         * The rate vector parameter is given by the range defined by
         * [\a rate_first, \a rate_last) iterator pair, and the phase
         * probability vector parameter is set to the equal phase
         * probabilities (i.e., to a vector of the same length \f$k\f$ of the
         * rate vector and with each element set to \f$1.0/k\f$).
         *
         * \tparam RateIterT Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
         * \tparam RateIterT2 Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
         *
         * \param rate_first The iterator to the beginning of the range of non-negative real elements representing the rates.
         * \param rate_last The iterator to the ending of the range of non-negative real elements representing the rates.
         *
         * \note
         *  The final \c disable_if parameter is an implementation detail that
         *  differentiates between this two argument constructor and the
         *  range-based two argument constructor described above.
         *
         * References:
         * -# ISO, ISO/IEC 14882-2014: Information technology - Programming languages - C++, 2014
         * .
         */
        //  We SFINAE this out of existance if the argument type is
        //  incrementable as in that case the type is probably an iterator.
        public: template <typename RateIterT>
                param_type(RateIterT rate_first,
                           RateIterT rate_last,
                           typename boost::enable_if_c<boost::has_pre_increment<RateIterT>::value>::type* = 0)
        : probs_(std::distance(rate_first, rate_last), 1), // will be normalized below
          rates_(rate_first, rate_last)
        {
            assert(probs_.size() == rates_.size());
        }

        /**
         * Constructs a @c param_type from the "rates" parameters
         * of the distribution and with equal phase probabilities.
         *
         * The rate vector parameter is given by the range defined by
         * \a rate_range, and the phase probability vector parameter is
         * set to the equal phase probabilities (i.e., to a vector of the same
         * length \f$k\f$ of the rate vector and with each element set
         * to \f$1.0/k\f$).
         *
         * \tparam RateRangeT Must meet the requirements of Range concept.
         *
         * \param rate_range The range of positive real elements representing the rates.
         */
        public: template <typename RateRangeT>
                param_type(RateRangeT const& rate_range)
        : probs_(boost::size(rate_range), 1), // Will be normalized below
          rates_(boost::begin(rate_range), boost::end(rate_range))
        {
            hyperexp_detail::normalize(probs_);

            assert( hyperexp_detail::check_params(probs_, rates_) );
        }

#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
        /**
         * Constructs a \c param_type from the phase probability vector
         * and rate vector parameters of the distribution.
         *
         * The phase probability vector parameter is given by the
         * brace-init-list (ISO,2014,sec. 8.5.4 [dcl.init.list])
         * defined by \a l1, and the rate vector parameter is given by the
         * brace-init-list (ISO,2014,sec. 8.5.4 [dcl.init.list])
         * defined by \a l2.
         *
         * \param l1 The initializer list for inizializing the phase probability vector.
         * \param l2 The initializer list for inizializing the rate vector.
         *
         * References:
         * -# ISO, ISO/IEC 14882-2014: Information technology - Programming languages - C++, 2014
         * .
         */
        public: param_type(std::initializer_list<RealT> l1, std::initializer_list<RealT> l2)
        : probs_(l1.begin(), l1.end()),
          rates_(l2.begin(), l2.end())
        {
            hyperexp_detail::normalize(probs_);

            assert( hyperexp_detail::check_params(probs_, rates_) );
        }

        /**
         * Constructs a \c param_type from the rate vector parameter
         * of the distribution and with equal phase probabilities.
         *
         * The rate vector parameter is given by the
         * brace-init-list (ISO,2014,sec. 8.5.4 [dcl.init.list])
         * defined by \a l1, and the phase probability vector parameter is
         * set to the equal phase probabilities (i.e., to a vector of the same
         * length \f$k\f$ of the rate vector and with each element set
         * to \f$1.0/k\f$).
         *
         * \param l1 The initializer list for inizializing the rate vector.
         *
         * References:
         * -# ISO, ISO/IEC 14882-2014: Information technology - Programming languages - C++, 2014
         * .
         */
        public: param_type(std::initializer_list<RealT> l1)
        : probs_(std::distance(l1.begin(), l1.end()), 1), // Will be normalized below
          rates_(l1.begin(), l1.end())
        {
            hyperexp_detail::normalize(probs_);

            assert( hyperexp_detail::check_params(probs_, rates_) );
        }
#endif // BOOST_NO_CXX11_HDR_INITIALIZER_LIST

        /**
         * Gets the phase probability vector parameter of the distribtuion.
         *
         * \return The phase probability vector parameter of the distribution.
         *
         * \note
         *  The returned probabilities are the normalized version of the ones
         *  passed at construction time.
         */
        public: std::vector<RealT> probabilities() const
        {
            return probs_;
        }

        /**
         * Gets the rate vector parameter of the distribtuion.
         *
         * \return The rate vector parameter of the distribution.
         */
        public: std::vector<RealT> rates() const
        {
            return rates_;
        }

        /** Writes a \c param_type to a \c std::ostream. */
        public: BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, param)
        {
            detail::print_vector(os, param.probs_);
            os << ' ';
            detail::print_vector(os, param.rates_);

            return os;
        }

        /** Reads a \c param_type from a \c std::istream. */
        public: BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, param)
        {
            // NOTE: if \c std::ios_base::exceptions is set, the code below may
            //       throw in case of a I/O failure.
            //       To prevent leaving the state of \c param inconsistent:
            //       - if an exception is thrown, the state of \c param is left
            //         unchanged (i.e., is the same as the one at the beginning
            //         of the function's execution), and
            //       - the state of \c param only after reading the whole input.

            std::vector<RealT> probs;
            std::vector<RealT> rates;

            // Reads probability and rate vectors
            detail::read_vector(is, probs);
            if (!is)
            {
                return is;
            }
            is >> std::ws;
            detail::read_vector(is, rates);
            if (!is)
            {
                return is;
            }

            // Update the state of the param_type object
            if (probs.size() > 0)
            {
                param.probs_.swap(probs);
                probs.clear();
            }
            if (rates.size() > 0)
            {
                param.rates_.swap(rates);
                rates.clear();
            }

            bool fail = false;

            // Adjust vector sizes (if needed)
            if (param.probs_.size() != param.rates_.size()
                || param.probs_.size() == 0)
            {
                fail = true;

                const std::size_t np = param.probs_.size();
                const std::size_t nr = param.rates_.size();

                if (np > nr)
                {
                    param.rates_.resize(np, 1);
                }
                else if (nr > np)
                {
                    param.probs_.resize(nr, 1);
                }
                else
                {
                    param.probs_.resize(1, 1);
                    param.rates_.resize(1, 1);
                }
            }

            // Normalize probabilities
            // NOTE: this cannot be done earlier since the probability vector
            //       can be changed due to size conformance
            hyperexp_detail::normalize(param.probs_);

            // Set the error state in the underlying stream in case of invalid input
            if (fail)
            {
                // This throws an exception if ios_base::exception(failbit) is enabled
                is.setstate(std::ios_base::failbit);
            }

            //post: vector size conformance
            assert(param.probs_.size() == param.rates_.size());

            return is;
        }

        /** Returns true if the two sets of parameters are the same. */
        public: BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
        {
            return lhs.probs_ == rhs.probs_
                   && lhs.rates_ == rhs.rates_;
        }

        /** Returns true if the two sets of parameters are the different. */
        public: BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)

        private: std::vector<RealT> probs_; ///< The phase probability vector parameter of the distribution
        private: std::vector<RealT> rates_; ///< The rate vector parameter of the distribution
    }; // param_type

    /**
     * Constructs a 1-phase \c hyperexponential_distribution (i.e., an
     * exponential distribution) with rate 1.
     */
    public: hyperexponential_distribution()
    : dd_(std::vector<RealT>(1, 1)),
      rates_(1, 1)
    {
        // empty
    }

    /**
     * Constructs a \c hyperexponential_distribution from the phase
     * probability vector and rate vector parameters of the
     * distribution.
     *
     * The phase probability vector parameter is given by the range
     * defined by [\a prob_first, \a prob_last) iterator pair, and the
     * rate vector parameter is given by the range defined by
     * [\a rate_first, \a rate_last) iterator pair.
     *
     * \tparam ProbIterT Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
     * \tparam RateIterT Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
     *
     * \param prob_first The iterator to the beginning of the range of non-negative real elements representing the phase probabilities; if elements don't sum to 1, they are normalized.
     * \param prob_last The iterator to the ending of the range of non-negative real elements representing the phase probabilities; if elements don't sum to 1, they are normalized.
     * \param rate_first The iterator to the beginning of the range of non-negative real elements representing the rates.
     * \param rate_last The iterator to the ending of the range of non-negative real elements representing the rates.
     *
     * References:
     * -# ISO, ISO/IEC 14882-2014: Information technology - Programming languages - C++, 2014
     * .
     */
    public: template <typename ProbIterT, typename RateIterT>
            hyperexponential_distribution(ProbIterT prob_first, ProbIterT prob_last,
                                          RateIterT rate_first, RateIterT rate_last)
    : dd_(prob_first, prob_last),
      rates_(rate_first, rate_last)
    {
        assert( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
    }

    /**
     * Constructs a \c hyperexponential_distribution from the phase
     * probability vector and rate vector parameters of the
     * distribution.
     *
     * The phase probability vector parameter is given by the range
     * defined by \a prob_range, and the rate vector parameter is
     * given by the range defined by \a rate_range.
     *
     * \tparam ProbRangeT Must meet the requirements of Range concept.
     * \tparam RateRangeT Must meet the requirements of Range concept.
     *
     * \param prob_range The range of non-negative real elements representing the phase probabilities; if elements don't sum to 1, they are normalized.
     * \param rate_range The range of positive real elements representing the rates.
     *
     * \note
     *  The final \c disable_if parameter is an implementation detail that
     *  differentiates between this two argument constructor and the
     *  iterator-based two argument constructor described below.
     */
    //  We SFINAE this out of existance if either argument type is
    //  incrementable as in that case the type is probably an iterator:
    public: template <typename ProbRangeT, typename RateRangeT>
            hyperexponential_distribution(ProbRangeT const& prob_range,
                                          RateRangeT const& rate_range,
                                          typename boost::disable_if_c<boost::has_pre_increment<ProbRangeT>::value || boost::has_pre_increment<RateRangeT>::value>::type* = 0)
    : dd_(prob_range),
      rates_(boost::begin(rate_range), boost::end(rate_range))
    {
        assert( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
    }

    /**
     * Constructs a \c hyperexponential_distribution from the rate
     * vector parameter of the distribution and with equal phase
     * probabilities.
     *
     * The rate vector parameter is given by the range defined by
     * [\a rate_first, \a rate_last) iterator pair, and the phase
     * probability vector parameter is set to the equal phase
     * probabilities (i.e., to a vector of the same length \f$k\f$ of the
     * rate vector and with each element set to \f$1.0/k\f$).
     *
     * \tparam RateIterT Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
     * \tparam RateIterT2 Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
     *
     * \param rate_first The iterator to the beginning of the range of non-negative real elements representing the rates.
     * \param rate_last The iterator to the ending of the range of non-negative real elements representing the rates.
     *
     * \note
     *  The final \c disable_if parameter is an implementation detail that
     *  differentiates between this two argument constructor and the
     *  range-based two argument constructor described above.
     *
     * References:
     * -# ISO, ISO/IEC 14882-2014: Information technology - Programming languages - C++, 2014
     * .
     */
    //  We SFINAE this out of existance if the argument type is
    //  incrementable as in that case the type is probably an iterator.
    public: template <typename RateIterT>
            hyperexponential_distribution(RateIterT rate_first,
                                          RateIterT rate_last,
                                          typename boost::enable_if_c<boost::has_pre_increment<RateIterT>::value>::type* = 0)
    : dd_(std::vector<RealT>(std::distance(rate_first, rate_last), 1)),
      rates_(rate_first, rate_last)
    {
        assert( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
    }

    /**
     * Constructs a @c param_type from the "rates" parameters
     * of the distribution and with equal phase probabilities.
     *
     * The rate vector parameter is given by the range defined by
     * \a rate_range, and the phase probability vector parameter is
     * set to the equal phase probabilities (i.e., to a vector of the same
     * length \f$k\f$ of the rate vector and with each element set
     * to \f$1.0/k\f$).
     *
     * \tparam RateRangeT Must meet the requirements of Range concept.
     *
     * \param rate_range The range of positive real elements representing the rates.
     */
    public: template <typename RateRangeT>
            hyperexponential_distribution(RateRangeT const& rate_range)
    : dd_(std::vector<RealT>(boost::size(rate_range), 1)),
      rates_(boost::begin(rate_range), boost::end(rate_range))
    {
        assert( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
    }

    /**
     * Constructs a \c hyperexponential_distribution from its parameters.
     *
     * \param param The parameters of the distribution.
     */
    public: explicit hyperexponential_distribution(param_type const& param)
    : dd_(param.probabilities()),
      rates_(param.rates())
    {
        assert( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
    }

#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
    /**
     * Constructs a \c hyperexponential_distribution from the phase
     * probability vector and rate vector parameters of the
     * distribution.
     *
     * The phase probability vector parameter is given by the
     * brace-init-list (ISO,2014,sec. 8.5.4 [dcl.init.list])
     * defined by \a l1, and the rate vector parameter is given by the
     * brace-init-list (ISO,2014,sec. 8.5.4 [dcl.init.list])
     * defined by \a l2.
     *
     * \param l1 The initializer list for inizializing the phase probability vector.
     * \param l2 The initializer list for inizializing the rate vector.
     *
     * References:
     * -# ISO, ISO/IEC 14882-2014: Information technology - Programming languages - C++, 2014
     * .
     */
    public: hyperexponential_distribution(std::initializer_list<RealT> const& l1, std::initializer_list<RealT> const& l2)
    : dd_(l1.begin(), l1.end()),
      rates_(l2.begin(), l2.end())
    {
        assert( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
    }

    /**
     * Constructs a \c hyperexponential_distribution from the rate
     * vector parameter of the distribution and with equal phase
     * probabilities.
     *
     * The rate vector parameter is given by the
     * brace-init-list (ISO,2014,sec. 8.5.4 [dcl.init.list])
     * defined by \a l1, and the phase probability vector parameter is
     * set to the equal phase probabilities (i.e., to a vector of the same
     * length \f$k\f$ of the rate vector and with each element set
     * to \f$1.0/k\f$).
     *
     * \param l1 The initializer list for inizializing the rate vector.
     *
     * References:
     * -# ISO, ISO/IEC 14882-2014: Information technology - Programming languages - C++, 2014
     * .
     */
    public: hyperexponential_distribution(std::initializer_list<RealT> const& l1)
    : dd_(std::vector<RealT>(std::distance(l1.begin(), l1.end()), 1)),
      rates_(l1.begin(), l1.end())
    {
        assert( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
    }
#endif

    /**
     * Gets a random variate distributed according to the
     * hyperexponential distribution.
     *
     * \tparam URNG Must meet the requirements of \uniform_random_number_generator.
     *
     * \param urng A uniform random number generator object.
     *
     * \return A random variate distributed according to the hyperexponential distribution.
     */
    public: template<class URNG>\
            RealT operator()(URNG& urng) const
    {
        const int i = dd_(urng);

        return boost::random::exponential_distribution<RealT>(rates_[i])(urng);
    }

    /**
     * Gets a random variate distributed according to the hyperexponential
     * distribution with parameters specified by \c param.
     *
     * \tparam URNG Must meet the requirements of \uniform_random_number_generator.
     *
     * \param urng A uniform random number generator object.
     * \param param A distribution parameter object.
     *
     * \return A random variate distributed according to the hyperexponential distribution.
     *  distribution with parameters specified by \c param.
     */
    public: template<class URNG>
            RealT operator()(URNG& urng, const param_type& param) const
    {
        return hyperexponential_distribution(param)(urng);
    }

    /** Returns the number of phases of the distribution. */
    public: std::size_t num_phases() const
    {
        return rates_.size();
    }

    /** Returns the phase probability vector parameter of the distribution. */
    public: std::vector<RealT> probabilities() const
    {
        return dd_.probabilities();
    }

    /** Returns the rate vector parameter of the distribution. */
    public: std::vector<RealT> rates() const
    {
        return rates_;
    }

    /** Returns the smallest value that the distribution can produce. */
    public: RealT min BOOST_PREVENT_MACRO_SUBSTITUTION () const
    {
        return 0;
    }

    /** Returns the largest value that the distribution can produce. */
    public: RealT max BOOST_PREVENT_MACRO_SUBSTITUTION () const
    {
        return std::numeric_limits<RealT>::infinity();
    }

    /** Returns the parameters of the distribution. */
    public: param_type param() const
    {
        std::vector<RealT> probs = dd_.probabilities();

        return param_type(probs.begin(), probs.end(), rates_.begin(), rates_.end());
    }

    /** Sets the parameters of the distribution. */
    public: void param(param_type const& param)
    {
        dd_.param(typename boost::random::discrete_distribution<int,RealT>::param_type(param.probabilities()));
        rates_ = param.rates();
    }

    /**
     * Effects: Subsequent uses of the distribution do not depend
     * on values produced by any engine prior to invoking reset.
     */
    public: void reset()
    {
        // empty
    }

    /** Writes an @c hyperexponential_distribution to a @c std::ostream. */
    public: BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, hyperexponential_distribution, hd)
    {
        os << hd.param();
        return os;
    }

    /** Reads an @c hyperexponential_distribution from a @c std::istream. */
    public: BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, hyperexponential_distribution, hd)
    {
        param_type param;
        if(is >> param)
        {
            hd.param(param);
        }
        return is;
    }

    /**
     * Returns true if the two instances of @c hyperexponential_distribution will
     * return identical sequences of values given equal generators.
     */
    public: BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(hyperexponential_distribution, lhs, rhs)
    {
        return lhs.dd_ == rhs.dd_
               && lhs.rates_ == rhs.rates_;
    }

    /**
     * Returns true if the two instances of @c hyperexponential_distribution will
     * return different sequences of values given equal generators.
     */
    public: BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(hyperexponential_distribution)

    private: boost::random::discrete_distribution<int,RealT> dd_; ///< The \c discrete_distribution used to sample the phase probability and choose the rate
    private: std::vector<RealT> rates_; ///< The rate vector parameter of the distribution
}; // hyperexponential_distribution

}} // namespace boost::random

#endif // BOOST_RANDOM_HYPEREXPONENTIAL_DISTRIBUTION_HPP


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

    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_PP_IS_ITERATING
#if !defined(FUSION_PP_MAP_TIE_20060814_1116)
#define FUSION_PP_MAP_TIE_20060814_1116

#include <boost/preprocessor/iterate.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/fusion/container/map/map.hpp>
#include <boost/fusion/container/map/detail/cpp03/limits.hpp>
#include <boost/fusion/support/pair.hpp>
#include <boost/fusion/container/generation/pair_tie.hpp>
#include <boost/type_traits/add_reference.hpp>

#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
#include <boost/fusion/container/generation/detail/preprocessed/map_tie.hpp>
#else
#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
#pragma wave option(preserve: 2, line: 0, output: "preprocessed/map_tie" FUSION_MAX_MAP_SIZE_STR".hpp")
#endif

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

    This is an auto-generated file. Do not edit!
==============================================================================*/

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

namespace boost { namespace fusion
{
    struct void_;

    namespace result_of
    {
        template <
            BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
                FUSION_MAX_MAP_SIZE, typename K, void_)
          , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
                FUSION_MAX_MAP_SIZE, typename D, void_)
          , typename Extra = void_
        >
        struct map_tie;

        template <>
        struct map_tie<>
        {
            typedef map<> type;
        };
    }

    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
    inline map<>
    map_tie()
    {
        return map<>();
    }

#define BOOST_FUSION_TIED_PAIR(z, n, data)                                                          \
    fusion::pair<                                                                                \
        BOOST_PP_CAT(K, n)                                                                          \
      , typename add_reference<BOOST_PP_CAT(D, n)>::type>

#define BOOST_FUSION_PAIR_TIE(z, n, _)                                         \
    fusion::pair_tie<BOOST_PP_CAT(K, n)>(BOOST_PP_CAT(_, n))                   \

#define BOOST_PP_FILENAME_1 <boost/fusion/container/generation/detail/pp_map_tie.hpp>
#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_MAP_SIZE)
#include BOOST_PP_ITERATE()

#undef BOOST_FUSION_PAIR
#undef BOOST_FUSION_MAKE_PAIR

}}

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

#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES

#endif
#else // defined(BOOST_PP_IS_ITERATING)
///////////////////////////////////////////////////////////////////////////////
//
//  Preprocessor vertical repetition code
//
///////////////////////////////////////////////////////////////////////////////

#define N BOOST_PP_ITERATION()

    namespace result_of
    {
        template <
            BOOST_PP_ENUM_PARAMS(N, typename K)
          , BOOST_PP_ENUM_PARAMS(N, typename D)
        >
        #define TEXT(z, n, text) , text
        struct map_tie<BOOST_PP_ENUM_PARAMS(N, K), BOOST_PP_ENUM_PARAMS(N, D) BOOST_PP_REPEAT_FROM_TO(N, FUSION_MAX_MAP_SIZE, TEXT, void_) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_MAP_SIZE, TEXT, void_)>
        #undef TEXT
        {
            typedef map<BOOST_PP_ENUM(N, BOOST_FUSION_TIED_PAIR, _)> type;
        };
    }

    template <
        BOOST_PP_ENUM_PARAMS(N, typename K)
      , BOOST_PP_ENUM_PARAMS(N, typename D)
    >
    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
    inline map<BOOST_PP_ENUM(N, BOOST_FUSION_TIED_PAIR, _)>
    map_tie(BOOST_PP_ENUM_BINARY_PARAMS(N, D, & arg))
    {
        return map<BOOST_PP_ENUM(N, BOOST_FUSION_TIED_PAIR, _)>(
            BOOST_PP_ENUM(N, BOOST_FUSION_PAIR_TIE, arg));
    }

#undef N
#endif // defined(BOOST_PP_IS_ITERATING)

license: mit


code:
#ifndef BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP
#define BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP

// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// archive/archive_exception.hpp:

// (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 <exception>
#include <boost/assert.hpp>
#include <string>

#include <boost/config.hpp>
#include <boost/archive/detail/decl.hpp>

// note: the only reason this is in here is that windows header
// includes #define exception_code _exception_code (arrrgghhhh!).
// the most expedient way to address this is be sure that this
// header is always included whenever this header file is included.
#if defined(BOOST_WINDOWS)
#include <excpt.h>
#endif

#include <boost/archive/detail/abi_prefix.hpp> // must be the last header

namespace boost {
namespace archive {

//////////////////////////////////////////////////////////////////////
// exceptions thrown by archives
//
class BOOST_SYMBOL_VISIBLE archive_exception :
    public virtual std::exception
{
private:
    char m_buffer[128];
protected:
    BOOST_ARCHIVE_DECL unsigned int
    append(unsigned int l, const char * a);
    BOOST_ARCHIVE_DECL
    archive_exception() BOOST_NOEXCEPT;
public:
    typedef enum {
        no_exception,       // initialized without code
        other_exception,    // any excepton not listed below
        unregistered_class, // attempt to serialize a pointer of
                            // an unregistered class
        invalid_signature,  // first line of archive does not contain
                            // expected string
        unsupported_version,// archive created with library version
                            // subsequent to this one
        pointer_conflict,   // an attempt has been made to directly
                            // serialize an object which has
                            // already been serialized through a pointer.
                            // Were this permitted, the archive load would result
                            // in the creation of an extra copy of the obect.
        incompatible_native_format, // attempt to read native binary format
                            // on incompatible platform
        array_size_too_short,// array being loaded doesn't fit in array allocated
        input_stream_error, // error on input stream
        invalid_class_name, // class name greater than the maximum permitted.
                            // most likely a corrupted archive or an attempt
                            // to insert virus via buffer overrun method.
        unregistered_cast,   // base - derived relationship not registered with
                            // void_cast_register
        unsupported_class_version, // type saved with a version # greater than the
                            // one used by the program.  This indicates that the program
                            // needs to be rebuilt.
        multiple_code_instantiation, // code for implementing serialization for some
                            // type has been instantiated in more than one module.
        output_stream_error // error on input stream
    } exception_code;
    exception_code code;

    BOOST_ARCHIVE_DECL archive_exception(
        exception_code c,
        const char * e1 = NULL,
        const char * e2 = NULL
    ) BOOST_NOEXCEPT;
    BOOST_ARCHIVE_DECL archive_exception(archive_exception const &) BOOST_NOEXCEPT ;
    virtual BOOST_ARCHIVE_DECL ~archive_exception() BOOST_NOEXCEPT_OR_NOTHROW ;
    virtual BOOST_ARCHIVE_DECL const char * what() const BOOST_NOEXCEPT_OR_NOTHROW ;
};

}// namespace archive
}// namespace boost

#include <boost/archive/detail/abi_suffix.hpp> // pops abi_suffix.hpp pragmas

#endif //BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP


code:
// 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)
//

// Preprocessed version of "boost/mpl/vector/vector10.hpp" header
// -- DO NOT modify by hand!

namespace boost { namespace mpl {

namespace aux {
template<> struct v_at_impl<0>
{
    template< typename V_ > struct result_
    {
        typedef typename V_::item0 type;
    };
};

}

template<>
struct at_impl< aux::vector_tag<0> >
{
    template< typename V_, typename N > struct apply
    {
        typedef typename aux::v_at_impl<BOOST_MPL_AUX_VALUE_WKND(N)::value>
            ::template result_<V_>::type type;
    };
};

template<>
struct size_impl< aux::vector_tag<0> >
{
    template< typename Vector > struct apply
        : long_<0>
    {
    };
};

template<>
struct O1_size_impl< aux::vector_tag<0> >
    : size_impl< aux::vector_tag<0> >
{
};

template<>
struct clear_impl< aux::vector_tag<0> >
{
    template< typename Vector > struct apply
    {
        typedef vector0<> type;
    };
};

template<
      typename T0
    >
struct vector1
{
    typedef aux::vector_tag<1> tag;
    typedef vector1 type;
    typedef T0 item0;
    typedef void_ item1;
    typedef T0 back;
    typedef v_iter< type,0 > begin;
    typedef v_iter< type,1 > end;
};

template<>
struct push_front_impl< aux::vector_tag<0> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector1<
              T
            > type;
    };
};

template<>
struct pop_front_impl< aux::vector_tag<1> >
{
    template< typename Vector > struct apply
    {
        typedef vector0<

            > type;
    };
};

template<>
struct push_back_impl< aux::vector_tag<0> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector1<

              T
            > type;
    };
};

template<>
struct pop_back_impl< aux::vector_tag<1> >
{
    template< typename Vector > struct apply
    {
        typedef vector0<

            > type;
    };
};

namespace aux {
template<> struct v_at_impl<1>
{
    template< typename V_ > struct result_
    {
        typedef typename V_::item1 type;
    };
};

}

template<>
struct at_impl< aux::vector_tag<1> >
{
    template< typename V_, typename N > struct apply
    {
        typedef typename aux::v_at_impl<BOOST_MPL_AUX_VALUE_WKND(N)::value>
            ::template result_<V_>::type type;
    };
};

template<>
struct front_impl< aux::vector_tag<1> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::item0 type;
    };
};

template<>
struct back_impl< aux::vector_tag<1> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::back type;
    };
};

template<>
struct empty_impl< aux::vector_tag<1> >
{
    template< typename Vector > struct apply
        : false_
    {
    };
};

template<>
struct size_impl< aux::vector_tag<1> >
{
    template< typename Vector > struct apply
        : long_<1>
    {
    };
};

template<>
struct O1_size_impl< aux::vector_tag<1> >
    : size_impl< aux::vector_tag<1> >
{
};

template<>
struct clear_impl< aux::vector_tag<1> >
{
    template< typename Vector > struct apply
    {
        typedef vector0<> type;
    };
};

template<
      typename T0, typename T1
    >
struct vector2
{
    typedef aux::vector_tag<2> tag;
    typedef vector2 type;
    typedef T0 item0;
    typedef T1 item1;

    typedef void_ item2;
    typedef T1 back;
    typedef v_iter< type,0 > begin;
    typedef v_iter< type,2 > end;
};

template<>
struct push_front_impl< aux::vector_tag<1> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector2<
              T
              ,
              typename Vector::item0
            > type;
    };
};

template<>
struct pop_front_impl< aux::vector_tag<2> >
{
    template< typename Vector > struct apply
    {
        typedef vector1<
              typename Vector::item1
            > type;
    };
};

template<>
struct push_back_impl< aux::vector_tag<1> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector2<
              typename Vector::item0
              ,
              T
            > type;
    };
};

template<>
struct pop_back_impl< aux::vector_tag<2> >
{
    template< typename Vector > struct apply
    {
        typedef vector1<
              typename Vector::item0
            > type;
    };
};

namespace aux {
template<> struct v_at_impl<2>
{
    template< typename V_ > struct result_
    {
        typedef typename V_::item2 type;
    };
};

}

template<>
struct at_impl< aux::vector_tag<2> >
{
    template< typename V_, typename N > struct apply
    {
        typedef typename aux::v_at_impl<BOOST_MPL_AUX_VALUE_WKND(N)::value>
            ::template result_<V_>::type type;
    };
};

template<>
struct front_impl< aux::vector_tag<2> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::item0 type;
    };
};

template<>
struct back_impl< aux::vector_tag<2> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::back type;
    };
};

template<>
struct empty_impl< aux::vector_tag<2> >
{
    template< typename Vector > struct apply
        : false_
    {
    };
};

template<>
struct size_impl< aux::vector_tag<2> >
{
    template< typename Vector > struct apply
        : long_<2>
    {
    };
};

template<>
struct O1_size_impl< aux::vector_tag<2> >
    : size_impl< aux::vector_tag<2> >
{
};

template<>
struct clear_impl< aux::vector_tag<2> >
{
    template< typename Vector > struct apply
    {
        typedef vector0<> type;
    };
};

template<
      typename T0, typename T1, typename T2
    >
struct vector3
{
    typedef aux::vector_tag<3> tag;
    typedef vector3 type;
    typedef T0 item0;
    typedef T1 item1;
    typedef T2 item2;

    typedef void_ item3;
    typedef T2 back;
    typedef v_iter< type,0 > begin;
    typedef v_iter< type,3 > end;
};

template<>
struct push_front_impl< aux::vector_tag<2> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector3<
              T
              ,
              typename Vector::item0, typename Vector::item1
            > type;
    };
};

template<>
struct pop_front_impl< aux::vector_tag<3> >
{
    template< typename Vector > struct apply
    {
        typedef vector2<
              typename Vector::item1, typename Vector::item2
            > type;
    };
};

template<>
struct push_back_impl< aux::vector_tag<2> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector3<
              typename Vector::item0, typename Vector::item1
              ,
              T
            > type;
    };
};

template<>
struct pop_back_impl< aux::vector_tag<3> >
{
    template< typename Vector > struct apply
    {
        typedef vector2<
              typename Vector::item0, typename Vector::item1
            > type;
    };
};

namespace aux {
template<> struct v_at_impl<3>
{
    template< typename V_ > struct result_
    {
        typedef typename V_::item3 type;
    };
};

}

template<>
struct at_impl< aux::vector_tag<3> >
{
    template< typename V_, typename N > struct apply
    {
        typedef typename aux::v_at_impl<BOOST_MPL_AUX_VALUE_WKND(N)::value>
            ::template result_<V_>::type type;
    };
};

template<>
struct front_impl< aux::vector_tag<3> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::item0 type;
    };
};

template<>
struct back_impl< aux::vector_tag<3> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::back type;
    };
};

template<>
struct empty_impl< aux::vector_tag<3> >
{
    template< typename Vector > struct apply
        : false_
    {
    };
};

template<>
struct size_impl< aux::vector_tag<3> >
{
    template< typename Vector > struct apply
        : long_<3>
    {
    };
};

template<>
struct O1_size_impl< aux::vector_tag<3> >
    : size_impl< aux::vector_tag<3> >
{
};

template<>
struct clear_impl< aux::vector_tag<3> >
{
    template< typename Vector > struct apply
    {
        typedef vector0<> type;
    };
};

template<
      typename T0, typename T1, typename T2, typename T3
    >
struct vector4
{
    typedef aux::vector_tag<4> tag;
    typedef vector4 type;
    typedef T0 item0;
    typedef T1 item1;
    typedef T2 item2;
    typedef T3 item3;

    typedef void_ item4;
    typedef T3 back;
    typedef v_iter< type,0 > begin;
    typedef v_iter< type,4 > end;
};

template<>
struct push_front_impl< aux::vector_tag<3> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector4<
              T
              ,
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2
            > type;
    };
};

template<>
struct pop_front_impl< aux::vector_tag<4> >
{
    template< typename Vector > struct apply
    {
        typedef vector3<
              typename Vector::item1, typename Vector::item2
            , typename Vector::item3
            > type;
    };
};

template<>
struct push_back_impl< aux::vector_tag<3> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector4<
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2
              ,
              T
            > type;
    };
};

template<>
struct pop_back_impl< aux::vector_tag<4> >
{
    template< typename Vector > struct apply
    {
        typedef vector3<
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2
            > type;
    };
};

namespace aux {
template<> struct v_at_impl<4>
{
    template< typename V_ > struct result_
    {
        typedef typename V_::item4 type;
    };
};

}

template<>
struct at_impl< aux::vector_tag<4> >
{
    template< typename V_, typename N > struct apply
    {
        typedef typename aux::v_at_impl<BOOST_MPL_AUX_VALUE_WKND(N)::value>
            ::template result_<V_>::type type;
    };
};

template<>
struct front_impl< aux::vector_tag<4> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::item0 type;
    };
};

template<>
struct back_impl< aux::vector_tag<4> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::back type;
    };
};

template<>
struct empty_impl< aux::vector_tag<4> >
{
    template< typename Vector > struct apply
        : false_
    {
    };
};

template<>
struct size_impl< aux::vector_tag<4> >
{
    template< typename Vector > struct apply
        : long_<4>
    {
    };
};

template<>
struct O1_size_impl< aux::vector_tag<4> >
    : size_impl< aux::vector_tag<4> >
{
};

template<>
struct clear_impl< aux::vector_tag<4> >
{
    template< typename Vector > struct apply
    {
        typedef vector0<> type;
    };
};

template<
      typename T0, typename T1, typename T2, typename T3, typename T4
    >
struct vector5
{
    typedef aux::vector_tag<5> tag;
    typedef vector5 type;
    typedef T0 item0;
    typedef T1 item1;
    typedef T2 item2;
    typedef T3 item3;
    typedef T4 item4;

    typedef void_ item5;
    typedef T4 back;
    typedef v_iter< type,0 > begin;
    typedef v_iter< type,5 > end;
};

template<>
struct push_front_impl< aux::vector_tag<4> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector5<
              T
              ,
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            > type;
    };
};

template<>
struct pop_front_impl< aux::vector_tag<5> >
{
    template< typename Vector > struct apply
    {
        typedef vector4<
              typename Vector::item1, typename Vector::item2
            , typename Vector::item3, typename Vector::item4
            > type;
    };
};

template<>
struct push_back_impl< aux::vector_tag<4> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector5<
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
              ,
              T
            > type;
    };
};

template<>
struct pop_back_impl< aux::vector_tag<5> >
{
    template< typename Vector > struct apply
    {
        typedef vector4<
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            > type;
    };
};

namespace aux {
template<> struct v_at_impl<5>
{
    template< typename V_ > struct result_
    {
        typedef typename V_::item5 type;
    };
};

}

template<>
struct at_impl< aux::vector_tag<5> >
{
    template< typename V_, typename N > struct apply
    {
        typedef typename aux::v_at_impl<BOOST_MPL_AUX_VALUE_WKND(N)::value>
            ::template result_<V_>::type type;
    };
};

template<>
struct front_impl< aux::vector_tag<5> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::item0 type;
    };
};

template<>
struct back_impl< aux::vector_tag<5> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::back type;
    };
};

template<>
struct empty_impl< aux::vector_tag<5> >
{
    template< typename Vector > struct apply
        : false_
    {
    };
};

template<>
struct size_impl< aux::vector_tag<5> >
{
    template< typename Vector > struct apply
        : long_<5>
    {
    };
};

template<>
struct O1_size_impl< aux::vector_tag<5> >
    : size_impl< aux::vector_tag<5> >
{
};

template<>
struct clear_impl< aux::vector_tag<5> >
{
    template< typename Vector > struct apply
    {
        typedef vector0<> type;
    };
};

template<
      typename T0, typename T1, typename T2, typename T3, typename T4
    , typename T5
    >
struct vector6
{
    typedef aux::vector_tag<6> tag;
    typedef vector6 type;
    typedef T0 item0;
    typedef T1 item1;
    typedef T2 item2;
    typedef T3 item3;
    typedef T4 item4;
    typedef T5 item5;

    typedef void_ item6;
    typedef T5 back;
    typedef v_iter< type,0 > begin;
    typedef v_iter< type,6 > end;
};

template<>
struct push_front_impl< aux::vector_tag<5> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector6<
              T
              ,
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            , typename Vector::item4
            > type;
    };
};

template<>
struct pop_front_impl< aux::vector_tag<6> >
{
    template< typename Vector > struct apply
    {
        typedef vector5<
              typename Vector::item1, typename Vector::item2
            , typename Vector::item3, typename Vector::item4
            , typename Vector::item5
            > type;
    };
};

template<>
struct push_back_impl< aux::vector_tag<5> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector6<
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            , typename Vector::item4
              ,
              T
            > type;
    };
};

template<>
struct pop_back_impl< aux::vector_tag<6> >
{
    template< typename Vector > struct apply
    {
        typedef vector5<
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            , typename Vector::item4
            > type;
    };
};

namespace aux {
template<> struct v_at_impl<6>
{
    template< typename V_ > struct result_
    {
        typedef typename V_::item6 type;
    };
};

}

template<>
struct at_impl< aux::vector_tag<6> >
{
    template< typename V_, typename N > struct apply
    {
        typedef typename aux::v_at_impl<BOOST_MPL_AUX_VALUE_WKND(N)::value>
            ::template result_<V_>::type type;
    };
};

template<>
struct front_impl< aux::vector_tag<6> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::item0 type;
    };
};

template<>
struct back_impl< aux::vector_tag<6> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::back type;
    };
};

template<>
struct empty_impl< aux::vector_tag<6> >
{
    template< typename Vector > struct apply
        : false_
    {
    };
};

template<>
struct size_impl< aux::vector_tag<6> >
{
    template< typename Vector > struct apply
        : long_<6>
    {
    };
};

template<>
struct O1_size_impl< aux::vector_tag<6> >
    : size_impl< aux::vector_tag<6> >
{
};

template<>
struct clear_impl< aux::vector_tag<6> >
{
    template< typename Vector > struct apply
    {
        typedef vector0<> type;
    };
};

template<
      typename T0, typename T1, typename T2, typename T3, typename T4
    , typename T5, typename T6
    >
struct vector7
{
    typedef aux::vector_tag<7> tag;
    typedef vector7 type;
    typedef T0 item0;
    typedef T1 item1;
    typedef T2 item2;
    typedef T3 item3;
    typedef T4 item4;
    typedef T5 item5;
    typedef T6 item6;

    typedef void_ item7;
    typedef T6 back;
    typedef v_iter< type,0 > begin;
    typedef v_iter< type,7 > end;
};

template<>
struct push_front_impl< aux::vector_tag<6> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector7<
              T
              ,
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            , typename Vector::item4, typename Vector::item5
            > type;
    };
};

template<>
struct pop_front_impl< aux::vector_tag<7> >
{
    template< typename Vector > struct apply
    {
        typedef vector6<
              typename Vector::item1, typename Vector::item2
            , typename Vector::item3, typename Vector::item4
            , typename Vector::item5, typename Vector::item6
            > type;
    };
};

template<>
struct push_back_impl< aux::vector_tag<6> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector7<
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            , typename Vector::item4, typename Vector::item5
              ,
              T
            > type;
    };
};

template<>
struct pop_back_impl< aux::vector_tag<7> >
{
    template< typename Vector > struct apply
    {
        typedef vector6<
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            , typename Vector::item4, typename Vector::item5
            > type;
    };
};

namespace aux {
template<> struct v_at_impl<7>
{
    template< typename V_ > struct result_
    {
        typedef typename V_::item7 type;
    };
};

}

template<>
struct at_impl< aux::vector_tag<7> >
{
    template< typename V_, typename N > struct apply
    {
        typedef typename aux::v_at_impl<BOOST_MPL_AUX_VALUE_WKND(N)::value>
            ::template result_<V_>::type type;
    };
};

template<>
struct front_impl< aux::vector_tag<7> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::item0 type;
    };
};

template<>
struct back_impl< aux::vector_tag<7> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::back type;
    };
};

template<>
struct empty_impl< aux::vector_tag<7> >
{
    template< typename Vector > struct apply
        : false_
    {
    };
};

template<>
struct size_impl< aux::vector_tag<7> >
{
    template< typename Vector > struct apply
        : long_<7>
    {
    };
};

template<>
struct O1_size_impl< aux::vector_tag<7> >
    : size_impl< aux::vector_tag<7> >
{
};

template<>
struct clear_impl< aux::vector_tag<7> >
{
    template< typename Vector > struct apply
    {
        typedef vector0<> type;
    };
};

template<
      typename T0, typename T1, typename T2, typename T3, typename T4
    , typename T5, typename T6, typename T7
    >
struct vector8
{
    typedef aux::vector_tag<8> tag;
    typedef vector8 type;
    typedef T0 item0;
    typedef T1 item1;
    typedef T2 item2;
    typedef T3 item3;
    typedef T4 item4;
    typedef T5 item5;
    typedef T6 item6;
    typedef T7 item7;

    typedef void_ item8;
    typedef T7 back;
    typedef v_iter< type,0 > begin;
    typedef v_iter< type,8 > end;
};

template<>
struct push_front_impl< aux::vector_tag<7> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector8<
              T
              ,
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            , typename Vector::item4, typename Vector::item5
            , typename Vector::item6
            > type;
    };
};

template<>
struct pop_front_impl< aux::vector_tag<8> >
{
    template< typename Vector > struct apply
    {
        typedef vector7<
              typename Vector::item1, typename Vector::item2
            , typename Vector::item3, typename Vector::item4
            , typename Vector::item5, typename Vector::item6
            , typename Vector::item7
            > type;
    };
};

template<>
struct push_back_impl< aux::vector_tag<7> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector8<
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            , typename Vector::item4, typename Vector::item5
            , typename Vector::item6
              ,
              T
            > type;
    };
};

template<>
struct pop_back_impl< aux::vector_tag<8> >
{
    template< typename Vector > struct apply
    {
        typedef vector7<
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            , typename Vector::item4, typename Vector::item5
            , typename Vector::item6
            > type;
    };
};

namespace aux {
template<> struct v_at_impl<8>
{
    template< typename V_ > struct result_
    {
        typedef typename V_::item8 type;
    };
};

}

template<>
struct at_impl< aux::vector_tag<8> >
{
    template< typename V_, typename N > struct apply
    {
        typedef typename aux::v_at_impl<BOOST_MPL_AUX_VALUE_WKND(N)::value>
            ::template result_<V_>::type type;
    };
};

template<>
struct front_impl< aux::vector_tag<8> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::item0 type;
    };
};

template<>
struct back_impl< aux::vector_tag<8> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::back type;
    };
};

template<>
struct empty_impl< aux::vector_tag<8> >
{
    template< typename Vector > struct apply
        : false_
    {
    };
};

template<>
struct size_impl< aux::vector_tag<8> >
{
    template< typename Vector > struct apply
        : long_<8>
    {
    };
};

template<>
struct O1_size_impl< aux::vector_tag<8> >
    : size_impl< aux::vector_tag<8> >
{
};

template<>
struct clear_impl< aux::vector_tag<8> >
{
    template< typename Vector > struct apply
    {
        typedef vector0<> type;
    };
};

template<
      typename T0, typename T1, typename T2, typename T3, typename T4
    , typename T5, typename T6, typename T7, typename T8
    >
struct vector9
{
    typedef aux::vector_tag<9> tag;
    typedef vector9 type;
    typedef T0 item0;
    typedef T1 item1;
    typedef T2 item2;
    typedef T3 item3;
    typedef T4 item4;
    typedef T5 item5;
    typedef T6 item6;
    typedef T7 item7;
    typedef T8 item8;

    typedef void_ item9;
    typedef T8 back;
    typedef v_iter< type,0 > begin;
    typedef v_iter< type,9 > end;
};

template<>
struct push_front_impl< aux::vector_tag<8> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector9<
              T
              ,
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            , typename Vector::item4, typename Vector::item5
            , typename Vector::item6, typename Vector::item7
            > type;
    };
};

template<>
struct pop_front_impl< aux::vector_tag<9> >
{
    template< typename Vector > struct apply
    {
        typedef vector8<
              typename Vector::item1, typename Vector::item2
            , typename Vector::item3, typename Vector::item4
            , typename Vector::item5, typename Vector::item6
            , typename Vector::item7, typename Vector::item8
            > type;
    };
};

template<>
struct push_back_impl< aux::vector_tag<8> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector9<
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            , typename Vector::item4, typename Vector::item5
            , typename Vector::item6, typename Vector::item7
              ,
              T
            > type;
    };
};

template<>
struct pop_back_impl< aux::vector_tag<9> >
{
    template< typename Vector > struct apply
    {
        typedef vector8<
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            , typename Vector::item4, typename Vector::item5
            , typename Vector::item6, typename Vector::item7
            > type;
    };
};

namespace aux {
template<> struct v_at_impl<9>
{
    template< typename V_ > struct result_
    {
        typedef typename V_::item9 type;
    };
};

}

template<>
struct at_impl< aux::vector_tag<9> >
{
    template< typename V_, typename N > struct apply
    {
        typedef typename aux::v_at_impl<BOOST_MPL_AUX_VALUE_WKND(N)::value>
            ::template result_<V_>::type type;
    };
};

template<>
struct front_impl< aux::vector_tag<9> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::item0 type;
    };
};

template<>
struct back_impl< aux::vector_tag<9> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::back type;
    };
};

template<>
struct empty_impl< aux::vector_tag<9> >
{
    template< typename Vector > struct apply
        : false_
    {
    };
};

template<>
struct size_impl< aux::vector_tag<9> >
{
    template< typename Vector > struct apply
        : long_<9>
    {
    };
};

template<>
struct O1_size_impl< aux::vector_tag<9> >
    : size_impl< aux::vector_tag<9> >
{
};

template<>
struct clear_impl< aux::vector_tag<9> >
{
    template< typename Vector > struct apply
    {
        typedef vector0<> type;
    };
};

template<
      typename T0, typename T1, typename T2, typename T3, typename T4
    , typename T5, typename T6, typename T7, typename T8, typename T9
    >
struct vector10
{
    typedef aux::vector_tag<10> tag;
    typedef vector10 type;
    typedef T0 item0;
    typedef T1 item1;
    typedef T2 item2;
    typedef T3 item3;
    typedef T4 item4;
    typedef T5 item5;
    typedef T6 item6;
    typedef T7 item7;
    typedef T8 item8;
    typedef T9 item9;

    typedef void_ item10;
    typedef T9 back;
    typedef v_iter< type,0 > begin;
    typedef v_iter< type,10 > end;
};

template<>
struct push_front_impl< aux::vector_tag<9> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector10<
              T
              ,
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            , typename Vector::item4, typename Vector::item5
            , typename Vector::item6, typename Vector::item7
            , typename Vector::item8
            > type;
    };
};

template<>
struct pop_front_impl< aux::vector_tag<10> >
{
    template< typename Vector > struct apply
    {
        typedef vector9<
              typename Vector::item1, typename Vector::item2
            , typename Vector::item3, typename Vector::item4
            , typename Vector::item5, typename Vector::item6
            , typename Vector::item7, typename Vector::item8
            , typename Vector::item9
            > type;
    };
};

template<>
struct push_back_impl< aux::vector_tag<9> >
{
    template< typename Vector, typename T > struct apply
    {
        typedef vector10<
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            , typename Vector::item4, typename Vector::item5
            , typename Vector::item6, typename Vector::item7
            , typename Vector::item8
              ,
              T
            > type;
    };
};

template<>
struct pop_back_impl< aux::vector_tag<10> >
{
    template< typename Vector > struct apply
    {
        typedef vector9<
              typename Vector::item0, typename Vector::item1
            , typename Vector::item2, typename Vector::item3
            , typename Vector::item4, typename Vector::item5
            , typename Vector::item6, typename Vector::item7
            , typename Vector::item8
            > type;
    };
};

namespace aux {
template<> struct v_at_impl<10>
{
    template< typename V_ > struct result_
    {
        typedef typename V_::item10 type;
    };
};

}

template<>
struct at_impl< aux::vector_tag<10> >
{
    template< typename V_, typename N > struct apply
    {
        typedef typename aux::v_at_impl<BOOST_MPL_AUX_VALUE_WKND(N)::value>
            ::template result_<V_>::type type;
    };
};

template<>
struct front_impl< aux::vector_tag<10> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::item0 type;
    };
};

template<>
struct back_impl< aux::vector_tag<10> >
{
    template< typename Vector > struct apply
    {
        typedef typename Vector::back type;
    };
};

template<>
struct empty_impl< aux::vector_tag<10> >
{
    template< typename Vector > struct apply
        : false_
    {
    };
};

template<>
struct size_impl< aux::vector_tag<10> >
{
    template< typename Vector > struct apply
        : long_<10>
    {
    };
};

template<>
struct O1_size_impl< aux::vector_tag<10> >
    : size_impl< aux::vector_tag<10> >
{
};

template<>
struct clear_impl< aux::vector_tag<10> >
{
    template< typename Vector > struct apply
    {
        typedef vector0<> type;
    };
};

}}


code:
// Copyright Aleksey Gurtovoy 2001-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)
//

// *Preprocessed* version of the main "inherit.hpp" header
// -- DO NOT modify by hand!

namespace boost { namespace mpl {

template<
      typename BOOST_MPL_AUX_NA_PARAM(T1)
    , typename BOOST_MPL_AUX_NA_PARAM(T2)
    >
struct inherit2
    : T1, T2
{
    typedef inherit2 type;
    BOOST_MPL_AUX_LAMBDA_SUPPORT(2, inherit2, (T1, T2))
};

template< typename T1 >
struct inherit2< T1,empty_base >
{
    typedef T1 type;
    BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (T1, empty_base))
};

template< typename T2 >
struct inherit2< empty_base,T2 >
{
    typedef T2 type;
    BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, T2))
};

template<>
struct inherit2< empty_base,empty_base >
{
    typedef empty_base type;
    BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2, inherit2, (empty_base, empty_base))
};

BOOST_MPL_AUX_NA_SPEC(2, inherit2)

template<
      typename T1 = na, typename T2 = na, typename T3 = na
    >
struct inherit3
    : inherit2<
          typename inherit2<
              T1, T2
            >::type
        , T3
        >
{
    BOOST_MPL_AUX_LAMBDA_SUPPORT(
          3
        , inherit3
        , ( T1, T2, T3)
        )
};

BOOST_MPL_AUX_NA_SPEC(3, inherit3)

template<
      typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na
    >
struct inherit4
    : inherit2<
          typename inherit3<
              T1, T2, T3
            >::type
        , T4
        >
{
    BOOST_MPL_AUX_LAMBDA_SUPPORT(
          4
        , inherit4
        , ( T1, T2, T3, T4)
        )
};

BOOST_MPL_AUX_NA_SPEC(4, inherit4)

template<
      typename T1 = na, typename T2 = na, typename T3 = na, typename T4 = na
    , typename T5 = na
    >
struct inherit5
    : inherit2<
          typename inherit4<
              T1, T2, T3, T4
            >::type
        , T5
        >
{
    BOOST_MPL_AUX_LAMBDA_SUPPORT(
          5
        , inherit5
        , ( T1, T2, T3, T4, T5)
        )
};

BOOST_MPL_AUX_NA_SPEC(5, inherit5)

/// primary template

template<
      typename T1 = empty_base, typename T2 = empty_base
    , typename T3 = empty_base, typename T4 = empty_base
    , typename T5 = empty_base
    >
struct inherit
    : inherit5< T1,T2,T3,T4,T5 >
{
};

template<>
struct inherit< na,na,na,na,na >
{
    template<

          typename T1, typename T2, typename T3, typename T4, typename T5

        >
    struct apply
        : inherit< T1,T2,T3,T4,T5 >
    {
    };
};

BOOST_MPL_AUX_NA_SPEC_LAMBDA(5, inherit)
BOOST_MPL_AUX_NA_SPEC_ARITY(5, inherit)
BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(5, 5, inherit)
}}


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) */
# /* Revised by Edward Diener (2011) */
#
# /* See http://www.boost.org for most recent version. */
#
# ifndef BOOST_PREPROCESSOR_CONFIG_LIMITS_HPP
# define BOOST_PREPROCESSOR_CONFIG_LIMITS_HPP
#
# define BOOST_PP_LIMIT_MAG 256
# define BOOST_PP_LIMIT_TUPLE 64
# define BOOST_PP_LIMIT_DIM 3
# define BOOST_PP_LIMIT_REPEAT 256
# define BOOST_PP_LIMIT_WHILE 256
# define BOOST_PP_LIMIT_FOR 256
# define BOOST_PP_LIMIT_ITERATION 256
# define BOOST_PP_LIMIT_ITERATION_DIM 3
# define BOOST_PP_LIMIT_SEQ 256
# define BOOST_PP_LIMIT_SLOT_SIG 10
# define BOOST_PP_LIMIT_SLOT_COUNT 5
#
# endif


code:
// Copyright Aleksey Gurtovoy 2000-2004
// Copyright Jaap Suter 2003
//
// 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)
//

// Preprocessed version of "boost/mpl/bitxor.hpp" header
// -- DO NOT modify by hand!

namespace boost { namespace mpl {

template<
      typename Tag1
    , typename Tag2
    >
struct bitxor_impl
    : if_c<
          ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1)
              > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2)
            )

        , aux::cast2nd_impl< bitxor_impl< Tag1,Tag1 >,Tag1, Tag2 >
        , aux::cast1st_impl< bitxor_impl< Tag2,Tag2 >,Tag1, Tag2 >
        >::type
{
};

/// for Digital Mars C++/compilers with no CTPS/TTP support
template<> struct bitxor_impl< na,na >
{
    template< typename U1, typename U2 > struct apply
    {
        typedef apply type;
        BOOST_STATIC_CONSTANT(int, value  = 0);
    };
};

template< typename Tag > struct bitxor_impl< na,Tag >
{
    template< typename U1, typename U2 > struct apply
    {
        typedef apply type;
        BOOST_STATIC_CONSTANT(int, value  = 0);
    };
};

template< typename Tag > struct bitxor_impl< Tag,na >
{
    template< typename U1, typename U2 > struct apply
    {
        typedef apply type;
        BOOST_STATIC_CONSTANT(int, value  = 0);
    };
};

template< typename T > struct bitxor_tag
{
    typedef typename T::tag type;
};

template<
      typename BOOST_MPL_AUX_NA_PARAM(N1)
    , typename BOOST_MPL_AUX_NA_PARAM(N2)
    , typename N3 = na, typename N4 = na, typename N5 = na
    >
struct bitxor_
    : bitxor_< bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4>, N5>
{
};

template<
      typename N1, typename N2, typename N3, typename N4
    >
struct bitxor_< N1,N2,N3,N4,na >

    : bitxor_< bitxor_< bitxor_< N1,N2 >, N3>, N4>
{
    BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(
          5
        , bitxor_
        , ( N1, N2, N3, N4, na )
        )
};

template<
      typename N1, typename N2, typename N3
    >
struct bitxor_< N1,N2,N3,na,na >

    : bitxor_< bitxor_< N1,N2 >, N3>
{
    BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(
          5
        , bitxor_
        , ( N1, N2, N3, na, na )
        )
};

template<
      typename N1, typename N2
    >
struct bitxor_< N1,N2,na,na,na >
    : bitxor_impl<
          typename bitxor_tag<N1>::type
        , typename bitxor_tag<N2>::type
        >::template apply< N1,N2 >::type
{
    BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(
          5
        , bitxor_
        , ( N1, N2, na, na, na )
        )

};

BOOST_MPL_AUX_NA_SPEC2(2, 5, bitxor_)

}}

namespace boost { namespace mpl {
template<>
struct bitxor_impl< integral_c_tag,integral_c_tag >
{
    template< typename N1, typename N2 > struct apply

        : integral_c<
              typename aux::largest_int<
                  typename N1::value_type
                , typename N2::value_type
                >::type
            , ( BOOST_MPL_AUX_VALUE_WKND(N1)::value
                  ^ BOOST_MPL_AUX_VALUE_WKND(N2)::value
                )
            >
    {
    };
};

}}


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_LIST_FILTER_HPP
# define BOOST_PREPROCESSOR_LIST_FILTER_HPP
#
# include <boost/preprocessor/config/config.hpp>
# include <boost/preprocessor/control/if.hpp>
# include <boost/preprocessor/list/fold_right.hpp>
# include <boost/preprocessor/tuple/elem.hpp>
# include <boost/preprocessor/tuple/rem.hpp>
#
# /* BOOST_PP_LIST_FILTER */
#
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
#    define BOOST_PP_LIST_FILTER(pred, data, list) BOOST_PP_TUPLE_ELEM(3, 2, BOOST_PP_LIST_FOLD_RIGHT(BOOST_PP_LIST_FILTER_O, (pred, data, BOOST_PP_NIL), list))
# else
#    define BOOST_PP_LIST_FILTER(pred, data, list) BOOST_PP_LIST_FILTER_I(pred, data, list)
#    define BOOST_PP_LIST_FILTER_I(pred, data, list) BOOST_PP_TUPLE_ELEM(3, 2, BOOST_PP_LIST_FOLD_RIGHT(BOOST_PP_LIST_FILTER_O, (pred, data, BOOST_PP_NIL), list))
# endif
#
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
#    define BOOST_PP_LIST_FILTER_O(d, pdr, elem) BOOST_PP_LIST_FILTER_O_D(d, BOOST_PP_TUPLE_ELEM(3, 0, pdr), BOOST_PP_TUPLE_ELEM(3, 1, pdr), BOOST_PP_TUPLE_ELEM(3, 2, pdr), elem)
# else
#    define BOOST_PP_LIST_FILTER_O(d, pdr, elem) BOOST_PP_LIST_FILTER_O_I(d, BOOST_PP_TUPLE_REM_3 pdr, elem)
#    define BOOST_PP_LIST_FILTER_O_I(d, im, elem) BOOST_PP_LIST_FILTER_O_D(d, im, elem)
# endif
#
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC()
#    define BOOST_PP_LIST_FILTER_O_D(d, pred, data, res, elem) (pred, data, BOOST_PP_IF(pred(d, data, elem), (elem, res), res))
# else
#    define BOOST_PP_LIST_FILTER_O_D(d, pred, data, res, elem) (pred, data, BOOST_PP_IF(pred##(d, data, elem), (elem, res), res))
# endif
#
# /* BOOST_PP_LIST_FILTER_D */
#
# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
#    define BOOST_PP_LIST_FILTER_D(d, pred, data, list) BOOST_PP_TUPLE_ELEM(3, 2, BOOST_PP_LIST_FOLD_RIGHT_ ## d(BOOST_PP_LIST_FILTER_O, (pred, data, BOOST_PP_NIL), list))
# else
#    define BOOST_PP_LIST_FILTER_D(d, pred, data, list) BOOST_PP_LIST_FILTER_D_I(d, pred, data, list)
#    define BOOST_PP_LIST_FILTER_D_I(d, pred, data, list) BOOST_PP_TUPLE_ELEM(3, 2, BOOST_PP_LIST_FOLD_RIGHT_ ## d(BOOST_PP_LIST_FILTER_O, (pred, data, BOOST_PP_NIL), list))
# endif
#
# endif


code:
#include "ForeignKeyDelegate.hpp"

#include <QComboBox>

#include "CandidateKeyFilter.hpp"

ForeignKeyDelegate::ForeignKeyDelegate (QAbstractItemModel * referenced_model
                                        , int referenced_key_column
                                        , QObject * parent
                                        , int referenced_key_role)
  : QStyledItemDelegate {parent}
  , candidate_key_filter_ {new CandidateKeyFilter {referenced_model, referenced_key_column, nullptr, referenced_key_role}}
{
}

ForeignKeyDelegate::ForeignKeyDelegate (QAbstractItemModel * referenced_model
                                        , QAbstractItemModel const * referencing_model
                                        , int referenced_key_column
                                        , int referencing_key_column
                                        , QObject * parent
                                        , int referenced_key_role
                                        , int referencing_key_role)
  : QStyledItemDelegate {parent}
  , candidate_key_filter_ {new CandidateKeyFilter {referenced_model, referencing_model, referenced_key_column, referencing_key_column, nullptr, referenced_key_role, referencing_key_role}}
{
}

ForeignKeyDelegate::~ForeignKeyDelegate ()
{
}

QWidget * ForeignKeyDelegate::createEditor (QWidget * parent
                                            , QStyleOptionViewItem const& /* option */
                                            , QModelIndex const& index) const
{
  auto editor = new QComboBox {parent};
  editor->setFrame (false);
  candidate_key_filter_->set_active_key (index);
  editor->setModel (candidate_key_filter_.data ());
  return editor;
}


code:
#ifndef BOOST_MPL_VOID_HPP_INCLUDED
#define BOOST_MPL_VOID_HPP_INCLUDED

// Copyright Aleksey Gurtovoy 2001-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$

#include <boost/mpl/void_fwd.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/aux_/na_spec.hpp>
#include <boost/mpl/aux_/config/msvc.hpp>
#include <boost/mpl/aux_/config/workaround.hpp>

BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN

//  [JDG Feb-4-2003] made void_ a complete type to allow it to be
//  instantiated so that it can be passed in as an object that can be
//  used to select an overloaded function. Possible use includes signaling
//  a zero arity functor evaluation call.
struct void_ { typedef void_ type; };

BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE

namespace boost { namespace mpl {

template< typename T >
struct is_void_
    : false_
{
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
    using false_::value;
#endif
};

template<>
struct is_void_<void_>
    : true_
{
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
    using true_::value;
#endif
};

template< typename T >
struct is_not_void_
    : true_
{
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
    using true_::value;
#endif
};

template<>
struct is_not_void_<void_>
    : false_
{
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
    using false_::value;
#endif
};

BOOST_MPL_AUX_NA_SPEC(1, is_void_)
BOOST_MPL_AUX_NA_SPEC(1, is_not_void_)

}}

#endif // BOOST_MPL_VOID_HPP_INCLUDED


code:
#ifndef BOOST_MPL_AUX_HAS_TAG_HPP_INCLUDED
#define BOOST_MPL_AUX_HAS_TAG_HPP_INCLUDED

// Copyright Aleksey Gurtovoy 2002-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$

#include <boost/mpl/has_xxx.hpp>

namespace boost { namespace mpl { namespace aux {
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_tag, tag, false)
}}}

#endif // BOOST_MPL_AUX_HAS_TAG_HPP_INCLUDED