text:
/*=============================================================================
    Phoenix V1.2.1
    Copyright (c) 2001-2003 Joel de Guzman
    Copyright (c) 2001-2003 Hartmut Kaiser

  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_SPIRIT_CLASSIC_PHOENIX_CASTS_HPP
#define BOOST_SPIRIT_CLASSIC_PHOENIX_CASTS_HPP

///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/phoenix/actor.hpp>
#include <boost/spirit/home/classic/phoenix/composite.hpp>
#include <boost/static_assert.hpp>

///////////////////////////////////////////////////////////////////////////////
namespace phoenix {

///////////////////////////////////////////////////////////////////////////////
//
//  Phoenix predefined maximum construct_ limit. This limit defines the maximum
//  number of parameters supported for calles to the set of construct_ template
//  functions (lazy object construction, see below). This number defaults to 3.
//  The actual maximum is rounded up in multiples of 3. Thus, if this value
//  is 4, the actual limit is 6. The ultimate maximum limit in this
//  implementation is 15.
//  PHOENIX_CONSTRUCT_LIMIT should NOT be greater than PHOENIX_LIMIT!

#if !defined(PHOENIX_CONSTRUCT_LIMIT)
#define PHOENIX_CONSTRUCT_LIMIT PHOENIX_LIMIT
#endif

// ensure PHOENIX_CONSTRUCT_LIMIT <= PHOENIX_LIMIT
BOOST_STATIC_ASSERT(PHOENIX_CONSTRUCT_LIMIT <= PHOENIX_LIMIT);

// ensure PHOENIX_CONSTRUCT_LIMIT <= 15
BOOST_STATIC_ASSERT(PHOENIX_CONSTRUCT_LIMIT <= 15);

///////////////////////////////////////////////////////////////////////////////
//
//  Lazy C++ casts
//
//      The set of lazy C++ cast template classes and functions provide a way
//      of lazily casting certain type to another during parsing.
//      The lazy C++ templates are (syntactically) used very much like
//      the well known C++ casts:
//
//          A *a = static_cast_<A *>(...actor returning a convertible type...);
//
//      where the given parameter should be an actor, which eval() function
//      returns a convertible type.
//
///////////////////////////////////////////////////////////////////////////////
template <typename T, typename A>
struct static_cast_l {

    template <typename TupleT>
    struct result { typedef T type; };

    static_cast_l(A const& a_)
    :   a(a_) {}

    template <typename TupleT>
    T
    eval(TupleT const& args) const
    {
        return static_cast<T>(a.eval(args));
    }

    A a;
};

//////////////////////////////////
template <typename T, typename BaseAT>
inline actor<static_cast_l<T, BaseAT> >
static_cast_(actor<BaseAT> const& a)
{
    typedef static_cast_l<T, BaseAT> cast_t;
    return actor<cast_t>(cast_t(a));
}

//////////////////////////////////
template <typename T, typename A>
struct dynamic_cast_l {

    template <typename TupleT>
    struct result { typedef T type; };

    dynamic_cast_l(A const& a_)
    :   a(a_) {}

    template <typename TupleT>
    T
    eval(TupleT const& args) const
    {
        return dynamic_cast<T>(a.eval(args));
    }

    A a;
};

//////////////////////////////////
template <typename T, typename BaseAT>
inline actor<dynamic_cast_l<T, BaseAT> >
dynamic_cast_(actor<BaseAT> const& a)
{
    typedef dynamic_cast_l<T, BaseAT> cast_t;
    return actor<cast_t>(cast_t(a));
}

//////////////////////////////////
template <typename T, typename A>
struct reinterpret_cast_l {

    template <typename TupleT>
    struct result { typedef T type; };

    reinterpret_cast_l(A const& a_)
    :   a(a_) {}

    template <typename TupleT>
    T
    eval(TupleT const& args) const
    {
        return reinterpret_cast<T>(a.eval(args));
    }

    A a;
};

//////////////////////////////////
template <typename T, typename BaseAT>
inline actor<reinterpret_cast_l<T, BaseAT> >
reinterpret_cast_(actor<BaseAT> const& a)
{
    typedef reinterpret_cast_l<T, BaseAT> cast_t;
    return actor<cast_t>(cast_t(a));
}

//////////////////////////////////
template <typename T, typename A>
struct const_cast_l {

    template <typename TupleT>
    struct result { typedef T type; };

    const_cast_l(A const& a_)
    :   a(a_) {}

    template <typename TupleT>
    T
    eval(TupleT const& args) const
    {
        return const_cast<T>(a.eval(args));
    }

    A a;
};

//////////////////////////////////
template <typename T, typename BaseAT>
inline actor<const_cast_l<T, BaseAT> >
const_cast_(actor<BaseAT> const& a)
{
    typedef const_cast_l<T, BaseAT> cast_t;
    return actor<cast_t>(cast_t(a));
}

///////////////////////////////////////////////////////////////////////////////
//
//  construct_
//
//      Lazy object construction
//
//      The set of construct_<> template classes and functions provide a way
//      of lazily constructing certain object from a arbitrary set of
//      actors during parsing.
//      The construct_ templates are (syntactically) used very much like
//      the well known C++ casts:
//
//          A a = construct_<A>(...arbitrary list of actors...);
//
//      where the given parameters are submitted as parameters to the
//      constructor of the object of type A. (This certainly implies, that
//      type A has a constructor with a fitting set of parameter types
//      defined.)
//
//      The maximum number of needed parameters is controlled through the
//      preprocessor constant PHOENIX_CONSTRUCT_LIMIT. Note though, that this
//      limit should not be greater than PHOENIX_LIMIT.
//
///////////////////////////////////////////////////////////////////////////////
template <typename T>
struct construct_l_0 {
    typedef T result_type;

    T operator()() const {
        return T();
    }
};

template <typename T>
struct construct_l {

    template <
            typename A
        ,   typename B
        ,   typename C

#if PHOENIX_CONSTRUCT_LIMIT > 3
        ,   typename D
        ,   typename E
        ,   typename F

#if PHOENIX_CONSTRUCT_LIMIT > 6
        ,   typename G
        ,   typename H
        ,   typename I

#if PHOENIX_CONSTRUCT_LIMIT > 9
        ,   typename J
        ,   typename K
        ,   typename L

#if PHOENIX_CONSTRUCT_LIMIT > 12
        ,   typename M
        ,   typename N
        ,   typename O
#endif
#endif
#endif
#endif
    >
    struct result { typedef T type; };

    T operator()() const
    {
        return T();
    }

    template <typename A>
    T operator()(A const& a) const
    {
        T t(a);
        return t;
    }

    template <typename A, typename B>
    T operator()(A const& a, B const& b) const
    {
        T t(a, b);
        return t;
    }

    template <typename A, typename B, typename C>
    T operator()(A const& a, B const& b, C const& c) const
    {
        T t(a, b, c);
        return t;
    }

#if PHOENIX_CONSTRUCT_LIMIT > 3
    template <
        typename A, typename B, typename C, typename D
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d) const
    {
        T t(a, b, c, d);
        return t;
    }

    template <
        typename A, typename B, typename C, typename D, typename E
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e) const
    {
        T t(a, b, c, d, e);
        return t;
    }

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f) const
    {
        T t(a, b, c, d, e, f);
        return t;
    }

#if PHOENIX_CONSTRUCT_LIMIT > 6
    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g) const
    {
        T t(a, b, c, d, e, f, g);
        return t;
    }

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h) const
    {
        T t(a, b, c, d, e, f, g, h);
        return t;
    }

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H, typename I
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h, I const& i) const
    {
        T t(a, b, c, d, e, f, g, h, i);
        return t;
    }

#if PHOENIX_CONSTRUCT_LIMIT > 9
    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H, typename I, typename J
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h, I const& i, J const& j) const
    {
        T t(a, b, c, d, e, f, g, h, i, j);
        return t;
    }

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H, typename I, typename J,
        typename K
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h, I const& i, J const& j,
        K const& k) const
    {
        T t(a, b, c, d, e, f, g, h, i, j, k);
        return t;
    }

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H, typename I, typename J,
        typename K, typename L
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h, I const& i, J const& j,
        K const& k, L const& l) const
    {
        T t(a, b, c, d, e, f, g, h, i, j, k, l);
        return t;
    }

#if PHOENIX_CONSTRUCT_LIMIT > 12
    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H, typename I, typename J,
        typename K, typename L, typename M
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h, I const& i, J const& j,
        K const& k, L const& l, M const& m) const
    {
        T t(a, b, c, d, e, f, g, h, i, j, k, l, m);
        return t;
    }

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H, typename I, typename J,
        typename K, typename L, typename M, typename N
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h, I const& i, J const& j,
        K const& k, L const& l, M const& m, N const& n) const
    {
        T t(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
        return t;
    }

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H, typename I, typename J,
        typename K, typename L, typename M, typename N, typename O
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h, I const& i, J const& j,
        K const& k, L const& l, M const& m, N const& n, O const& o) const
    {
        T t(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);
        return t;
    }

#endif
#endif
#endif
#endif
};

template <typename T>
struct construct_1 {

    template <
            typename A
    >
    struct result { typedef T type; };

    template <typename A>
    T operator()(A const& a) const
    {
        T t(a);
        return t;
    }

};

template <typename T>
struct construct_2 {

    template <
            typename A
        ,   typename B
    >
    struct result { typedef T type; };

    template <typename A, typename B>
    T operator()(A const& a, B const& b) const
    {
        T t(a, b);
        return t;
    }

};

template <typename T>
struct construct_3 {

    template <
            typename A
        ,   typename B
        ,   typename C
    >
    struct result { typedef T type; };

    template <typename A, typename B, typename C>
    T operator()(A const& a, B const& b, C const& c) const
    {
        T t(a, b, c);
        return t;
    }
};

#if PHOENIX_CONSTRUCT_LIMIT > 3
template <typename T>
struct construct_4 {

    template <
            typename A
        ,   typename B
        ,   typename C
        ,   typename D
    >
    struct result { typedef T type; };

    template <
        typename A, typename B, typename C, typename D
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d) const
    {
        T t(a, b, c, d);
        return t;
    }
};

template <typename T>
struct construct_5 {

    template <
            typename A
        ,   typename B
        ,   typename C
        ,   typename D
        ,   typename E
    >
    struct result { typedef T type; };

    template <
        typename A, typename B, typename C, typename D, typename E
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e) const
    {
        T t(a, b, c, d, e);
        return t;
    }
};

template <typename T>
struct construct_6 {

    template <
            typename A
        ,   typename B
        ,   typename C
        ,   typename D
        ,   typename E
        ,   typename F
    >
    struct result { typedef T type; };

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f) const
    {
        T t(a, b, c, d, e, f);
        return t;
    }
};
#endif

#if PHOENIX_CONSTRUCT_LIMIT > 6
template <typename T>
struct construct_7 {

    template <
            typename A
        ,   typename B
        ,   typename C
        ,   typename D
        ,   typename E
        ,   typename F
        ,   typename G
    >
    struct result { typedef T type; };

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g) const
    {
        T t(a, b, c, d, e, f, g);
        return t;
    }
};

template <typename T>
struct construct_8 {

    template <
            typename A
        ,   typename B
        ,   typename C
        ,   typename D
        ,   typename E
        ,   typename F
        ,   typename G
        ,   typename H
    >
    struct result { typedef T type; };

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h) const
    {
        T t(a, b, c, d, e, f, g, h);
        return t;
    }
};

template <typename T>
struct construct_9 {

    template <
            typename A
        ,   typename B
        ,   typename C
        ,   typename D
        ,   typename E
        ,   typename F
        ,   typename G
        ,   typename H
        ,   typename I
    >
    struct result { typedef T type; };

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H, typename I
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h, I const& i) const
    {
        T t(a, b, c, d, e, f, g, h, i);
        return t;
    }
};
#endif

#if PHOENIX_CONSTRUCT_LIMIT > 9
template <typename T>
struct construct_10 {

    template <
            typename A
        ,   typename B
        ,   typename C
        ,   typename D
        ,   typename E
        ,   typename F
        ,   typename G
        ,   typename H
        ,   typename I
        ,   typename J
    >
    struct result { typedef T type; };

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H, typename I, typename J
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h, I const& i, J const& j) const
    {
        T t(a, b, c, d, e, f, g, h, i, j);
        return t;
    }
};

template <typename T>
struct construct_11 {

    template <
            typename A
        ,   typename B
        ,   typename C
        ,   typename D
        ,   typename E
        ,   typename F
        ,   typename G
        ,   typename H
        ,   typename I
        ,   typename J
        ,   typename K
    >
    struct result { typedef T type; };

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H, typename I, typename J,
        typename K
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h, I const& i, J const& j,
        K const& k) const
    {
        T t(a, b, c, d, e, f, g, h, i, j, k);
        return t;
    }
};

template <typename T>
struct construct_12 {

    template <
            typename A
        ,   typename B
        ,   typename C
        ,   typename D
        ,   typename E
        ,   typename F
        ,   typename G
        ,   typename H
        ,   typename I
        ,   typename J
        ,   typename K
        ,   typename L
    >
    struct result { typedef T type; };

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H, typename I, typename J,
        typename K, typename L
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h, I const& i, J const& j,
        K const& k, L const& l) const
    {
        T t(a, b, c, d, f, e, g, h, i, j, k, l);
        return t;
    }
};
#endif

#if PHOENIX_CONSTRUCT_LIMIT > 12
template <typename T>
struct construct_13 {

    template <
            typename A
        ,   typename B
        ,   typename C
        ,   typename D
        ,   typename E
        ,   typename F
        ,   typename G
        ,   typename H
        ,   typename I
        ,   typename J
        ,   typename K
        ,   typename L
        ,   typename M
    >
    struct result { typedef T type; };

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H, typename I, typename J,
        typename K, typename L, typename M
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h, I const& i, J const& j,
        K const& k, L const& l, M const& m) const
    {
        T t(a, b, c, d, e, f, g, h, i, j, k, l, m);
        return t;
    }
};

template <typename T>
struct construct_14 {

    template <
            typename A
        ,   typename B
        ,   typename C
        ,   typename D
        ,   typename E
        ,   typename F
        ,   typename G
        ,   typename H
        ,   typename I
        ,   typename J
        ,   typename K
        ,   typename L
        ,   typename M
        ,   typename N
    >
    struct result { typedef T type; };

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H, typename I, typename J,
        typename K, typename L, typename M, typename N
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h, I const& i, J const& j,
        K const& k, L const& l, M const& m, N const& n) const
    {
        T t(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
        return t;
    }
};

template <typename T>
struct construct_15 {

    template <
            typename A
        ,   typename B
        ,   typename C
        ,   typename D
        ,   typename E
        ,   typename F
        ,   typename G
        ,   typename H
        ,   typename I
        ,   typename J
        ,   typename K
        ,   typename L
        ,   typename M
        ,   typename N
        ,   typename O
    >
    struct result { typedef T type; };

    template <
        typename A, typename B, typename C, typename D, typename E,
        typename F, typename G, typename H, typename I, typename J,
        typename K, typename L, typename M, typename N, typename O
    >
    T operator()(
        A const& a, B const& b, C const& c, D const& d, E const& e,
        F const& f, G const& g, H const& h, I const& i, J const& j,
        K const& k, L const& l, M const& m, N const& n, O const& o) const
    {
        T t(a, b, c, d, f, e, g, h, i, j, k, l, m, n, o);
        return t;
    }
};
#endif

#if defined(BOOST_BORLANDC) || (defined(__MWERKS__) && (__MWERKS__ <= 0x3002))

///////////////////////////////////////////////////////////////////////////////
//
//  The following specializations are needed because Borland and CodeWarrior
//  does not accept default template arguments in nested template classes in
//  classes (i.e construct_l::result)
//
///////////////////////////////////////////////////////////////////////////////
template <typename T, typename TupleT>
struct composite0_result<construct_l_0<T>, TupleT> {

    typedef T type;
};

//////////////////////////////////
template <typename T, typename TupleT,
    typename A>
struct composite1_result<construct_l<T>, TupleT, A> {

    typedef T type;
};

//////////////////////////////////
template <typename T, typename TupleT,
    typename A, typename B>
struct composite2_result<construct_l<T>, TupleT, A, B> {

    typedef T type;
};

//////////////////////////////////
template <typename T, typename TupleT,
    typename A, typename B, typename C>
struct composite3_result<construct_l<T>, TupleT, A, B, C> {

    typedef T type;
};

#if PHOENIX_LIMIT > 3
//////////////////////////////////
template <typename T, typename TupleT,
    typename A, typename B, typename C, typename D>
struct composite4_result<construct_l<T>, TupleT,
    A, B, C, D> {

    typedef T type;
};

//////////////////////////////////
template <typename T, typename TupleT,
    typename A, typename B, typename C, typename D, typename E>
struct composite5_result<construct_l<T>, TupleT,
    A, B, C, D, E> {

    typedef T type;
};

//////////////////////////////////
template <typename T, typename TupleT,
    typename A, typename B, typename C, typename D, typename E,
    typename F>
struct composite6_result<construct_l<T>, TupleT,
    A, B, C, D, E, F> {

    typedef T type;
};

#if PHOENIX_LIMIT > 6
//////////////////////////////////
template <typename T, typename TupleT,
    typename A, typename B, typename C, typename D, typename E,
    typename F, typename G>
struct composite7_result<construct_l<T>, TupleT,
    A, B, C, D, E, F, G> {

    typedef T type;
};

//////////////////////////////////
template <typename T, typename TupleT,
    typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H>
struct composite8_result<construct_l<T>, TupleT,
    A, B, C, D, E, F, G, H> {

    typedef T type;
};

//////////////////////////////////
template <typename T, typename TupleT,
    typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H, typename I>
struct composite9_result<construct_l<T>, TupleT,
    A, B, C, D, E, F, G, H, I> {

    typedef T type;
};

#if PHOENIX_LIMIT > 9
//////////////////////////////////
template <typename T, typename TupleT,
    typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H, typename I, typename J>
struct composite10_result<construct_l<T>, TupleT,
    A, B, C, D, E, F, G, H, I, J> {

    typedef T type;
};

//////////////////////////////////
template <typename T, typename TupleT,
    typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H, typename I, typename J,
    typename K>
struct composite11_result<construct_l<T>, TupleT,
    A, B, C, D, E, F, G, H, I, J, K> {

    typedef T type;
};

//////////////////////////////////
template <typename T, typename TupleT,
    typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H, typename I, typename J,
    typename K, typename L>
struct composite12_result<construct_l<T>, TupleT,
    A, B, C, D, E, F, G, H, I, J, K, L> {

    typedef T type;
};

#if PHOENIX_LIMIT > 12
//////////////////////////////////
template <typename T, typename TupleT,
    typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H, typename I, typename J,
    typename K, typename L, typename M>
struct composite13_result<construct_l<T>, TupleT,
    A, B, C, D, E, F, G, H, I, J, K, L, M> {

    typedef T type;
};

//////////////////////////////////
template <typename T, typename TupleT,
    typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H, typename I, typename J,
    typename K, typename L, typename M, typename N>
struct composite14_result<construct_l<T>, TupleT,
    A, B, C, D, E, F, G, H, I, J, K, L, M, N> {

    typedef T type;
};

//////////////////////////////////
template <typename T, typename TupleT,
    typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H, typename I, typename J,
    typename K, typename L, typename M, typename N, typename O>
struct composite15_result<construct_l<T>, TupleT,
    A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> {

    typedef T type;
};

#endif
#endif
#endif
#endif
#endif

//////////////////////////////////
template <typename T>
inline typename impl::make_composite<construct_l_0<T> >::type
construct_()
{
    typedef impl::make_composite<construct_l_0<T> > make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_l_0<T>()));
}

//////////////////////////////////
template <typename T, typename A>
inline typename impl::make_composite<construct_1<T>, A>::type
construct_(A const& a)
{
    typedef impl::make_composite<construct_1<T>, A> make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_1<T>(),
        as_actor<A>::convert(a)
    ));
}

//////////////////////////////////
template <typename T, typename A, typename B>
inline typename impl::make_composite<construct_2<T>, A, B>::type
construct_(A const& a, B const& b)
{
    typedef impl::make_composite<construct_2<T>, A, B> make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_2<T>(),
        as_actor<A>::convert(a),
        as_actor<B>::convert(b)
    ));
}

//////////////////////////////////
template <typename T, typename A, typename B, typename C>
inline typename impl::make_composite<construct_3<T>, A, B, C>::type
construct_(A const& a, B const& b, C const& c)
{
    typedef impl::make_composite<construct_3<T>, A, B, C> make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_3<T>(),
        as_actor<A>::convert(a),
        as_actor<B>::convert(b),
        as_actor<C>::convert(c)
    ));
}

#if PHOENIX_CONSTRUCT_LIMIT > 3
//////////////////////////////////
template <
    typename T, typename A, typename B, typename C, typename D
>
inline typename impl::make_composite<construct_4<T>, A, B, C, D>::type
construct_(
    A const& a, B const& b, C const& c, D const& d)
{
    typedef
        impl::make_composite<construct_4<T>, A, B, C, D>
        make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_4<T>(),
        as_actor<A>::convert(a),
        as_actor<B>::convert(b),
        as_actor<C>::convert(c),
        as_actor<D>::convert(d)
    ));
}

//////////////////////////////////
template <
    typename T, typename A, typename B, typename C, typename D, typename E
>
inline typename impl::make_composite<construct_5<T>, A, B, C, D, E>::type
construct_(
    A const& a, B const& b, C const& c, D const& d, E const& e)
{
    typedef
        impl::make_composite<construct_5<T>, A, B, C, D, E>
        make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_5<T>(),
        as_actor<A>::convert(a),
        as_actor<B>::convert(b),
        as_actor<C>::convert(c),
        as_actor<D>::convert(d),
        as_actor<E>::convert(e)
    ));
}

//////////////////////////////////
template <
    typename T, typename A, typename B, typename C, typename D, typename E,
    typename F
>
inline typename impl::make_composite<construct_6<T>, A, B, C, D, E, F>::type
construct_(
    A const& a, B const& b, C const& c, D const& d, E const& e,
    F const& f)
{
    typedef
        impl::make_composite<construct_6<T>, A, B, C, D, E, F>
        make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_6<T>(),
        as_actor<A>::convert(a),
        as_actor<B>::convert(b),
        as_actor<C>::convert(c),
        as_actor<D>::convert(d),
        as_actor<E>::convert(e),
        as_actor<F>::convert(f)
    ));
}

#if PHOENIX_CONSTRUCT_LIMIT > 6
//////////////////////////////////
template <
    typename T, typename A, typename B, typename C, typename D, typename E,
    typename F, typename G
>
inline typename impl::make_composite<construct_7<T>, A, B, C, D, E, F, G>::type
construct_(
    A const& a, B const& b, C const& c, D const& d, E const& e,
    F const& f, G const& g)
{
    typedef
        impl::make_composite<construct_7<T>, A, B, C, D, E, F, G>
        make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_7<T>(),
        as_actor<A>::convert(a),
        as_actor<B>::convert(b),
        as_actor<C>::convert(c),
        as_actor<D>::convert(d),
        as_actor<E>::convert(e),
        as_actor<F>::convert(f),
        as_actor<G>::convert(g)
    ));
}

//////////////////////////////////
template <
    typename T, typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H
>
inline typename impl::make_composite<construct_8<T>, A, B, C, D, E, F, G, H>::type
construct_(
    A const& a, B const& b, C const& c, D const& d, E const& e,
    F const& f, G const& g, H const& h)
{
    typedef
        impl::make_composite<construct_8<T>, A, B, C, D, E, F, G, H>
        make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_8<T>(),
        as_actor<A>::convert(a),
        as_actor<B>::convert(b),
        as_actor<C>::convert(c),
        as_actor<D>::convert(d),
        as_actor<E>::convert(e),
        as_actor<F>::convert(f),
        as_actor<G>::convert(g),
        as_actor<H>::convert(h)
    ));
}

//////////////////////////////////
template <
    typename T, typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H, typename I
>
inline typename impl::make_composite<construct_9<T>, A, B, C, D, E, F, G, H, I>::type
construct_(
    A const& a, B const& b, C const& c, D const& d, E const& e,
    F const& f, G const& g, H const& h, I const& i)
{
    typedef
        impl::make_composite<construct_9<T>, A, B, C, D, E, F, G, H, I>
        make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_9<T>(),
        as_actor<A>::convert(a),
        as_actor<B>::convert(b),
        as_actor<C>::convert(c),
        as_actor<D>::convert(d),
        as_actor<E>::convert(e),
        as_actor<F>::convert(f),
        as_actor<G>::convert(g),
        as_actor<H>::convert(h),
        as_actor<I>::convert(i)
    ));
}

#if PHOENIX_CONSTRUCT_LIMIT > 9
//////////////////////////////////
template <
    typename T, typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H, typename I, typename J
>
inline typename impl::make_composite<
    construct_10<T>, A, B, C, D, E, F, G, H, I, J>::type
construct_(
    A const& a, B const& b, C const& c, D const& d, E const& e,
    F const& f, G const& g, H const& h, I const& i, J const& j)
{
    typedef
        impl::make_composite<
            construct_10<T>, A, B, C, D, E, F, G, H, I, J
        >
        make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_10<T>(),
        as_actor<A>::convert(a),
        as_actor<B>::convert(b),
        as_actor<C>::convert(c),
        as_actor<D>::convert(d),
        as_actor<E>::convert(e),
        as_actor<F>::convert(f),
        as_actor<G>::convert(g),
        as_actor<H>::convert(h),
        as_actor<I>::convert(i),
        as_actor<J>::convert(j)
    ));
}

//////////////////////////////////
template <
    typename T, typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H, typename I, typename J, typename K
>
inline typename impl::make_composite<
    construct_11<T>, A, B, C, D, E, F, G, H, I, J, K>::type
construct_(
    A const& a, B const& b, C const& c, D const& d, E const& e,
    F const& f, G const& g, H const& h, I const& i, J const& j,
    K const& k)
{
    typedef
        impl::make_composite<
            construct_11<T>, A, B, C, D, E, F, G, H, I, J, K
        >
        make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_11<T>(),
        as_actor<A>::convert(a),
        as_actor<B>::convert(b),
        as_actor<C>::convert(c),
        as_actor<D>::convert(d),
        as_actor<E>::convert(e),
        as_actor<F>::convert(f),
        as_actor<G>::convert(g),
        as_actor<H>::convert(h),
        as_actor<I>::convert(i),
        as_actor<J>::convert(j),
        as_actor<K>::convert(k)
    ));
}

//////////////////////////////////
template <
    typename T, typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H, typename I, typename J, typename K,
    typename L
>
inline typename impl::make_composite<
    construct_12<T>, A, B, C, D, E, F, G, H, I, J, K, L>::type
construct_(
    A const& a, B const& b, C const& c, D const& d, E const& e,
    F const& f, G const& g, H const& h, I const& i, J const& j,
    K const& k, L const& l)
{
    typedef
        impl::make_composite<
            construct_12<T>, A, B, C, D, E, F, G, H, I, J, K, L
        >
        make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_12<T>(),
        as_actor<A>::convert(a),
        as_actor<B>::convert(b),
        as_actor<C>::convert(c),
        as_actor<D>::convert(d),
        as_actor<E>::convert(e),
        as_actor<F>::convert(f),
        as_actor<G>::convert(g),
        as_actor<H>::convert(h),
        as_actor<I>::convert(i),
        as_actor<J>::convert(j),
        as_actor<K>::convert(k),
        as_actor<L>::convert(l)
    ));
}

#if PHOENIX_CONSTRUCT_LIMIT > 12
//////////////////////////////////
template <
    typename T, typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H, typename I, typename J, typename K,
    typename L, typename M
>
inline typename impl::make_composite<
    construct_13<T>, A, B, C, D, E, F, G, H, I, J, K, L, M>::type
construct_(
    A const& a, B const& b, C const& c, D const& d, E const& e,
    F const& f, G const& g, H const& h, I const& i, J const& j,
    K const& k, L const& l, M const& m)
{
    typedef
        impl::make_composite<
            construct_13<T>, A, B, C, D, E, F, G, H, I, J, K, L, M
        >
        make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_13<T>(),
        as_actor<A>::convert(a),
        as_actor<B>::convert(b),
        as_actor<C>::convert(c),
        as_actor<D>::convert(d),
        as_actor<E>::convert(e),
        as_actor<F>::convert(f),
        as_actor<G>::convert(g),
        as_actor<H>::convert(h),
        as_actor<I>::convert(i),
        as_actor<J>::convert(j),
        as_actor<K>::convert(k),
        as_actor<L>::convert(l),
        as_actor<M>::convert(m)
    ));
}

//////////////////////////////////
template <
    typename T, typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H, typename I, typename J, typename K,
    typename L, typename M, typename N
>
inline typename impl::make_composite<
    construct_14<T>, A, B, C, D, E, F, G, H, I, J, K, L, M>::type
construct_(
    A const& a, B const& b, C const& c, D const& d, E const& e,
    F const& f, G const& g, H const& h, I const& i, J const& j,
    K const& k, L const& l, M const& m, N const& n)
{
    typedef
        impl::make_composite<
            construct_14<T>, A, B, C, D, E, F, G, H, I, J, K, L, M, N
        >
        make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_14<T>(),
        as_actor<A>::convert(a),
        as_actor<B>::convert(b),
        as_actor<C>::convert(c),
        as_actor<D>::convert(d),
        as_actor<E>::convert(e),
        as_actor<F>::convert(f),
        as_actor<G>::convert(g),
        as_actor<H>::convert(h),
        as_actor<I>::convert(i),
        as_actor<J>::convert(j),
        as_actor<K>::convert(k),
        as_actor<L>::convert(l),
        as_actor<M>::convert(m),
        as_actor<N>::convert(n)
    ));
}

//////////////////////////////////
template <
    typename T, typename A, typename B, typename C, typename D, typename E,
    typename F, typename G, typename H, typename I, typename J, typename K,
    typename L, typename M, typename N, typename O
>
inline typename impl::make_composite<
    construct_15<T>, A, B, C, D, E, F, G, H, I, J, K, L, M, O>::type
construct_(
    A const& a, B const& b, C const& c, D const& d, E const& e,
    F const& f, G const& g, H const& h, I const& i, J const& j,
    K const& k, L const& l, M const& m, N const& n, O const& o)
{
    typedef
        impl::make_composite<
            construct_15<T>, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O
        >
        make_composite_t;
    typedef typename make_composite_t::type type_t;
    typedef typename make_composite_t::composite_type composite_type_t;

    return type_t(composite_type_t(construct_15<T>(),
        as_actor<A>::convert(a),
        as_actor<B>::convert(b),
        as_actor<C>::convert(c),
        as_actor<D>::convert(d),
        as_actor<E>::convert(e),
        as_actor<F>::convert(f),
        as_actor<G>::convert(g),
        as_actor<H>::convert(h),
        as_actor<I>::convert(i),
        as_actor<J>::convert(j),
        as_actor<K>::convert(k),
        as_actor<L>::convert(l),
        as_actor<M>::convert(m),
        as_actor<N>::convert(n),
        as_actor<O>::convert(o)
    ));
}

#endif
#endif
#endif
#endif

///////////////////////////////////////////////////////////////////////////////
}   //  namespace phoenix

#endif


text:
/*
    Copyright (c) 2014, Philipp Krähenbühl
    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
        * Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
        * Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
        * Neither the name of the Stanford University nor the
        names of its contributors may be used to endorse or promote products
        derived from this software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY Philipp Krähenbühl ''AS IS'' AND ANY
    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL Philipp Krähenbühl BE LIABLE FOR ANY
    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
	 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
	 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
	 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "segmentation/segmentation.h"
#include "proposals/seed.h"
#include "proposals/proposal.h"
#include "proposals/geodesics.h"
#include "proposals/unary.h"
#include "proposals/saliency.h"
#include "gop.h"
#include "util.h"
#include "map.h"
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

static void LearnedSeed_train1( LearnedSeed & that, const std::vector< std::shared_ptr<ImageOverSegmentation> > & ios, const list & lbl, int max_seed ) {
	// Load the data
	std::vector<VectorXs> v_lbl;
	if( ios.size() != len(lbl) )
		throw std::invalid_argument("gops and lbls size does not match!");
	for( int i=0; i<len(lbl); i++ )
		v_lbl.push_back( mapVectorX<short>(extract<np::ndarray>(lbl[i])) );
	that.train( ios, v_lbl, max_seed );
}
static void LearnedSeed_train2( LearnedSeed & that, const std::vector< std::shared_ptr<ImageOverSegmentation> > & ios, const list & lbl, int max_seed, int n_seed_per_obj ) {
	// Load the data
	std::vector<VectorXs> v_lbl;
	if( ios.size() != len(lbl) )
		throw std::invalid_argument("gops and lbls size does not match!");
	for( int i=0; i<len(lbl); i++ )
		v_lbl.push_back( mapVectorX<short>(extract<np::ndarray>(lbl[i])) );
	that.train( ios, v_lbl, max_seed, n_seed_per_obj );
}
static np::ndarray Unary_compute( const Unary & that, int seed ) {
	return toNumpy( that.compute( seed ) );
}
static ProposalSettings::UnarySettings* make_UnarySettings1( int n_seed ) {
	return new ProposalSettings::UnarySettings( n_seed );
}
static ProposalSettings::UnarySettings* make_UnarySettings2( int n_seed, int n_lvl_set ) {
	return new ProposalSettings::UnarySettings( n_seed, n_lvl_set );
}
static ProposalSettings::UnarySettings* make_UnarySettings3( int n_seed, int n_lvl_set, std::shared_ptr<UnaryFactory> fg_unary ) {
	return new ProposalSettings::UnarySettings( n_seed, n_lvl_set, fg_unary );
}
static ProposalSettings::UnarySettings* make_UnarySettings4( int n_seed, int n_lvl_set, std::shared_ptr<UnaryFactory> fg_unary, list background_seeds ) {
	return new ProposalSettings::UnarySettings( n_seed, n_lvl_set, fg_unary, backgroundUnary( to_vector<int>( background_seeds ) ) );
}
static ProposalSettings::UnarySettings* make_UnarySettings5( int n_seed, int n_lvl_set, std::shared_ptr<UnaryFactory> fg_unary, list background_seeds, float min_size ) {
	return new ProposalSettings::UnarySettings( n_seed, n_lvl_set, fg_unary, backgroundUnary( to_vector<int>( background_seeds ) ), min_size );
}
static ProposalSettings::UnarySettings* make_UnarySettings6( int n_seed, int n_lvl_set, std::shared_ptr<UnaryFactory> fg_unary, list background_seeds, float min_size, float max_size ) {
	return new ProposalSettings::UnarySettings( n_seed, n_lvl_set, fg_unary, backgroundUnary( to_vector<int>( background_seeds ) ), min_size, max_size );
}
static ProposalSettings::UnarySettings* make_UnarySettings7( int n_seed, int n_lvl_set, std::shared_ptr<UnaryFactory> fg_unary, std::shared_ptr<UnaryFactory> bg_unary ) {
	return new ProposalSettings::UnarySettings( n_seed, n_lvl_set, fg_unary, bg_unary );
}
static ProposalSettings::UnarySettings* make_UnarySettings8( int n_seed, int n_lvl_set, std::shared_ptr<UnaryFactory> fg_unary, std::shared_ptr<UnaryFactory> bg_unary, float min_size ) {
	return new ProposalSettings::UnarySettings( n_seed, n_lvl_set, fg_unary, bg_unary, min_size );
}
static ProposalSettings::UnarySettings* make_UnarySettings9( int n_seed, int n_lvl_set, std::shared_ptr<UnaryFactory> fg_unary, std::shared_ptr<UnaryFactory> bg_unary, float min_size, float max_size ) {
	return new ProposalSettings::UnarySettings( n_seed, n_lvl_set, fg_unary, bg_unary, min_size, max_size );
}
static void ProposalSettings_set_foreground_seeds( ProposalSettings & that, const SeedFunction & f ) {
	that.foreground_seeds = f.clone();
}
static np::ndarray Salienct_saliency( const Saliency & sal, const ImageOverSegmentation & ios ) {
	return toNumpy( sal.saliency( ios ) );
}

void defineProposals() {
	ADD_MODULE(proposals);

	//***** Seeds *****//
	class_< SeedFunction, std::shared_ptr<SeedFunction>, boost::noncopyable >( "SeedFunction", no_init )
	.def("compute", &SeedFunction::compute);
	class_< ImageSeedFunction, std::shared_ptr<ImageSeedFunction>, bases<SeedFunction>, boost::noncopyable >( "ImageSeedFunction", no_init );
	class_< RegularSeed, std::shared_ptr<RegularSeed>, bases<ImageSeedFunction> >( "RegularSeed" );
	class_< GeodesicSeed, std::shared_ptr<GeodesicSeed>, bases<SeedFunction> >( "GeodesicSeed" )
	.def(init<float>())
	.def(init<float,float>())
	.def(init<float,float,float>())
	.def_pickle(SaveLoad_pickle_suite<GeodesicSeed>());
	class_< RandomSeed, std::shared_ptr<RandomSeed>, bases<SeedFunction> >( "RandomSeed" )
	.def_pickle(SaveLoad_pickle_suite<RandomSeed>());
	class_< SaliencySeed, std::shared_ptr<SaliencySeed>, bases<SeedFunction> >( "SaliencySeed" )
	.def_pickle(SaveLoad_pickle_suite<SaliencySeed>());
	class_< SegmentationSeed, std::shared_ptr<SegmentationSeed>, bases<SeedFunction> >( "SegmentationSeed" )
	.def_pickle(SaveLoad_pickle_suite<SegmentationSeed>());
	class_< LearnedSeed, std::shared_ptr<LearnedSeed>, bases<SeedFunction> >("LearnedSeed")
	.def( "train", &LearnedSeed_train1 )
	.def( "train", &LearnedSeed_train2 )
	.def( "load", static_cast<void(LearnedSeed::*)(const std::string &)>(&LearnedSeed::load) )
	.def( "save", static_cast<void(LearnedSeed::*)(const std::string &)const>(&LearnedSeed::save) )
	.def_pickle(SaveLoad_pickle_suite<LearnedSeed>());

	//***** Unaries *****//
	class_<UnaryFactory,std::shared_ptr<UnaryFactory>,boost::noncopyable>("UnaryFactory",no_init)
	.def("create",&UnaryFactory::create);

	class_<ProposalSettings::UnarySettings>("UnarySettings")
	.def("__init__",make_constructor(&make_UnarySettings1))
	.def("__init__",make_constructor(&make_UnarySettings2))
	.def("__init__",make_constructor(&make_UnarySettings3))
	.def("__init__",make_constructor(&make_UnarySettings4))
	.def("__init__",make_constructor(&make_UnarySettings5))
	.def("__init__",make_constructor(&make_UnarySettings6))
	.def("__init__",make_constructor(&make_UnarySettings7))
	.def("__init__",make_constructor(&make_UnarySettings8))
	.def("__init__",make_constructor(&make_UnarySettings9))
	.def_readwrite("fg_unary",&ProposalSettings::UnarySettings::fg_unary)
	.def_readwrite("bg_unary",&ProposalSettings::UnarySettings::bg_unary)
	.def_readwrite("edge_weight",&ProposalSettings::UnarySettings::edge_weight)
	.def_readwrite("n_seed",&ProposalSettings::UnarySettings::n_seed)
	.def_readwrite("n_lvl_set",&ProposalSettings::UnarySettings::n_lvl_set)
	.def_readwrite("min_size",&ProposalSettings::UnarySettings::min_size)
	.def_readwrite("max_size",&ProposalSettings::UnarySettings::max_size);

	class_< std::vector<ProposalSettings::UnarySettings> >("UnarySettingsVec")
	.def(vector_indexing_suite<std::vector<ProposalSettings::UnarySettings> >());

	class_<ProposalSettings>("ProposalSettings")
	.add_property("foreground_seeds",make_getter(&ProposalSettings::foreground_seeds),ProposalSettings_set_foreground_seeds)
// 	.def_readwrite("foreground_seeds",&ProposalSettings::foreground_seeds)
	.def_readwrite("unaries",&ProposalSettings::unaries)
	.def_readwrite("max_iou",&ProposalSettings::max_iou);

	class_<Proposal>("Proposal",init<ProposalSettings>())
	.def("propose",&Proposal::propose);

	class_<GeodesicDistance>("GeodesicDistance",init<OverSegmentation>())
	.def("compute",static_cast<VectorXf (GeodesicDistance::*)(int)const>( &GeodesicDistance::compute ))
	.def("compute",static_cast<VectorXf (GeodesicDistance::*)(const VectorXf &)const>( &GeodesicDistance::compute ))
	.add_property("N",&GeodesicDistance::N);

	class_<Unary,std::shared_ptr<Unary>,boost::noncopyable>("Unary",no_init)
	.def( "compute", Unary_compute );

	def("seedUnary",&seedUnary);
	def("rgbUnary",&rgbUnary);
	def("labUnary",&labUnary);
	def("zeroUnary",&zeroUnary);
	def("learnedUnary",static_cast<std::shared_ptr<UnaryFactory>(*)(const FeatureSet &,const VectorXf &, float)>(&learnedUnary));
	def("learnedUnary",static_cast<std::shared_ptr<UnaryFactory>(*)(const VectorXf &, float)>(&learnedUnary));
	def("learnedUnary",static_cast<std::shared_ptr<UnaryFactory>(*)(const std::string &)>(&learnedUnary));
	def("binaryLearnedUnary",static_cast<std::shared_ptr<UnaryFactory>(*)(const FeatureSet &,const VectorXf &, float)>(&binaryLearnedUnary));
	def("binaryLearnedUnary",static_cast<std::shared_ptr<UnaryFactory>(*)(const VectorXf &, float)>(&binaryLearnedUnary));
	def("binaryLearnedUnary",static_cast<std::shared_ptr<UnaryFactory>(*)(const std::string &)>(&binaryLearnedUnary));
	def("saveLearnedUnary",&saveLearnedUnary);

	class_<FeatureSet>("FeatureSet")
	.def("add",static_cast<void (FeatureSet::*)( const FeatureType & )>(&FeatureSet::add))
	.def("add",static_cast<void (FeatureSet::*)( const FeatureSet & )>(&FeatureSet::add))
	.def("has",&FeatureSet::has)
	.def("remove",&FeatureSet::remove)
	.def_pickle(SaveLoad_pickle_suite<FeatureSet>());

	def("defaultUnaryFeatures",defaultUnaryFeatures);

	class_<UnaryFeature,std::shared_ptr<UnaryFeature>,boost::noncopyable>("UnaryFeature",no_init)
	.def( "compute", static_cast<RMatrixXf (UnaryFeature::*)(int)const>(&UnaryFeature::compute) )
	.def( "featureId", &UnaryFeature::featureId )
	.def( "dim", &UnaryFeature::dim )
	.def( "N", &UnaryFeature::N )
	.add_static_property("Constant",make_getter(UnaryFeature::Constant))
	.add_static_property("Indicator",make_getter(UnaryFeature::Indicator))
	.add_static_property("InverseIndicator",make_getter(UnaryFeature::InverseIndicator))
	.add_static_property("Position",make_getter(UnaryFeature::Position))
	.add_static_property("RGB",make_getter(UnaryFeature::RGB))
	.add_static_property("Lab",make_getter(UnaryFeature::Lab))
	.add_static_property("RGBHistogram",make_getter(UnaryFeature::RGBHistogram))
	.add_static_property("LabHistogram",make_getter(UnaryFeature::LabHistogram))
	.add_static_property("BoundaryIndicator",make_getter(UnaryFeature::BoundaryIndicator))
	.add_static_property("BoundaryID",make_getter(UnaryFeature::BoundaryID))
	.add_static_property("BoundaryDistance",make_getter(UnaryFeature::BoundaryDistance));

	class_<UnaryFeatures>("UnaryFeatures",init<ImageOverSegmentation>())
	.def(init<ImageOverSegmentation,FeatureSet>())
	.def("subset", &UnaryFeatures::subset )
	.def("get", &UnaryFeatures::get )
	.def("dim", &UnaryFeatures::dim )
	.def("compute", &UnaryFeatures::compute );

	// Unary Learning
	class_<Saliency>("Saliency")
	.def("saliency",Salienct_saliency);
}

ext: cpp

max_stars_repo_name: PingCheng-Wei/SD-MaskRCNN

max_issues_repo_name: PingCheng-Wei/SD-MaskRCNN

max_forks_repo_name: PingCheng-Wei/SD-MaskRCNN


text:
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
#include "biharmonic_coordinates.h"
#include "cotmatrix.h"
#include "massmatrix.h"
#include "min_quad_with_fixed.h"
#include "normal_derivative.h"
#include "on_boundary.h"
#include <Eigen/Sparse>

template <
  typename DerivedV,
  typename DerivedT,
  typename SType,
  typename DerivedW>
IGL_INLINE bool igl::biharmonic_coordinates(
  const Eigen::PlainObjectBase<DerivedV> & V,
  const Eigen::PlainObjectBase<DerivedT> & T,
  const std::vector<std::vector<SType> > & S,
  Eigen::PlainObjectBase<DerivedW> & W)
{
  return biharmonic_coordinates(V,T,S,2,W);
}

template <
  typename DerivedV,
  typename DerivedT,
  typename SType,
  typename DerivedW>
IGL_INLINE bool igl::biharmonic_coordinates(
  const Eigen::PlainObjectBase<DerivedV> & V,
  const Eigen::PlainObjectBase<DerivedT> & T,
  const std::vector<std::vector<SType> > & S,
  const int k,
  Eigen::PlainObjectBase<DerivedW> & W)
{
  using namespace Eigen;
  using namespace std;
  // This is not the most efficient way to build A, but follows "Linear
  // Subspace Design for Real-Time Shape Deformation" [Wang et al. 2015].
  SparseMatrix<double> A;
  {
    SparseMatrix<double> N,Z,L,K,M;
    normal_derivative(V,T,N);
    Array<bool,Dynamic,1> I;
    Array<bool,Dynamic,Dynamic> C;
    on_boundary(T,I,C);
    {
      std::vector<Triplet<double> >ZIJV;
      for(int t =0;t<T.rows();t++)
      {
        for(int f =0;f<T.cols();f++)
        {
          if(C(t,f))
          {
            const int i = t+f*T.rows();
            for(int c = 1;c<T.cols();c++)
            {
              ZIJV.emplace_back(T(t,(f+c)%T.cols()),i,1);
            }
          }
        }
      }
      Z.resize(V.rows(),N.rows());
      Z.setFromTriplets(ZIJV.begin(),ZIJV.end());
      N = (Z*N).eval();
    }
    cotmatrix(V,T,L);
    K = N+L;
    massmatrix(V,T,MASSMATRIX_TYPE_DEFAULT,M);
    // normalize
    M /= ((VectorXd)M.diagonal()).array().abs().maxCoeff();
    DiagonalMatrix<double,Dynamic> Minv =
      ((VectorXd)M.diagonal().array().inverse()).asDiagonal();
    switch(k)
    {
      default:
        assert(false && "unsupported");
      case 2:
        // For C1 smoothness in 2D, one should use bi-harmonic
        A = K.transpose() * (Minv * K);
        break;
      case 3:
        // For C1 smoothness in 3D, one should use tri-harmonic
        A = K.transpose() * (Minv * (-L * (Minv * K)));
        break;
    }
  }
  // Vertices in point handles
  const size_t mp =
    count_if(S.begin(),S.end(),[](const vector<int> & h){return h.size()==1;});
  // number of region handles
  const size_t r = S.size()-mp;
  // Vertices in region handles
  size_t mr = 0;
  for(const auto & h : S)
  {
    if(h.size() > 1)
    {
      mr += h.size();
    }
  }
  const size_t dim = T.cols()-1;
  // Might as well be dense... I think...
  MatrixXd J = MatrixXd::Zero(mp+mr,mp+r*(dim+1));
  VectorXi b(mp+mr);
  MatrixXd H(mp+r*(dim+1),dim);
  {
    int v = 0;
    int c = 0;
    for(int h = 0;h<S.size();h++)
    {
      if(S[h].size()==1)
      {
        H.row(c) = V.block(S[h][0],0,1,dim);
        J(v,c++) = 1;
        b(v) = S[h][0];
        v++;
      }else
      {
        assert(S[h].size() >= dim+1);
        for(int p = 0;p<S[h].size();p++)
        {
          for(int d = 0;d<dim;d++)
          {
            J(v,c+d) = V(S[h][p],d);
          }
          J(v,c+dim) = 1;
          b(v) = S[h][p];
          v++;
        }
        H.block(c,0,dim+1,dim).setIdentity();
        c+=dim+1;
      }
    }
  }
  // minimize    ½ W' A W'
  // subject to  W(b,:) = J
  return min_quad_with_fixed(
    A,VectorXd::Zero(A.rows()).eval(),b,J,SparseMatrix<double>(),VectorXd(),true,W);
}

#ifdef IGL_STATIC_LIBRARY
// Explicit template specialization
template bool igl::biharmonic_coordinates<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, int, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
#endif

max_stars_repo_name: FabianRepository/SinusProject

max_issues_repo_name: FabianRepository/SinusProject

max_forks_repo_name: FabianRepository/SinusProject


text:
#include "CmrDataReader.h"
#include "Implement/LogUserImpl.h"

#include <sstream>
#include <iostream>
#include <boost\assign\list_of.hpp>
#include <iomanip>
#include <fstream>

using namespace Yap;
using namespace std;
using boost::assign::list_of;

namespace Yap
{
	namespace details
	{

		/// This structure is used to store version info and sizes of all sections.
		struct EcnuRawSections
		{
			double  FileVersion;
			int  Section1Size;
			int  Section2Size;
			int  Section3Size;
			int  Section4Size;
		};

	}
}

CmrDataReader::CmrDataReader(void) :
	ProcessorImpl(L"CmrDataReader")
{
	AddInput(L"Input", 0, DataTypeUnknown);
	AddOutput(L"Output", YAP_ANY_DIMENSION, DataTypeComplexFloat);

	AddProperty<std::wstring> (L"DataPath", L"", L"包含原始数据文件的文件夹。");
	AddProperty<int>(L"ChannelCount", 4, L"通道数");
	AddProperty<int>(L"ChannelSwitch", 0xf, L"通道开关指示值"); // 00001111, select all four channels.
	AddProperty<int>(L"GroupCount", 1, L"分组扫描数");
}

CmrDataReader::CmrDataReader(const CmrDataReader& rhs)
	: ProcessorImpl(rhs)
{
}

CmrDataReader::~CmrDataReader()
{
}

bool CmrDataReader::Input(const wchar_t * name, IData * data)
{
	// Should not pass in data to start raw data file reading.
	assert(data == nullptr);

	int channel_count = GetProperty<int>(L"ChannelCount");
	assert(channel_count > 0 && channel_count <= 32);
	for (int channel_index = 0; channel_index < channel_count; ++channel_index)
	{
		unsigned int channel_mask = (1 << channel_index); // 每次循环都和0或，得到某通道0001(1),0010(2),0100(4),1000(8)
		bool channel_used = ((channel_mask & GetProperty<int>(L"ChannelSwitch")) == channel_mask);    // channel_mask只要和给的通道一样，就必定等于channel_mask自己

		if (channel_used)
		{
 			if (!ReadRawData(channel_index))
 			{
 				return false;
 			}
		}
	}
	return true;
}

bool CmrDataReader::ReadRawData(unsigned int channel_index)
{
	std::wostringstream output;
	output << GetProperty<std::wstring>(L"DataPath") << L"\\ChannelData"
		<< setfill(L'0') << setw(2) << channel_index + 1 << L".fid";

	std::vector<float*> channel_data_buffer;
	std::vector<unsigned int> slices;
	unsigned int width = 0, height = 0, dim4 = 0, total_slice_count = 0; // 对于未进行累加处理的数据，得到的slice实际是 真实的slice  × 实际累加次数。
	int group_count = GetProperty<int>(L"GroupCount");
	if (group_count == 0)
	{
		group_count = 1;
	}

	for (int i = 0; i < group_count; ++i)
	{
		wstring data_path = output.str();
		if (group_count > 1)
		{
			wostringstream temp_output;
			temp_output << L"." << group_count << L"." << i + 1;

			data_path += temp_output.str();
		}

		unsigned int group_slice_count = 0;
		float * temp_raw_data_buffer = ReadEcnuFile(data_path.c_str(), width, height, group_slice_count, dim4);
		if (temp_raw_data_buffer == nullptr)
		{
			return false;
		}
		channel_data_buffer.push_back(temp_raw_data_buffer);
		total_slice_count += group_slice_count;
		slices.push_back(group_slice_count);
	}

	float* raw_data_buffer = nullptr;
	if (channel_data_buffer.size() == 1)
	{
		raw_data_buffer = channel_data_buffer[0];
	}
	else
	{
		try
		{
			raw_data_buffer = new float[width * height * total_slice_count * 2];
		}
		catch(bad_alloc&)
		{
			return false;
		}

		unsigned int offset = 0;
		for (unsigned int i = 0; i < channel_data_buffer.size(); ++i)
		{
			std::memcpy(raw_data_buffer + offset, channel_data_buffer[i], width * height * slices[i] * 2 * sizeof(float));
			offset += width * height * slices[i] * 2;
		}
	}

	Dimensions dimensions;
	dimensions(DimensionReadout, 0U, width)
		(DimensionPhaseEncoding, 0U, height)
		(DimensionSlice, 0U, total_slice_count)
		(Dimension4, 0U, dim4)
		(DimensionChannel, channel_index, 1);

	auto output_data = CreateData<complex<float>>(nullptr,
		reinterpret_cast<complex<float>*>(raw_data_buffer), dimensions);

	Feed(L"Output", output_data.get());

	return true;
}

/**
Read raw data from raw data file.
@return Pointer to the buffer used to store the raw-data. Should be released by the caller of this function.
@param width Output parameter used to store the width of the image (in pixel).
@param height Output, height of the image.
@param slices Output, number of slices read.
*/
float* CmrDataReader::ReadEcnuFile(const wchar_t * file_path,
	unsigned int& width,
	unsigned int& height,
	unsigned int& slices,
	unsigned int& dim4)
{
	ifstream file(file_path, ios::binary);

	// read raw data header
	details::EcnuRawSections sections;
	if (!file.read(reinterpret_cast<char*>(&sections), sizeof(details::EcnuRawSections)))
		return nullptr;

	// read dimension information
	file.seekg(sizeof(details::EcnuRawSections) + sections.Section1Size + sections.Section2Size + sections.Section3Size,
		ios::beg);

	// Version 1.5701001以上版本, 允许浮点误差
	if (sections.FileVersion - 1.5701 > 0.00000005)
	{
		int buf[5];
		file.read(reinterpret_cast<char*>(buf), sizeof(int) * 5);
		assert(buf[4] == 1);
		width = buf[0];
		height = buf[1];
		slices = buf[2] * buf[3];
		dim4 = buf[3];
	}
	else
	{
		// 1.5702版本以上的谱仪版本，数据增加到5维，目前暂时第5维为1.
		int buf[4];
		file.read(reinterpret_cast<char*>(buf), sizeof(int) * 4);
		width = buf[0];
		height = buf[1];
		slices = buf[2] * buf[3];
		dim4 = buf[3];
	}

	unsigned buffer_size = width * height * 2 * slices;
	float * data = new float[buffer_size];

	// read actual data
	if (file.read(reinterpret_cast<char*>(data), buffer_size * sizeof(float)))
	{
		return data;
	}
	else
	{
		delete[]data;
		return nullptr;
	}
}

max_stars_repo_name: PengJinFa/YAPNew

max_issues_repo_name: PengJinFa/YAPNew

max_forks_repo_name: PengJinFa/YAPNew


text:
// Copyright (c) 2005, Rodrigo Braz Monteiro
// Copyright (c) 2010, Thomas Goyne <plorkyeran@aegisub.org>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Aegisub Group nor the names of its contributors
//     may be used to endorse or promote products derived from this software
//     without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Aegisub Project http://www.aegisub.org/

/// @file ass_override.cpp
/// @brief Parse and modify ASSA style overrides
/// @ingroup subs_storage
///

#include "config.h"

#include "ass_dialogue.h"

#include "utils.h"

#include <libaegisub/color.h>

#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/format.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <functional>

using namespace boost::adaptors;

AssOverrideParameter::AssOverrideParameter(VariableDataType type, AssParameterClass classification)
: type(type)
, classification(classification)
{
}

AssOverrideParameter::AssOverrideParameter(AssOverrideParameter&& o)
: value(std::move(o.value))
, block(std::move(o.block))
, type(o.type)
, classification(o.classification)
, omitted(o.omitted)
{
}

AssOverrideParameter& AssOverrideParameter::operator=(AssOverrideParameter&& rhs) {
	value = std::move(rhs.value);
	block = std::move(rhs.block);
	type = rhs.type;
	classification = rhs.classification;
	return *this;
}

AssOverrideParameter::~AssOverrideParameter() {
}

template<> std::string AssOverrideParameter::Get<std::string>() const {
	if (omitted) throw agi::InternalError("AssOverrideParameter::Get() called on omitted parameter", nullptr);
	if (block.get()) {
		std::string str(block->GetText());
		if (boost::starts_with(str, "{")) str.erase(begin(str));
		if (boost::ends_with(str, "}")) str.erase(end(str) - 1);
		return str;
	}
	return value;
}

template<> int AssOverrideParameter::Get<int>() const {
	if (classification == AssParameterClass::ALPHA)
		// &Hxx&, but vsfilter lets you leave everything out
		return mid<int>(0, strtol(std::find_if(value.c_str(), value.c_str() + value.size(), isxdigit), nullptr, 16), 255);
	return atoi(Get<std::string>().c_str());
}

template<> double AssOverrideParameter::Get<double>() const {
	return atof(Get<std::string>().c_str());
}

template<> float AssOverrideParameter::Get<float>() const {
	return atof(Get<std::string>().c_str());
}

template<> bool AssOverrideParameter::Get<bool>() const {
	return Get<int>() != 0;
}

template<> agi::Color AssOverrideParameter::Get<agi::Color>() const {
	return Get<std::string>();
}

template<> AssDialogueBlockOverride *AssOverrideParameter::Get<AssDialogueBlockOverride*>() const {
	if (!block.get()) {
		block.reset(new AssDialogueBlockOverride(Get<std::string>()));
		block->ParseTags();
	}
	return block.get();
}

template<> void AssOverrideParameter::Set<std::string>(std::string new_value) {
	omitted = false;
	value = new_value;
	block.reset();
}

template<> void AssOverrideParameter::Set<int>(int new_value) {
	if (classification == AssParameterClass::ALPHA)
		Set(str(boost::format("&H%02X&") % mid(0, new_value, 255)));
	else
		Set(std::to_string(new_value));
}

template<> void AssOverrideParameter::Set<double>(double new_value) {
	Set(std::to_string(new_value));
}

template<> void AssOverrideParameter::Set<bool>(bool new_value) {
	Set<int>(new_value);
}

namespace {
/// The parameter is absent unless the total number of parameters is the
/// indicated number. Note that only arguments not at the end need to be marked
/// as optional; this is just to know which parameters to skip when there are
/// earlier optional arguments
enum AssParameterOptional {
	NOT_OPTIONAL = 0xFF,
	OPTIONAL_1 = 0x01,
	OPTIONAL_2 = 0x02,
	OPTIONAL_3 = 0x04,
	OPTIONAL_4 = 0x08,
	OPTIONAL_5 = 0x10,
	OPTIONAL_6 = 0x20,
	OPTIONAL_7 = 0x40
};

/// Prototype of a single override parameter
struct AssOverrideParamProto {
	/// ASS_ParameterOptional
	int optional;

	/// Type of this parameter
	VariableDataType type;

	/// Semantic type of this parameter
	AssParameterClass classification;

	AssOverrideParamProto(VariableDataType type, int opt, AssParameterClass classi)
	: optional(opt)
	, type(type)
	, classification(classi)
	{
	}
};

struct AssOverrideTagProto {
	/// Name of the tag, with slash
	std::string name;

	/// Parameters to this tag
	std::vector<AssOverrideParamProto> params;

	typedef std::vector<AssOverrideTagProto>::iterator iterator;

	/// @brief Add a parameter to this tag prototype
	/// @param type Data type of the parameter
	/// @param classi Semantic type of the parameter
	/// @param opt Situations in which this parameter is present
	void AddParam(VariableDataType type, AssParameterClass classi = AssParameterClass::NORMAL, int opt = NOT_OPTIONAL) {
		params.emplace_back(type, opt, classi);
	}

	/// @brief Convenience function for single-argument tags
	/// @param name Name of the tag, with slash
	/// @param type Data type of the parameter
	/// @param classi Semantic type of the parameter
	/// @param opt Situations in which this parameter is present
	void Set(const char *name, VariableDataType type, AssParameterClass classi = AssParameterClass::NORMAL, int opt = NOT_OPTIONAL) {
		this->name = name;
		params.emplace_back(type, opt, classi);
	}
};

static std::vector<AssOverrideTagProto> proto;
static void load_protos() {
	static bool loaded = false;
	if (loaded) return;
	loaded = true;

	proto.resize(56);
	int i = 0;

	// Longer tag names must appear before shorter tag names

	proto[0].Set("\\alpha", VariableDataType::TEXT, AssParameterClass::ALPHA); // \alpha&H<aa>&
	proto[++i].Set("\\bord", VariableDataType::FLOAT, AssParameterClass::ABSOLUTE_SIZE); // \bord<depth>
	proto[++i].Set("\\xbord", VariableDataType::FLOAT, AssParameterClass::ABSOLUTE_SIZE); // \xbord<depth>
	proto[++i].Set("\\ybord", VariableDataType::FLOAT, AssParameterClass::ABSOLUTE_SIZE); // \ybord<depth>
	proto[++i].Set("\\shad", VariableDataType::FLOAT, AssParameterClass::ABSOLUTE_SIZE); // \shad<depth>
	proto[++i].Set("\\xshad", VariableDataType::FLOAT, AssParameterClass::ABSOLUTE_SIZE); // \xshad<depth>
	proto[++i].Set("\\yshad", VariableDataType::FLOAT, AssParameterClass::ABSOLUTE_SIZE); // \yshad<depth>

	// \fade(<a1>,<a2>,<a3>,<t1>,<t2>,<t3>,<t4>)
	i++;
	proto[i].name = "\\fade";
	proto[i].AddParam(VariableDataType::INT);
	proto[i].AddParam(VariableDataType::INT);
	proto[i].AddParam(VariableDataType::INT);
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::RELATIVE_TIME_START);
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::RELATIVE_TIME_START);
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::RELATIVE_TIME_START);
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::RELATIVE_TIME_START);

	// \move(<x1>,<y1>,<x2>,<y2>[,<t1>,<t2>])
	i++;
	proto[i].name = "\\move";
	proto[i].AddParam(VariableDataType::FLOAT, AssParameterClass::ABSOLUTE_POS_X);
	proto[i].AddParam(VariableDataType::FLOAT, AssParameterClass::ABSOLUTE_POS_Y);
	proto[i].AddParam(VariableDataType::FLOAT, AssParameterClass::ABSOLUTE_POS_X);
	proto[i].AddParam(VariableDataType::FLOAT, AssParameterClass::ABSOLUTE_POS_Y);
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::RELATIVE_TIME_START);
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::RELATIVE_TIME_START);

	// If these are rearranged, keep rect clip and vector clip adjacent in this order
	// \clip(<x1>,<y1>,<x2>,<y2>)
	i++;
	proto[i].name = "\\clip";
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::ABSOLUTE_POS_X);
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::ABSOLUTE_POS_Y);
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::ABSOLUTE_POS_X);
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::ABSOLUTE_POS_Y);

	// \clip([<scale>,]<some drawings>)
	i++;
	proto[i].name = "\\clip";
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::NORMAL,OPTIONAL_2);
	proto[i].AddParam(VariableDataType::TEXT, AssParameterClass::DRAWING);

	// \iclip(<x1>,<y1>,<x2>,<y2>)
	i++;
	proto[i].name = "\\iclip";
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::ABSOLUTE_POS_X);
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::ABSOLUTE_POS_Y);
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::ABSOLUTE_POS_X);
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::ABSOLUTE_POS_Y);

	// \iclip([<scale>,]<some drawings>)
	i++;
	proto[i].name = "\\iclip";
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::NORMAL,OPTIONAL_2);
	proto[i].AddParam(VariableDataType::TEXT, AssParameterClass::DRAWING);

	proto[++i].Set("\\fscx", VariableDataType::FLOAT, AssParameterClass::RELATIVE_SIZE_X); // \fscx<percent>
	proto[++i].Set("\\fscy", VariableDataType::FLOAT, AssParameterClass::RELATIVE_SIZE_Y); // \fscy<percent>
	// \pos(<x>,<y>)
	i++;
	proto[i].name = "\\pos";
	proto[i].AddParam(VariableDataType::FLOAT, AssParameterClass::ABSOLUTE_POS_X);
	proto[i].AddParam(VariableDataType::FLOAT, AssParameterClass::ABSOLUTE_POS_Y);

	// \org(<x>,<y>)
	i++;
	proto[i].name = "\\org";
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::ABSOLUTE_POS_X);
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::ABSOLUTE_POS_Y);

	proto[++i].Set("\\pbo", VariableDataType::INT, AssParameterClass::ABSOLUTE_POS_Y); // \pbo<y>
	// \fad(<t1>,<t2>)
	i++;
	proto[i].name = "\\fad";
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::RELATIVE_TIME_START);
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::RELATIVE_TIME_END);

	proto[++i].Set("\\fsp", VariableDataType::FLOAT, AssParameterClass::ABSOLUTE_SIZE); // \fsp<pixels>
	proto[++i].Set("\\frx", VariableDataType::FLOAT); // \frx<degrees>
	proto[++i].Set("\\fry", VariableDataType::FLOAT); // \fry<degrees>
	proto[++i].Set("\\frz", VariableDataType::FLOAT); // \frz<degrees>
	proto[++i].Set("\\fr", VariableDataType::FLOAT); // \fr<degrees>
	proto[++i].Set("\\fax", VariableDataType::FLOAT); // \fax<factor>
	proto[++i].Set("\\fay", VariableDataType::FLOAT); // \fay<factor>
	proto[++i].Set("\\1c", VariableDataType::TEXT); // \1c&H<bbggrr>&
	proto[++i].Set("\\2c", VariableDataType::TEXT); // \2c&H<bbggrr>&
	proto[++i].Set("\\3c", VariableDataType::TEXT); // \3c&H<bbggrr>&
	proto[++i].Set("\\4c", VariableDataType::TEXT); // \4c&H<bbggrr>&
	proto[++i].Set("\\1a", VariableDataType::TEXT, AssParameterClass::ALPHA); // \1a&H<aa>&
	proto[++i].Set("\\2a", VariableDataType::TEXT, AssParameterClass::ALPHA); // \2a&H<aa>&
	proto[++i].Set("\\3a", VariableDataType::TEXT, AssParameterClass::ALPHA); // \3a&H<aa>&
	proto[++i].Set("\\4a", VariableDataType::TEXT, AssParameterClass::ALPHA); // \4a&H<aa>&
	proto[++i].Set("\\fe", VariableDataType::TEXT); // \fe<charset>
	proto[++i].Set("\\ko", VariableDataType::INT, AssParameterClass::KARAOKE); // \ko<duration>
	proto[++i].Set("\\kf", VariableDataType::INT, AssParameterClass::KARAOKE); // \kf<duration>
	proto[++i].Set("\\be", VariableDataType::INT); // \be<strength>
	proto[++i].Set("\\blur", VariableDataType::FLOAT); // \blur<strength>
	proto[++i].Set("\\fn", VariableDataType::TEXT); // \fn<name>
	proto[++i].Set("\\fs+", VariableDataType::FLOAT); // \fs+<size>
	proto[++i].Set("\\fs-", VariableDataType::FLOAT); // \fs-<size>
	proto[++i].Set("\\fs", VariableDataType::FLOAT, AssParameterClass::ABSOLUTE_SIZE); // \fs<size>
	proto[++i].Set("\\an", VariableDataType::INT); // \an<alignment>
	proto[++i].Set("\\c", VariableDataType::TEXT); // \c&H<bbggrr>&
	proto[++i].Set("\\b", VariableDataType::INT); // \b<0/1/weight>
	proto[++i].Set("\\i", VariableDataType::BOOL); // \i<0/1>
	proto[++i].Set("\\u", VariableDataType::BOOL); // \u<0/1>
	proto[++i].Set("\\s", VariableDataType::BOOL); // \s<0/1>
	proto[++i].Set("\\a", VariableDataType::INT); // \a<alignment>
	proto[++i].Set("\\k", VariableDataType::INT, AssParameterClass::KARAOKE); // \k<duration>
	proto[++i].Set("\\K", VariableDataType::INT, AssParameterClass::KARAOKE); // \K<duration>
	proto[++i].Set("\\q", VariableDataType::INT); // \q<0-3>
	proto[++i].Set("\\p", VariableDataType::INT); // \p<n>
	proto[++i].Set("\\r", VariableDataType::TEXT); // \r[<name>]

	// \t([<t1>,<t2>,][<accel>,]<style modifiers>)
	i++;
	proto[i].name = "\\t";
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::RELATIVE_TIME_START,OPTIONAL_3 | OPTIONAL_4);
	proto[i].AddParam(VariableDataType::INT, AssParameterClass::RELATIVE_TIME_START,OPTIONAL_3 | OPTIONAL_4);
	proto[i].AddParam(VariableDataType::FLOAT, AssParameterClass::NORMAL,OPTIONAL_2 | OPTIONAL_4);
	proto[i].AddParam(VariableDataType::BLOCK);
}

std::vector<std::string> tokenize(const std::string &text) {
	std::vector<std::string> paramList;
	paramList.reserve(6);

	if (text.empty())
		return paramList;

	if (text[0] != '(') {
		// There's just one parameter (because there's no parentheses)
		// This means text is all our parameters
		paramList.emplace_back(boost::trim_copy(text));
		return paramList;
	}

	// Ok, so there are parentheses used here, so there may be more than one parameter
	// Enter fullscale parsing!
	size_t i = 0, textlen = text.size();
	int parDepth = 1;
	while (i < textlen && parDepth > 0) {
		// Just skip until next ',' or ')', whichever comes first
		// (Next ')' is achieved when parDepth == 0)
		size_t start = ++i;
		while (i < textlen && parDepth > 0) {
			char c = text[i];
			// parDepth 1 is where we start, and the tag-level we're interested in parsing on
			if (c == ',' && parDepth == 1) break;
			if (c == '(') parDepth++;
			else if (c == ')') {
				if (--parDepth == 0) {
					// We just ate the parenthesis ending this parameter block
					// Make sure it doesn't get included in the parameter text
					break;
				}
			}
			i++;
		}
		// i now points to the first character not member of this parameter
		paramList.emplace_back(boost::trim_copy(text.substr(start, i - start)));
	}

	if (i+1 < textlen) {
		// There's some additional garbage after the parentheses
		// Just add it in for completeness
		paramList.emplace_back(text.begin() + i + 1, text.end());
	}
	return paramList;
}

void parse_parameters(AssOverrideTag *tag, const std::string &text, AssOverrideTagProto::iterator proto_it) {
	tag->Clear();

	// Tokenize text, attempting to find all parameters
	std::vector<std::string> paramList = tokenize(text);
	size_t totalPars = paramList.size();

	int parsFlag = 1 << (totalPars - 1); // Get optional parameters flag
	// vector (i)clip is the second clip proto_ittype in the list
	if ((tag->Name == "\\clip" || tag->Name == "\\iclip") && totalPars != 4) {
		++proto_it;
	}

	unsigned curPar = 0;
	for (auto& curproto : proto_it->params) {
		// Create parameter
		tag->Params.emplace_back(curproto.type, curproto.classification);

		// Check if it's optional and not present
		if (!(curproto.optional & parsFlag) || curPar >= totalPars)
			continue;

		tag->Params.back().Set(paramList[curPar++]);
	}
}

}

// From ass_dialogue.h
void AssDialogueBlockOverride::ParseTags() {
	Tags.clear();

	int depth = 0;
	size_t start = 0;
	for (size_t i = 1; i < text.size(); ++i) {
		if (depth > 0) {
			if (text[i] == ')')
				--depth;
		}
		else if (text[i] == '\\') {
			Tags.emplace_back(text.substr(start, i - start));
			start = i;
		}
		else if (text[i] == '(')
			++depth;
	}

	if (!text.empty())
		Tags.emplace_back(text.substr(start));
}

void AssDialogueBlockOverride::AddTag(std::string const& tag) {
	Tags.emplace_back(tag);
}

static std::string tag_str(AssOverrideTag const& t) { return t; }
std::string AssDialogueBlockOverride::GetText() {
	text = "{" + join(Tags | transformed(tag_str), std::string()) + "}";
	return text;
}

void AssDialogueBlockOverride::ProcessParameters(ProcessParametersCallback callback, void *userData) {
	for (auto& tag : Tags) {
		for (auto& par : tag.Params) {
			if (par.omitted) continue;

			callback(tag.Name, &par, userData);

			// Go recursive if it's a block parameter
			if (par.GetType() == VariableDataType::BLOCK)
				par.Get<AssDialogueBlockOverride*>()->ProcessParameters(callback, userData);
		}
	}
}

AssOverrideTag::AssOverrideTag() : valid(false) { }
AssOverrideTag::AssOverrideTag(std::string const& text) {
	SetText(text);
}
AssOverrideTag::AssOverrideTag(AssOverrideTag&& rhs)
: valid(rhs.valid)
, Name(std::move(rhs.Name))
, Params(std::move(rhs.Params))
{
}

AssOverrideTag& AssOverrideTag::operator=(AssOverrideTag&& rhs) {
	valid = rhs.valid;
	Name = std::move(rhs.Name);
	Params = std::move(rhs.Params);
	return *this;
}

void AssOverrideTag::Clear() {
	Params.clear();
	Params.reserve(6);
	valid = false;
}

void AssOverrideTag::SetText(const std::string &text) {
	load_protos();
	for (auto cur = proto.begin(); cur != proto.end(); ++cur) {
		if (boost::starts_with(text, cur->name)) {
			Name = cur->name;
			parse_parameters(this, text.substr(Name.size()), cur);
			valid = true;
			return;
		}
	}

	// Junk tag
	Name = text;
	valid = false;
}

static std::string param_str(AssOverrideParameter const& p) { return p.Get<std::string>(); }
AssOverrideTag::operator std::string() const {
	std::string result = Name;

	// Determine if it needs parentheses
	bool parentheses = Params.size() > 1;
	if (parentheses) result += "(";

	// Add parameters
	result += join(Params
		| filtered([](AssOverrideParameter const& p) { return !p.omitted; } )
		| transformed(param_str),
		",");

	if (parentheses) result += ")";
	return result;
}

max_stars_repo_name: rcombs/Aegisub

max_issues_repo_name: rcombs/Aegisub

max_forks_repo_name: rcombs/Aegisub


text:
//==============================================================================
//         Copyright 2003 - 2012   LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2012   LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#define NT2_UNIT_MODULE "nt2 complex.operator toolbox - arg/scalar Mode"

//////////////////////////////////////////////////////////////////////////////
// unit test behavior of boost.simd.operator components in scalar mode
//////////////////////////////////////////////////////////////////////////////
/// created  by jt the 18/02/2011
///
#include <nt2/toolbox/operator/include/functions/arg.hpp>
#include <boost/simd/sdk/simd/logical.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/dispatch/functor/meta/call.hpp>
#include <nt2/sdk/unit/tests.hpp>
#include <nt2/sdk/unit/module.hpp>
#include <nt2/toolbox/constant/constant.hpp>

NT2_TEST_CASE_TPL ( arg_real__2_0,  BOOST_SIMD_REAL_TYPES)
{

  using nt2::arg;
  using nt2::tag::arg_;
  typedef std::complex<T> cT;
  typedef typename boost::dispatch::meta::as_integer<T>::type iT;
  typedef typename boost::dispatch::meta::call<arg_(cT)>::type r_t;
  typedef typename nt2::meta::scalar_of<r_t>::type sr_t;
  typedef typename nt2::meta::scalar_of<r_t>::type ssr_t;
  typedef nt2::imaginary<T> ciT;
  typedef T wished_r_t;

  // return type conformity test
  NT2_TEST( (boost::is_same < r_t, wished_r_t >::value) );
  std::cout << std::endl;
  double ulpd;
  ulpd=0.0;

  // specific values tests
  NT2_TEST_EQUAL(arg(cT(nt2::Inf<T>())), nt2::Zero<T>());
  NT2_TEST_EQUAL(arg(cT(nt2::Minf<T>())),nt2::Pi<T>());
  NT2_TEST_EQUAL(arg(cT(nt2::Nan<T>())), nt2::Nan<T>());
  NT2_TEST_EQUAL(arg(cT(nt2::One<T>())), nt2::Zero<T>());
  NT2_TEST_EQUAL(arg(cT(nt2::Zero<T>())),nt2::Zero<T>());
  NT2_TEST_EQUAL(arg(cT(0, 1)), nt2::Pio_2<T>());
  NT2_TEST_EQUAL(arg(cT(1, 0)), nt2::Zero<T>());
  NT2_TEST_EQUAL(arg(cT(2, 2)), nt2::Pio_2<T>()/2);
  NT2_TEST_EQUAL(arg(cT(2,-2)),-nt2::Pio_2<T>()/2);
} // end of test for floating_