text:
// Boost.Geometry

// Copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle

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

#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_SPAR_HPP
#define BOOST_GEOMETRY_SRS_PROJECTIONS_SPAR_HPP

#include <boost/geometry/core/radius.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>

#include <boost/geometry/srs/projections/impl/pj_datums.hpp>
#include <boost/geometry/srs/projections/impl/pj_ellps.hpp>
#include <boost/geometry/srs/projections/dpar.hpp>
#include <boost/geometry/srs/projections/par_data.hpp>
#include <boost/geometry/srs/sphere.hpp>
#include <boost/geometry/srs/spheroid.hpp>

// TODO: move this functionality
#include <boost/geometry/index/detail/tuples.hpp>

#include <boost/mpl/assert.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/not.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/variant/variant.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_void.hpp>

#include <string>
#include <vector>

namespace boost { namespace geometry { namespace srs
{

namespace spar
{

// Static parameters holder

#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX \
typename P0, typename P1, typename P2, typename P3, typename P4, \
typename P5, typename P6, typename P7, typename P8, typename P9, \
typename P10, typename P11, typename P12, typename P13, typename P14

#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX \
P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14

#ifndef DOXYGEN_NO_DETAIL
namespace detail
{

template <BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
struct map_params_to_cons
{
  typedef boost::tuples::cons
    <
        P0,
        typename map_params_to_cons
            <
                P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14,
                boost::tuples::null_type
            >::type
    > type;
};

template <>
struct map_params_to_cons
<
    boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
    boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
    boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type
>
{
  typedef boost::tuples::null_type type;
};

} // namespace detail
#endif // DOXYGEN_NO_DETAIL

template
<
    // null_type -> void?
    typename P0 = boost::tuples::null_type,
    typename P1 = boost::tuples::null_type,
    typename P2 = boost::tuples::null_type,
    typename P3 = boost::tuples::null_type,
    typename P4 = boost::tuples::null_type,
    typename P5 = boost::tuples::null_type,
    typename P6 = boost::tuples::null_type,
    typename P7 = boost::tuples::null_type,
    typename P8 = boost::tuples::null_type,
    typename P9 = boost::tuples::null_type,
    typename P10 = boost::tuples::null_type,
    typename P11 = boost::tuples::null_type,
    typename P12 = boost::tuples::null_type,
    typename P13 = boost::tuples::null_type,
    typename P14 = boost::tuples::null_type
>
struct parameters
    : detail::map_params_to_cons<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>::type
{
private:
    typedef typename detail::map_params_to_cons<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>::type base_type;

public:
    typedef typename base_type::tail_type tail_type;

    parameters()
        : base_type()
    {}

    explicit parameters(P0 const& p0)
        : base_type(p0, cnull(), cnull(), cnull(), cnull(), cnull(), cnull(), cnull(), cnull(), cnull())
    {}

    parameters(P0 const& p0, P1 const& p1)
        : base_type(p0, p1, cnull(), cnull(), cnull(), cnull(), cnull(), cnull(), cnull(), cnull())
    {}

    parameters(P0 const& p0, P1 const& p1, P2 const& p2)
        : base_type(p0, p1, p2, cnull(), cnull(), cnull(), cnull(), cnull(), cnull(), cnull())
    {}

    parameters(P0 const& p0, P1 const& p1, P2 const& p2, P3 const& p3)
        : base_type(p0, p1, p2, p3, cnull(), cnull(), cnull(), cnull(), cnull(), cnull())
    {}

    parameters(P0 const& p0, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4)
        : base_type(p0, p1, p2, p3, p4, cnull(), cnull(), cnull(), cnull(), cnull())
    {}

    parameters(P0 const& p0, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5)
        : base_type(p0, p1, p2, p3, p4, p5, cnull(), cnull(), cnull(), cnull())
    {}

    parameters(P0 const& p0, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5, P6 const& p6)
        : base_type(p0, p1, p2, p3, p4, p5, p6, cnull(), cnull(), cnull())
    {}

    parameters(P0 const& p0, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5, P6 const& p6, P7 const& p7)
        : base_type(p0, p1, p2, p3, p4, p5, p6, p7, cnull(), cnull())
    {}

    parameters(P0 const& p0, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5, P6 const& p6, P7 const& p7, P8 const& p8)
        : base_type(p0, p1, p2, p3, p4, p5, p6, p7, p8, cnull())
    {}

    parameters(P0 const& p0, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5, P6 const& p6, P7 const& p7, P8 const& p8, P9 const& p9)
        : base_type(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)
    {}

    parameters(P0 const& p0, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5, P6 const& p6, P7 const& p7, P8 const& p8, P9 const& p9, P10 const& p10)
        : base_type(p0,
            tail_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10))
    {}

    parameters(P0 const& p0, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5, P6 const& p6, P7 const& p7, P8 const& p8, P9 const& p9, P10 const& p10, P11 const& p11)
        : base_type(p0,
            tail_type(p1,
                typename tail_type::tail_type(p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)))
    {}

    parameters(P0 const& p0, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5, P6 const& p6, P7 const& p7, P8 const& p8, P9 const& p9, P10 const& p10, P11 const& p11, P12 const& p12)
        : base_type(p0,
            tail_type(p1,
                typename tail_type::tail_type(p2,
                    typename tail_type::tail_type::tail_type(p3, p4, p5, p6, p7, p8, p9, p10, p11, p12))))
    {}

    parameters(P0 const& p0, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5, P6 const& p6, P7 const& p7, P8 const& p8, P9 const& p9, P10 const& p10, P11 const& p11, P12 const& p12, P13 const& p13)
        : base_type(p0,
            tail_type(p1,
                typename tail_type::tail_type(p2,
                    typename tail_type::tail_type::tail_type(p3,
                        typename tail_type::tail_type::tail_type::tail_type(p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)))))
    {}

    parameters(P0 const& p0, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5, P6 const& p6, P7 const& p7, P8 const& p8, P9 const& p9, P10 const& p10, P11 const& p11, P12 const& p12, P13 const& p13, P14 const& p14)
        : base_type(p0,
            tail_type(p1,
                typename tail_type::tail_type(p2,
                    typename tail_type::tail_type::tail_type(p3,
                        typename tail_type::tail_type::tail_type::tail_type(p4,
                            typename tail_type::tail_type::tail_type::tail_type::tail_type(p5, p6, p7, p8, p9, p10, p11, p12, p13, p14))))))
    {}

private:
    static inline const boost::tuples::null_type cnull()
    {
        return boost::tuples::null_type();
    }
};

#ifndef DOXYGEN_NO_DETAIL
namespace detail
{

template <typename Parameters, typename Parameter>
struct add_parameter
{
    BOOST_MPL_ASSERT_MSG((false), INVALID_ARGUMENT, (Parameters));
};

// NOTE: parameters has to be convertible to tuples::cons
template <BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX, typename Parameter>
struct add_parameter<spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>, Parameter>
    : index::detail::tuples::push_back
        <
            typename detail::map_params_to_cons<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>::type,
            Parameter
        >
{};

template <typename Head, typename Tail, typename Parameter>
struct add_parameter<boost::tuples::cons<Head, Tail>, Parameter>
    : index::detail::tuples::push_back
        <
            boost::tuples::cons<Head, Tail>,
            Parameter
        >
{};

} // namespace detail
#endif // DOXYGEN_NO_DETAIL

// Static parameters values

struct datum_wgs84 {};
struct datum_ggrs87 {};
struct datum_nad83 {};
struct datum_nad27 {};
struct datum_potsdam {};
struct datum_carthage {};
struct datum_hermannskogel {};
struct datum_ire65 {};
struct datum_nzgd49 {};
struct datum_osgb36 {};

struct ellps_merit {};
struct ellps_sgs85 {};
struct ellps_grs80 {};
struct ellps_iau76 {};
struct ellps_airy {};
struct ellps_apl4_9 {};
struct ellps_nwl9d {};
struct ellps_mod_airy {};
struct ellps_andrae {};
struct ellps_aust_sa {};
struct ellps_grs67 {};
struct ellps_bessel {};
struct ellps_bess_nam {};
struct ellps_clrk66 {};
struct ellps_clrk80 {};
struct ellps_clrk80ign {};
struct ellps_cpm {};
struct ellps_delmbr {};
struct ellps_engelis {};
struct ellps_evrst30 {};
struct ellps_evrst48 {};
struct ellps_evrst56 {};
struct ellps_evrst69 {};
struct ellps_evrstss {};
struct ellps_fschr60 {};
struct ellps_fschr60m {};
struct ellps_fschr68 {};
struct ellps_helmert {};
struct ellps_hough {};
struct ellps_intl {};
struct ellps_krass {};
struct ellps_kaula {};
struct ellps_lerch {};
struct ellps_mprts {};
struct ellps_new_intl {};
struct ellps_plessis {};
struct ellps_seasia {};
struct ellps_walbeck {};
struct ellps_wgs60 {};
struct ellps_wgs66 {};
struct ellps_wgs72 {};
struct ellps_wgs84 {};
struct ellps_sphere {};

struct mode_plane {};
struct mode_di {};
struct mode_dd {};
struct mode_hex {};

struct orient_isea {};
struct orient_pole {};

struct pm_greenwich {};
struct pm_lisbon {};
struct pm_paris {};
struct pm_bogota {};
struct pm_madrid {};
struct pm_rome {};
struct pm_bern {};
struct pm_jakarta {};
struct pm_ferro {};
struct pm_brussels {};
struct pm_stockholm {};
struct pm_athens {};
struct pm_oslo {};

struct proj_aea {}; struct proj_leac {}; // Albers Equal Area, Lambert Equal Area Conic
struct proj_aeqd {}; // Azimuthal Equidistant
struct proj_airy {}; // Airy
struct proj_aitoff {}; struct proj_wintri {}; // Aitoff, Winkel Tripel
struct proj_august {};
struct proj_apian {}; struct proj_ortel {}; struct proj_bacon {};
struct proj_bipc {};
struct proj_boggs {};
struct proj_bonne {};
struct proj_cass {};
struct proj_cc {};
struct proj_cea {};
struct proj_chamb {};
struct proj_collg {};
struct proj_crast {};
struct proj_denoy {};
struct proj_eck1 {};
struct proj_eck2 {};
struct proj_eck3 {}; struct proj_putp1 {}; struct proj_wag6 {}; struct proj_kav7 {};
struct proj_eck4 {};
struct proj_eck5 {};
struct proj_eqc {};
struct proj_eqdc {};
struct proj_etmerc {}; struct proj_utm {};
struct proj_fahey {};
struct proj_fouc_s {};
struct proj_gall {};
struct proj_geocent {};
struct proj_geos {};
struct proj_gins8 {};
struct proj_gn_sinu {}; struct proj_sinu {}; struct proj_eck6 {}; struct proj_mbtfps {};
struct proj_gnom {};
struct proj_goode {};
struct proj_gstmerc {};
struct proj_hammer {};
struct proj_hatano {};
struct proj_healpix {};
struct proj_rhealpix {};
struct proj_igh {};
struct proj_imw_p {};
struct proj_isea {};
struct proj_krovak {};
struct proj_labrd {};
struct proj_laea {};
struct proj_lagrng {};
struct proj_larr {};
struct proj_lask {};
struct proj_lonlat {}; struct proj_latlon {}; struct proj_latlong {}; struct proj_longlat {};
struct proj_lcc {};
struct proj_lcca {};
struct proj_loxim {};
struct proj_lsat {};
struct proj_mbt_fps {};
struct proj_mbtfpp {};
struct proj_mbtfpq {};
struct proj_merc {};
struct proj_mill {};
struct proj_mil_os {}; struct proj_lee_os {}; struct proj_gs48 {}; struct proj_alsk {}; struct proj_gs50 {};
struct proj_moll {}; struct proj_wag4 {}; struct proj_wag5 {};
struct proj_natearth {};
struct proj_nell {};
struct proj_nell_h {};
struct proj_nicol {};
struct proj_nsper {}; struct proj_tpers {};
struct proj_nzmg {};
struct proj_ob_tran {};
struct proj_ocea {};
struct proj_oea {};
struct proj_omerc {};
struct proj_ortho {};
struct proj_poly {};
struct proj_putp2 {};
struct proj_putp3 {}; struct proj_putp3p {};
struct proj_putp4p {}; struct proj_weren {};
struct proj_putp5 {}; struct proj_putp5p {};
struct proj_putp6 {}; struct proj_putp6p {};
struct proj_qsc {};
struct proj_robin {};
struct proj_rouss {};
struct proj_rpoly {};
struct proj_euler {}; struct proj_murd1 {}; struct proj_murd2 {}; struct proj_murd3 {}; struct proj_pconic {}; struct proj_tissot {}; struct proj_vitk1 {};
struct proj_somerc {};
struct proj_stere {}; struct proj_ups {};
struct proj_sterea {};
struct proj_kav5 {}; struct proj_qua_aut {}; struct proj_fouc {}; struct proj_mbt_s {};
struct proj_tcc {};
struct proj_tcea {};
struct proj_tmerc {};
struct proj_tpeqd {};
struct proj_urm5 {};
struct proj_urmfps {}; struct proj_wag1 {};
struct proj_vandg {};
struct proj_vandg2 {}; struct proj_vandg3 {};
struct proj_vandg4 {};
struct proj_wag2 {};
struct proj_wag3 {};
struct proj_wag7 {};
struct proj_wink1 {};
struct proj_wink2 {};

struct sweep_x {};
struct sweep_y {};

struct units_km {};
struct units_m {};
struct units_dm {};
struct units_cm {};
struct units_mm {};
struct units_kmi {};
struct units_in {};
struct units_ft {};
struct units_yd {};
struct units_mi {};
struct units_fath {};
struct units_ch {};
struct units_link {};
struct units_us_in {};
struct units_us_ft {};
struct units_us_yd {};
struct units_us_ch {};
struct units_us_mi {};
struct units_ind_yd {};
struct units_ind_ft {};
struct units_ind_ch {};

// Static parameters names

#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(NAME) \
template <typename T = double> \
struct NAME \
{ \
    NAME() : value(0) {} \
    explicit NAME(T const& v) : value(v) {} \
    T value; \
};

BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(a)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(b)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(e)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(es)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(f)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(gamma)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(h)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(k)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(k_0)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(m)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(n)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(q)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(r)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(rf)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(to_meter)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(vto_meter)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(w)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(x_0)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(y_0)

#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(NAME) \
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_F(NAME)

BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(alpha)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(azi)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(lat_0)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(lat_1)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(lat_2)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(lat_b)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(lat_ts)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(lon_0)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(lon_1)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(lon_2)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(lon_wrap)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(lonc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(o_alpha)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(o_lat_1)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(o_lat_2)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(o_lat_c)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(o_lat_p)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(o_lon_1)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(o_lon_2)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(o_lon_c)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(o_lon_p)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(pm)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(r_lat_a)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(r_lat_g)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(theta)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_R(tilt)

#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_I(NAME) \
template <int I> struct NAME { static const int value = I; };

BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_I(aperture)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_I(lsat)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_I(north_square)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_I(path)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_I(resolution)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_I(south_square)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_I(zone)

#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(NAME) \
struct NAME {};

BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(czech)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(geoc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(guam)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(no_cut)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(no_defs)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(no_rot)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(ns)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(over)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(r_a)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(r_au)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(r_g)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(r_h)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(r_v)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(rescale)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PARAM_BE(south)

template
<
    typename SpheroidOrSphere
>
struct ellps
{
    typedef SpheroidOrSphere model_type;

    ellps() : model() {}
    explicit ellps(SpheroidOrSphere const& sph) : model(sph) {}

    SpheroidOrSphere model;
};

struct nadgrids
    : srs::detail::nadgrids
{
    typedef srs::detail::nadgrids base_t;
    nadgrids(std::string const& g0) : base_t(g0) {}
    nadgrids(std::string const& g0, std::string const& g1) : base_t(g0, g1) {}
    nadgrids(std::string const& g0, std::string const& g1, std::string const& g2) : base_t(g0, g1, g2) {}
    nadgrids(std::string const& g0, std::string const& g1, std::string const& g2, std::string const& g3) : base_t(g0, g1, g2, g3) {}
    nadgrids(std::string const& g0, std::string const& g1, std::string const& g2, std::string const& g3, std::string const& g4) : base_t(g0, g1, g2, g3, g4) {}
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
    nadgrids(std::initializer_list<std::string> l) : base_t(l) {}
#endif
};

template <typename Proj>
struct o_proj
{
    typedef Proj type;
};

template <typename T = double>
struct towgs84
    : srs::detail::towgs84<T>
{
    typedef srs::detail::towgs84<T> base_t;

    towgs84(T const& v0, T const& v1, T const& v2)
        : base_t(v0, v1, v2)
    {}
    towgs84(T const& v0, T const& v1, T const& v2, T const& v3, T const& v4, T const& v5, T const& v6)
        : base_t(v0, v1, v2, v3, v4, v5, v6)
    {}
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
    towgs84(std::initializer_list<T> l) : base_t(l) {}
#endif
};

template <typename Units>
struct vunits
{
    typedef Units type;
};

// Static parameters traits

#ifndef DOXYGEN_NO_DETAIL
namespace detail
{

template <typename D>
struct datum_traits
{
    static const bool is_specialized = false;
    typedef void ellps_type;
    typedef void def_type;
};

#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(NAME, ELLPS, DEF_T, DEF_V) \
template <> \
struct datum_traits<spar::NAME> \
{ \
    static const bool is_specialized = true; \
    typedef spar::ELLPS ellps_type; \
    typedef spar::DEF_T def_type; \
    static spar::DEF_T def() { return spar::DEF_T DEF_V; } \
    static const dpar::value_datum id = dpar::NAME; \
};

BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(datum_wgs84, ellps_wgs84, towgs84<double>, (0,0,0))
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(datum_ggrs87, ellps_grs80, towgs84<double>, (-199.87,74.79,246.62))
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(datum_nad83, ellps_grs80, towgs84<double>, (0,0,0))
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(datum_nad27, ellps_clrk66, nadgrids, ("@conus","@alaska","@ntv2_0.gsb","@ntv1_can.dat"))
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(datum_potsdam, ellps_bessel, towgs84<double>, (598.1,73.7,418.2,0.202,0.045,-2.455,6.7))
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(datum_carthage, ellps_clrk80ign, towgs84<double>, (-263.0,6.0,431.0))
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(datum_hermannskogel, ellps_bessel, towgs84<double>, (577.326,90.129,463.919,5.137,1.474,5.297,2.4232))
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(datum_ire65, ellps_mod_airy, towgs84<double>, (482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15))
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(datum_nzgd49, ellps_intl, towgs84<double>, (59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993))
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_DATUM(datum_osgb36, ellps_airy, towgs84<double>, (446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894))

template <typename E>
struct ellps_traits
{
    static const bool is_specialized = false;
    template <typename T> struct model_type
    {
        typedef void type;
    };
};

template <typename E>
struct ellps_traits<spar::ellps<E> >
{
    static const bool is_specialized = true;
    template <typename T> struct model_type
    {
        // TODO: transform to spheroid<T> or sphere<T>
        typedef typename spar::ellps<E>::model_type type;
    };

    template <typename T>
    static typename spar::ellps<E>::model_type const& model(spar::ellps<E> const& e)
    {
        return e.model;
    }
};

// TODO: Implement as RadiusType-agnostic, member struct template defining model
//       and function template returning it
#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(NAME) \
template <> \
struct ellps_traits<spar::NAME> \
{ \
    static const bool is_specialized = true; \
    template <typename T> struct model_type \
    { \
        typedef srs::spheroid<T> type; \
    }; \
    template <typename T> \
    static srs::spheroid<T> model(spar::NAME const&) { \
        return srs::spheroid<T>(projections::detail::pj_get_ellps<T>().first[dpar::NAME].a, \
                                projections::detail::pj_get_ellps<T>().first[dpar::NAME].b); \
    } \
};

#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_SPHERE(NAME) \
template <> \
struct ellps_traits<spar::NAME> \
{ \
    static const bool is_specialized = true; \
    template <typename T> struct model_type \
    { \
        typedef srs::sphere<T> type; \
    }; \
    template <typename T> \
    static srs::sphere<T> model(spar::NAME const&) { \
        return srs::sphere<T>(projections::detail::pj_get_ellps<T>().first[dpar::NAME].a); \
    } \
};

BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_merit)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_sgs85)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_grs80)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_iau76)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_airy)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_apl4_9)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_nwl9d)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_mod_airy)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_andrae)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_aust_sa)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_grs67)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_bessel)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_bess_nam)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_clrk66)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_clrk80)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_clrk80ign)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_cpm)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_delmbr)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_engelis)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_evrst30)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_evrst48)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_evrst56)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_evrst69)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_evrstss)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_fschr60)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_fschr60m)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_fschr68)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_helmert)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_hough)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_intl)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_krass)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_kaula)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_lerch)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_mprts)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_new_intl)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_plessis)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_seasia)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_walbeck)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_wgs60)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_wgs66)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_wgs72)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ELLPS(ellps_wgs84)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_SPHERE(ellps_sphere)

template <typename M>
struct mode_traits
{
    static const bool is_specialized = false;
    typedef void type;
};

#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_MODE(NAME) \
template <> \
struct mode_traits<spar::NAME> \
{ \
    static const bool is_specialized = true; \
    typedef spar::NAME type; \
};

BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_MODE(mode_plane)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_MODE(mode_di)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_MODE(mode_dd)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_MODE(mode_hex)

template <typename O>
struct orient_traits
{
    static const bool is_specialized = false;
    typedef void type;
};

#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ORIENT(NAME) \
template <> \
struct orient_traits<spar::NAME> \
{ \
    static const bool is_specialized = true; \
    typedef spar::NAME type; \
};

BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ORIENT(orient_isea)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_ORIENT(orient_pole)

template <typename M>
struct pm_traits
{
    static const bool is_specialized = false;
    typedef void type;
};

template <typename T>
struct pm_traits<spar::pm<T> >
{
    static const bool is_specialized = true;
    typedef T type;
    static T const& value(spar::pm<T> const& p) { return p.value; }
};

#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PM(NAME, INDEX) \
template <> \
struct pm_traits<spar::NAME> \
{ \
    static const bool is_specialized = true; \
    typedef double type; \
    static double value(spar::NAME const& ) { return projections::detail::pj_prime_meridians[INDEX].deg; } \
};

BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PM(pm_greenwich, 0)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PM(pm_lisbon,    1)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PM(pm_paris,     2)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PM(pm_bogota,    3)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PM(pm_madrid,    4)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PM(pm_rome,      5)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PM(pm_bern,      6)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PM(pm_jakarta,   7)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PM(pm_ferro,     8)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PM(pm_brussels,  9)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PM(pm_stockholm, 10)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PM(pm_athens,    11)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PM(pm_oslo,      12)

template <typename P>
struct proj_traits
{
    static const bool is_specialized = false;
    typedef void type;
};

#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(NAME) \
template <> \
struct proj_traits<spar::NAME> \
{ \
    static const bool is_specialized = true; \
    typedef spar::NAME type; \
    static const srs::dpar::value_proj id = dpar::NAME; \
};

BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_aea)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_leac)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_aeqd)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_airy)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_aitoff)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_wintri)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_august)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_apian)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_ortel)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_bacon)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_bipc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_boggs)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_bonne)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_cass)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_cc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_cea)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_chamb)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_collg)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_crast)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_denoy)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_eck1)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_eck2)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_eck3)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_putp1)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_wag6)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_kav7)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_eck4)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_eck5)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_eqc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_eqdc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_etmerc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_utm)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_fahey)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_fouc_s)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_gall)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_geocent)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_geos)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_gins8)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_gn_sinu)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_sinu)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_eck6)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_mbtfps)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_gnom)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_goode)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_gstmerc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_hammer)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_hatano)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_healpix)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_rhealpix)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_igh)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_imw_p)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_isea)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_krovak)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_labrd)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_laea)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_lagrng)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_larr)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_lask)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_lonlat)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_latlon)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_latlong)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_longlat)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_lcc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_lcca)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_loxim)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_lsat)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_mbt_fps)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_mbtfpp)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_mbtfpq)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_merc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_mill)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_mil_os)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_lee_os)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_gs48)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_alsk)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_gs50)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_moll)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_wag4)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_wag5)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_natearth)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_nell)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_nell_h)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_nicol)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_nsper)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_tpers)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_nzmg)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_ob_tran)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_ocea)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_oea)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_omerc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_ortho)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_poly)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_putp2)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_putp3)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_putp3p)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_putp4p)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_weren)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_putp5)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_putp5p)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_putp6)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_putp6p)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_qsc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_robin)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_rouss)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_rpoly)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_euler)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_murd1)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_murd2)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_murd3)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_pconic)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_tissot)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_vitk1)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_somerc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_stere)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_ups)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_sterea)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_kav5)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_qua_aut)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_fouc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_mbt_s)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_tcc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_tcea)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_tmerc)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_tpeqd)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_urm5)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_urmfps)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_wag1)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_vandg)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_vandg2)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_vandg3)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_vandg4)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_wag2)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_wag3)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_wag7)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_wink1)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_PROJ(proj_wink2)

template <typename S>
struct sweep_traits
{
    static const bool is_specialized = false;
    typedef void type;
};

#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_SWEEP(NAME) \
template <> \
struct sweep_traits<spar::NAME> \
{ \
    static const bool is_specialized = true; \
    typedef spar::NAME type; \
};

BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_SWEEP(sweep_x)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_SWEEP(sweep_y)

template <typename S>
struct units_traits
{
    static const bool is_specialized = false;
    typedef void type;
};

#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(NAME) \
template <> \
struct units_traits<spar::NAME> \
{ \
    static const bool is_specialized = true; \
    typedef spar::NAME type; \
    static const srs::dpar::value_units id = dpar::NAME; \
};

BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_km)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_m)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_dm)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_cm)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_mm)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_kmi)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_in)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_ft)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_yd)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_mi)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_fath)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_ch)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_link)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_us_in)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_us_ft)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_us_yd)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_us_ch)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_us_mi)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_ind_yd)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_ind_ft)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_ind_ch)

template
<
    typename Tuple,
    template <typename> class IsSamePred,
    int I = 0,
    int N = boost::tuples::length<Tuple>::value
>
struct tuples_find_index_if
    : boost::mpl::if_c
        <
            IsSamePred<typename boost::tuples::element<I, Tuple>::type>::value,
            boost::integral_constant<int, I>,
            typename tuples_find_index_if<Tuple, IsSamePred, I+1, N>::type
        >::type
{};

template
<
    typename Tuple,
    template <typename> class IsSamePred,
    int N
>
struct tuples_find_index_if<Tuple, IsSamePred, N, N>
    : boost::integral_constant<int, N>
{};

template
<
    typename Tuple,
    template <typename> class IsSamePred,
    int I = tuples_find_index_if<Tuple, IsSamePred>::value,
    int N = boost::tuples::length<Tuple>::value
>
struct tuples_find_if
    : boost::tuples::element<I, Tuple>
{};

template
<
    typename Tuple,
    template <typename> class IsSamePred,
    int N
>
struct tuples_find_if<Tuple, IsSamePred, N, N>
{
    typedef boost::tuples::null_type type;
};

template <typename T>
struct tuples_is_found
    : boost::mpl::not_<boost::is_same<T, boost::tuples::null_type> >
{};

template <typename T>
struct tuples_is_not_found
    : boost::is_same<T, boost::tuples::null_type>
{};

template <typename Tuple, template <typename> class IsSamePred>
struct tuples_exists_if
    : tuples_is_found
        <
            typename tuples_find_if<Tuple, IsSamePred>::type
        >
{};

template <typename T, template <typename> class Param>
struct is_same_t : boost::false_type {};
template <typename T, template <typename> class Param>
struct is_same_t<Param<T>, Param> : boost::true_type {};

template <typename T, template <int> class Param>
struct is_same_i : boost::false_type {};
template <int I, template <int> class Param>
struct is_same_i<Param<I>, Param> : boost::true_type {};

template <typename T, template <typename> class Traits>
struct it_traits_specialized
    : boost::mpl::if_c
        <
            Traits<T>::is_specialized,
            boost::true_type,
            boost::false_type
        >::type
{};

template <typename Param>
struct is_param
{
    template <typename T>
    struct pred : boost::is_same<T, Param> {};
};

template <template <typename> class Param>
struct is_param_t
{
    template <typename T>
    struct pred : is_same_t<T, Param> {};
};

template <template <int> class Param>
struct is_param_i
{
    template <typename T>
    struct pred : is_same_i<T, Param> {};
};

template <template <typename> class Traits>
struct is_param_tr
{
    template <typename T>
    struct pred : it_traits_specialized<T, Traits> {};
};

//template <typename IsParam1, typename IsParam2>
//struct is_param_or
//{
//    template <typename T>
//    struct pred : boost::mpl::or_<IsParam1::pred<T>, IsParam2::pred<T> > {};
//};

// pick proj static name

template <typename Tuple>
struct pick_proj_tag
{
    typedef typename tuples_find_if
        <
            Tuple,
            is_param_tr<proj_traits>::pred
        >::type proj_type;

    static const bool is_found = tuples_is_found<proj_type>::value;

    BOOST_MPL_ASSERT_MSG((is_found), PROJECTION_NOT_NAMED, (Tuple));

    typedef proj_traits<proj_type> traits_type;
    typedef typename traits_type::type type;
};

template <typename Tuple>
struct pick_o_proj_tag
{
    typedef typename tuples_find_if
        <
            Tuple,
            is_param_t<o_proj>::pred
        >::type o_proj_type;

    static const bool is_found = tuples_is_found<o_proj_type>::value;

    BOOST_MPL_ASSERT_MSG((is_found), NO_O_PROJ_PARAMETER, (Tuple));

    typedef proj_traits<typename o_proj_type::type> traits_type;
    typedef typename traits_type::type type;
};

} // namespace detail
#endif // DOXYGEN_NO_DETAIL

} // namespace spar

}}} // namespace boost::geometry::srs

#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_SPAR_HPP


text:
/**
 * \file boost/numeric/ublasx/operation/rcond.hpp
 *
 * \brief Matrix reciprocal condition number estimate.
 *
 * The condition number of a regular (square) matrix is the product
 * of the \e norm of the matrix and the norm of its inverse (or
 * pseudo-inverse), and hence depends on the kind of matrix-norm.
 *
 * Copyright (c) 2010, Marco Guazzone
 *
 * 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)
 *
 * \author Marco Guazzone, marco.guazzone@gmail.com
 */

#ifndef BOOST_NUMERIC_UBLASX_OPERATION_RCOND_HPP
#define BOOST_NUMERIC_UBLASX_OPERATION_RCOND_HPP

#include <algorithm>
#include <boost/numeric/bindings/lapack/auxiliary/lange.hpp>
#include <boost/numeric/bindings/lapack/computational/gbcon.hpp>
#include <boost/numeric/bindings/lapack/computational/gbtrf.hpp>
#include <boost/numeric/bindings/lapack/computational/gecon.hpp>
#include <boost/numeric/bindings/lapack/computational/getrf.hpp>
#include <boost/numeric/bindings/lapack/computational/hecon.hpp>
#include <boost/numeric/bindings/lapack/computational/hetrf.hpp>
#include <boost/numeric/bindings/lapack/computational/sycon.hpp>
#include <boost/numeric/bindings/lapack/computational/sytrf.hpp>
#include <boost/numeric/bindings/lapack/computational/trcon.hpp>
#include <boost/numeric/bindings/ublas.hpp>
#include <boost/numeric/ublas/banded.hpp>
#include <boost/numeric/ublas/exception.hpp>
#include <boost/numeric/ublas/expression_types.hpp>
#include <boost/numeric/ublas/hermitian.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/matrix_expression.hpp>
#include <boost/numeric/ublas/traits.hpp>
#include <boost/numeric/ublas/symmetric.hpp>
#include <boost/numeric/ublas/triangular.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublasx/operation/num_columns.hpp>
#include <boost/numeric/ublasx/operation/num_rows.hpp>
#include <boost/numeric/ublasx/operation/qr.hpp>
#include <stdexcept>

namespace boost { namespace numeric { namespace ublasx {

using namespace ::boost::numeric::ublas;

namespace detail {

enum matrix_norm_category
{
	matrix_norm_1,
	matrix_norm_2,
	matrix_norm_frobenius,
	matrix_norm_inf
};

//template <
//	typename ValueT,
//	typename LayoutT,
//	typename StorageT
//>
//ValueT* band_mat_to_lapack_vec(banded_matrix<ValueT,LayoutT,StorageT> const& A, ::fortran_int_t& n)
//{
//	typedef banded_matrix<ValueT,LayoutT,StorageT> matrix_type;
//	typedef typename matrix_traits<matrix_type>::size_type size_type;
//
//	const size_type kl = A.lower();
//	const size_type ku = A.upper();
//	const size_type nr = num_rows(A);
//	const size_type nc = num_columns(A);
//
//	n = (2*kl+ku+1)*nc;
//
//	ValueT* v = new ValueT[n];
//
//	for (size_type r = 0; r < nr; ++r)
//	{
//		for (size_type c = 0; c < nc; ++c)
//		{
//			size_type rr = kl+ku+r-c;
//			size_type k = (2*kl+ku+1)*c+rr;
//
//			if ((r == c) || (c <= (ku+r) && r <= (c+kl)))
//			{
//				// In band
//				v[k] = A(r,c);
//			}
//			else
//			{
//				// Out of band
//				v[k] = ValueT();
//			}
//		}
//	}
//
//	return v;
//}

//template <typename T>
//void print_vector(std::string const& desc, T const* a, std::size_t n)
//{
//	std::cout << std::endl << desc << std::endl << "  [";
//	for(std::size_t i = 0; i < n; ++i)
//	{
//		std::cout << " " << std::fixed << a[i];
//	}
//	std::cout << "]" << std::endl;
//}

template <typename MatrixT>
typename type_traits<
	typename matrix_traits<MatrixT>::value_type
>::real_type rcond_impl(MatrixT const& A, matrix_norm_category norm_category, column_major_tag)
{
    typedef typename matrix_traits<MatrixT>::value_type value_type;
	typedef typename type_traits<value_type>::real_type result_type;
	typedef typename matrix_traits<MatrixT>::size_type size_type;
	typedef matrix<value_type, column_major> work_matrix_type;

	size_type nr = num_rows(A);
	size_type nc = num_columns(A);
	size_type k = ::std::min(nr,nc);

	// Check if A is a square matrix
	if (nr != nc)
	{
		// Non-square matrix -> Use QR decomposition
		if (nr < nc)
		{
			return rcond_impl(qr_decompose(trans(A)).R(false), norm_category, column_major_tag());
		}
		else
		{
			return rcond_impl(qr_decompose(A).R(false), norm_category, column_major_tag());
		}
	}

	char what_norm;
	result_type norm;
	result_type res;

	//FIXME: actually, in bindings this function is broken
//	switch (norm_category)
//	{
//		case matrix_norm_1:
//			what_norm = 'O';
//			break;
//		case matrix_norm_inf:
//			what_norm = 'I';
//			break;
////		case matrix_norm_frobenius:
////			what_norm = 'F';
////			break;
//		default:
//			throw std::runtime_error("[rcond::detail::rcond_impl] Unsupported norm category.");
//	}

	// Compute the norm of A
	//FIXME: actually, in bindings this function is broken
//	::boost::numeric::bindings::lapack::lange(
//		what_norm,
//		A
//	);
	switch (norm_category)
	{
		case matrix_norm_1:
			what_norm = 'O';
			norm = norm_1(A);
			break;
		case matrix_norm_inf:
			what_norm = 'I';
			norm = norm_inf(A);
			break;
		default:
			throw std::runtime_error("[rcond::detail::rcond_impl] Unsupported norm category.");
	}

	// Compute the LUP factorization of A
	work_matrix_type tmp_LU(A);
	vector< ::fortran_int_t > dummy_ipiv(k);
	::boost::numeric::bindings::lapack::getrf(
		tmp_LU,
		dummy_ipiv
	);
	dummy_ipiv.resize(0, false); // free memory

	// Finally, compute the reciprocal condition number
	::boost::numeric::bindings::lapack::gecon(
		what_norm,
		tmp_LU,
		norm,
		res
	);

	return res;
}

template <typename MatrixT>
typename type_traits<
	typename matrix_traits<MatrixT>::value_type
>::real_type rcond_impl(MatrixT const& A, matrix_norm_category norm_category, row_major_tag)
{
	typedef matrix<
				typename matrix_traits<MatrixT>::value_type,
				column_major
			> work_matrix_type;

	work_matrix_type tmp_A(A);

	return rcond_impl(tmp_A, norm_category, column_major_tag());
}

template <
	typename ValueT,
	typename TriangularT,
	typename StorageT
>
typename type_traits<ValueT>::real_type rcond_impl(triangular_matrix<ValueT,TriangularT,column_major,StorageT> const& A, matrix_norm_category norm_category, column_major_tag)
{
	typedef triangular_matrix<ValueT,TriangularT,column_major,StorageT> matrix_type;
    typedef typename matrix_traits<matrix_type>::value_type value_type;
	typedef typename matrix_traits<matrix_type>::size_type size_type;
	typedef typename type_traits<value_type>::real_type result_type;
	typedef matrix<value_type,column_major> auxiliary_matrix_type;
	typedef triangular_adaptor<auxiliary_matrix_type, TriangularT> work_matrix_type;

	size_type nr = num_rows(A);
	size_type nc = num_columns(A);

	// Check if A is a square matrix
	if (nr != nc)
	{
		// Non-square matrix -> Use QR decomposition
		if (nr < nc)
		{
			return rcond_impl(qr_decompose(trans(A)).R(), norm_category, column_major_tag());
		}
		else
		{
			return rcond_impl(qr_decompose(A).R(), norm_category, column_major_tag());
		}
	}

	char what_norm;
	result_type res;

	switch (norm_category)
	{
		case matrix_norm_1:
			what_norm = 'O';
			break;
		case matrix_norm_inf:
			what_norm = 'I';
			break;
		default:
			throw std::runtime_error("[rcond::detail::rcond_impl] Unsupported norm category.");
	}

	auxiliary_matrix_type aux_A(A);
	work_matrix_type tmp_A(aux_A);

	// Finally, compute the reciprocal condition number
	::boost::numeric::bindings::lapack::trcon(
		what_norm,
		tmp_A,
		res
	);

	return res;
}

template <
	typename ValueT,
	typename TriangularT,
	typename StorageT
>
typename type_traits<ValueT>::real_type rcond_impl(triangular_matrix<ValueT,TriangularT,row_major,StorageT> const& A, matrix_norm_category norm_category, row_major_tag)
{
	typedef triangular_matrix<ValueT,TriangularT,column_major,StorageT> work_matrix_type;

	work_matrix_type tmp_A(A);

	return rcond_impl(tmp_A, norm_category, column_major_tag());
}

/*
template <
	typename ValueT,
	typename StorageT
>
typename type_traits<ValueT>::real_type rcond_impl(banded_matrix<ValueT,column_major,StorageT> const& A, matrix_norm_category norm_category, column_major_tag)
{
	typedef banded_matrix<ValueT,column_major,StorageT> matrix_type;
    typedef typename matrix_traits<matrix_type>::value_type value_type;
	typedef typename matrix_traits<matrix_type>::size_type size_type;
	typedef typename type_traits<value_type>::real_type result_type;
	//typedef matrix<value_type,LayoutT> auxiliary_matrix_type;
	//typedef banded_adaptor<auxiliary_matrix_type> work_matrix_type;
	typedef banded_matrix<ValueT,row_major,StorageT> work_matrix_type;
	typedef vector< ::fortran_int_t > vector_type;

	size_type nr = num_rows(A);
	size_type nc = num_columns(A);

	// Check if A is a square matrix
	if (nr != nc)
	{
		// Non-square matrix -> Use QR decomposition
		if (nr < nc)
		{
			return rcond_impl(qr_decompose(trans(A)).R(), norm_category, column_major_tag());
		}
		else
		{
			return rcond_impl(qr_decompose(A).R(), norm_category, column_major_tag());
		}
	}

	char what_norm;
	result_type norm;
	result_type res;
	size_type k = ::std::min(nr,nc);
	size_type kl = A.lower();
	size_type ku = A.upper();
//	size_type ldab = 2*kl+ku+1;

	switch (norm_category)
	{
		case matrix_norm_1:
			what_norm = 'O';
			break;
		case matrix_norm_inf:
			what_norm = 'I';
			break;
//		case matrix_norm_frobenius:
//			what_norm = 'F';
//			break;
		default:
			throw std::runtime_error("[rcond::detail::rcond_impl] Unsupported norm category.");
	}

	// Compute the norm of A
	//FIXME: actually, in bindings this function is broken
//	::boost::numeric::bindings::lapack::lange(
//		what_norm,
//		A
//	);
	switch (norm_category)
	{
		case matrix_norm_1:
			norm = norm_1(A);
			break;
		case matrix_norm_inf:
			norm = norm_inf(A);
			break;
		default:
			throw std::runtime_error("[rcond::detail::rcond_impl] Unsupported norm category.");
	}

	// Compute the LUP factorization of A
//	::fortran_int_t* aux_ab = band_mat_to_lapack_vec(A, n);
//	vector< ::fortran_int_t> tmp_ipiv(k);
//	::std::ptrdiff_t info;
//	info = ::boost::numeric::bindings::lapack::detail::gbtrf(
//		nr,
//		nc,
//		kl,
//		ku,
//		aux_ab,
//		ldab,
//		tmp_ipiv.data().begin()
//	);
	work_matrix_type AB(A, kl, kl+ku); //NOTE: "kl+ku" is not a typo
	vector_type ipiv(k);
	::boost::numeric::bindings::lapack::gbtrf(AB, ipiv);

	// Finally, compute the reciprocal condition number
	::boost::numeric::bindings::lapack::gbcon(
		what_norm,
		AB,
		ipiv,
		norm,
		res
	);

	return res;
}
*/

template <
	typename ValueT,
	typename StorageT
>
typename type_traits<ValueT>::real_type rcond_impl(banded_matrix<ValueT,column_major,StorageT> const& A, matrix_norm_category norm_category, column_major_tag)
{
	typedef banded_matrix<ValueT,row_major,StorageT> work_matrix_type;

	work_matrix_type tmp_A(A, A.lower(), A.upper());

	return rcond_impl(tmp_A, norm_category, row_major_tag());
}

template <
	typename ValueT,
	typename StorageT
>
typename type_traits<ValueT>::real_type rcond_impl(banded_matrix<ValueT,row_major,StorageT> const& A, matrix_norm_category norm_category, row_major_tag)
{
	typedef banded_matrix<ValueT,row_major,StorageT> matrix_type;
    typedef typename matrix_traits<matrix_type>::value_type value_type;
	typedef typename matrix_traits<matrix_type>::size_type size_type;
	typedef typename type_traits<value_type>::real_type result_type;
	typedef banded_matrix<ValueT,row_major,StorageT> work_matrix_type;
	typedef vector< ::fortran_int_t > vector_type;

	size_type nr = num_rows(A);
	size_type nc = num_columns(A);

	// Check if A is a square matrix
	if (nr != nc)
	{
		// Non-square matrix -> Use QR decomposition
		if (nr < nc)
		{
			return rcond_impl(qr_decompose(trans(A)).R(), norm_category, column_major_tag());
		}
		else
		{
			return rcond_impl(qr_decompose(A).R(), norm_category, column_major_tag());
		}
	}

	char what_norm;
	result_type norm;
	result_type res;
	size_type k = ::std::min(nr,nc);
	size_type kl = A.lower();
	size_type ku = A.upper();
//	size_type ldab = 2*kl+ku+1;

	switch (norm_category)
	{
		case matrix_norm_1:
			what_norm = 'O';
			break;
		case matrix_norm_inf:
			what_norm = 'I';
			break;
//		case matrix_norm_frobenius:
//			what_norm = 'F';
//			break;
		default:
			throw std::runtime_error("[rcond::detail::rcond_impl] Unsupported norm category.");
	}

	// Compute the norm of A
	//FIXME: actually, in bindings this function is broken
//	::boost::numeric::bindings::lapack::lange(
//		what_norm,
//		A
//	);
	switch (norm_category)
	{
		case matrix_norm_1:
			norm = norm_1(A);
			break;
		case matrix_norm_inf:
			norm = norm_inf(A);
			break;
		default:
			throw std::runtime_error("[rcond::detail::rcond_impl] Unsupported norm category.");
	}

	// Compute the LUP factorization of A
//	::fortran_int_t* aux_ab = band_mat_to_lapack_vec(A, n);
//	vector< ::fortran_int_t> tmp_ipiv(k);
//	::std::ptrdiff_t info;
//	info = ::boost::numeric::bindings::lapack::detail::gbtrf(
//		nr,
//		nc,
//		kl,
//		ku,
//		aux_ab,
//		ldab,
//		tmp_ipiv.data().begin()
//	);
	work_matrix_type AB(A, kl, kl+ku); //NOTE: "kl+ku" is not a typo
	vector_type ipiv(k);
	::boost::numeric::bindings::lapack::gbtrf(AB, ipiv);

	// Finally, compute the reciprocal condition number
	::boost::numeric::bindings::lapack::gbcon(
		what_norm,
		AB,
		ipiv,
		norm,
		res
	);

	return res;
}

template <
	typename ValueT,
	typename TriangularT,
	typename StorageT
>
typename type_traits<ValueT>::real_type rcond_impl(symmetric_matrix<ValueT,TriangularT,column_major,StorageT> const& A, matrix_norm_category norm_category, column_major_tag)
{
	typedef symmetric_matrix<ValueT,TriangularT,column_major,StorageT> matrix_type;
    typedef typename matrix_traits<matrix_type>::value_type value_type;
	typedef typename matrix_traits<matrix_type>::size_type size_type;
	typedef typename type_traits<value_type>::real_type result_type;
	typedef matrix<ValueT,column_major> auxiliary_matrix_type;
	typedef symmetric_adaptor<auxiliary_matrix_type,TriangularT> work_matrix_type;
	typedef vector< ::fortran_int_t > vector_type;

	size_type nr = num_rows(A);
	size_type nc = num_columns(A);
	size_type n = ::std::min(nr, nc);

	// Check if A is a square matrix
	if (nr != nc)
	{
		// Non-square matrix -> Use QR decomposition
		if (nr < nc)
		{
			return rcond_impl(qr_decompose(trans(A)).R(), norm_category, column_major_tag());
		}
		else
		{
			return rcond_impl(qr_decompose(A).R(), norm_category, column_major_tag());
		}
	}

	result_type norm;
	result_type res;

	// Compute the norm of A
	//FIXME: actually, in bindings this function is broken
//	::boost::numeric::bindings::lapack::lange(
//		what_norm,
//		A
//	);
	switch (norm_category)
	{
		case matrix_norm_1:
			norm = norm_1(A);
			break;
		case matrix_norm_inf:
			norm = norm_inf(A);
			break;
		default:
			throw std::runtime_error("[rcond::detail::rcond_impl] Unsupported norm category.");
	}

	// Compute the LUP factorization of A
	//work_matrix_type AB(A);
	auxiliary_matrix_type aux_A(A);
	work_matrix_type AB(aux_A);
	vector_type ipiv(n);
	::boost::numeric::bindings::lapack::sytrf(AB, ipiv);

	// Finally, compute the reciprocal condition number
	::boost::numeric::bindings::lapack::sycon(
		AB,
		ipiv,
		norm,
		res
	);

	return res;
}

template <
	typename ValueT,
	typename TriangularT,
	typename StorageT
>
typename type_traits<ValueT>::real_type rcond_impl(symmetric_matrix<ValueT,TriangularT,row_major,StorageT> const& A, matrix_norm_category norm_category, row_major_tag)
{
	typedef symmetric_matrix<ValueT,TriangularT,column_major,StorageT> work_matrix_type;

	work_matrix_type tmp_A(A);

	return rcond_impl(tmp_A, norm_category, column_major_tag());
}

template <
	typename ValueT,
	typename TriangularT,
	typename StorageT
>
typename type_traits<ValueT>::real_type rcond_impl(hermitian_matrix<ValueT,TriangularT,column_major,StorageT> const& A, matrix_norm_category norm_category, column_major_tag)
{
	typedef hermitian_matrix<ValueT,TriangularT,column_major,StorageT> matrix_type;
    typedef typename matrix_traits<matrix_type>::value_type value_type;
	typedef typename matrix_traits<matrix_type>::size_type size_type;
	typedef typename type_traits<value_type>::real_type result_type;
	typedef matrix<ValueT,column_major> auxiliary_matrix_type;
	typedef hermitian_adaptor<auxiliary_matrix_type,TriangularT> work_matrix_type;
	typedef vector< ::fortran_int_t > vector_type;

	size_type nr = num_rows(A);
	size_type nc = num_columns(A);
	size_type n = ::std::min(nr, nc);

	// Check if A is a square matrix
	if (nr != nc)
	{
		// Non-square matrix -> Use QR decomposition
		if (nr < nc)
		{
			return rcond_impl(qr_decompose(trans(A)).R(), norm_category, column_major_tag());
		}
		else
		{
			return rcond_impl(qr_decompose(A).R(), norm_category, column_major_tag());
		}
	}

	result_type norm;
	result_type res;

	// Compute the norm of A
	//FIXME: actually, in bindings this function is broken
//	::boost::numeric::bindings::lapack::lange(
//		what_norm,
//		A
//	);
	switch (norm_category)
	{
		case matrix_norm_1:
			norm = norm_1(A);
			break;
		case matrix_norm_inf:
			norm = norm_inf(A);
			break;
		default:
			throw std::runtime_error("[rcond::detail::rcond_impl] Unsupported norm category.");
	}

	// Compute the LUP factorization of A
	auxiliary_matrix_type aux_A(A);
	work_matrix_type AB(aux_A);
	vector_type ipiv(n);
	::boost::numeric::bindings::lapack::hetrf(AB, ipiv);

	// Finally, compute the reciprocal condition number
	::boost::numeric::bindings::lapack::hecon(
		AB,
		ipiv,
		norm,
		res
	);

	return res;
}

template <
	typename ValueT,
	typename TriangularT,
	typename StorageT
>
typename type_traits<ValueT>::real_type rcond_impl(hermitian_matrix<ValueT,TriangularT,row_major,StorageT> const& A, matrix_norm_category norm_category, row_major_tag)
{
	typedef hermitian_matrix<ValueT,TriangularT,column_major,StorageT> work_matrix_type;

	work_matrix_type tmp_A(A);

	return rcond_impl(tmp_A, norm_category, column_major_tag());
}

} // Namespace detail

/**
 * \brief Matrix reciprocal condition number estimate based on 1-norm.
 *
 * \tparam MatrixExprT The type of the input matrix expression.
 *
 * \param A The input \e square matrix expression.
 * \return The estimate of the reciprocal condition number of \a A.
 *
 * \author Marco Guazzone, marco.guazzone@gmail.com
 */
template <typename MatrixExprT>
typename type_traits<
	typename matrix_traits<MatrixExprT>::value_type
>::real_type rcond(matrix_expression<MatrixExprT> const& A)
{
	typedef typename matrix_traits<MatrixExprT>::orientation_category orientation_category;

	return detail::rcond_impl(A(), detail::matrix_norm_1, orientation_category());
}

//FIXME: Does we also need this?
///**
// * \brief Matrix reciprocal condition number estimate based on the matrix norm
// *  defined by parameter \a what_norm.
// *
// * \tparam MatrixExprT The type of the input matrix expression.
// * \tparam NormTagT The type of the matrix norm category.
// *
// * \param A The input \e square matrix expression.
// * \param what_norm The matrix norm category.
// * \return The estimate of the reciprocal condition number of \a A.
// *
// * \author Marco Guazzone, marco.guazzone@gmail.com
// */
//template <typename MatrixExprT, typename NormTagT>
//typename type_traits<
//	typename matrix_traits<MatrixExprT>::value_type
//>::real_type rcond(matrix_expression<MatrixExprT> const& A, NormTagT what_norm)
//{
//	typedef typename matrix_traits<MatrixExprT>::orientation_category orientation_category;
//
//	return detail::rcond_impl(A(), detail::matrix_norm_1, orientation_category());
//}

}}} // Namespace boost::numeric::ublasx

#endif // BOOST_NUMERIC_UBLASX_OPERATION_RCOND_HPP

ext: hpp


text:
#include <cmath>
#include <iostream>
#include <vector>

#include <boost/align/aligned_allocator.hpp>
#include <boost/align/aligned_delete.hpp>

#include <boost/simd/function/cos.hpp>
#include <boost/simd/function/load.hpp>
#include <boost/simd/function/sin.hpp>
#include <boost/simd/function/sincos.hpp>
#include <boost/simd/function/store.hpp>
#include <boost/simd/pack.hpp>

int main(int argc, char** argv)
{
  namespace bs = boost::simd;
  namespace ba = boost::alignment;

  using pack_t = bs::pack<float>;

  std::size_t num_elements = 1024;
  std::size_t alignment    = pack_t::alignment;
  //! [transcendental-declare]
  std::vector<float, ba::aligned_allocator<float, pack_t::alignment>> X(num_elements);
  std::vector<float, ba::aligned_allocator<float, pack_t::alignment>> sinX(num_elements);
  std::vector<float, ba::aligned_allocator<float, pack_t::alignment>> cosX(num_elements);
  //! [transcendental-declare]

  //! [transcendental-scalar]
  for (int i = 0; i < num_elements; ++i) {
    sinX[i] = std::sin(X[i]);
    cosX[i] = std::cos(X[i]);
  }
  //! [transcendental-scalar]

  //! [transcendental-calc-individ]
  for (int i = 0; i < num_elements; i += pack_t::static_size) {
    pack_t v0 = bs::load<pack_t>(&X[i]);
    bs::store(bs::sin(v0), &sinX[i]);
    bs::store(bs::cos(v0), &sinX[i]);
  }
  //! [transcendental-calc-individ]

  //! [transcendental-calc-combine]
  for (int i = 0; i < num_elements; i += pack_t::static_size) {
    pack_t v0 = bs::load<pack_t>(&X[i]);
    auto res  = bs::sincos(v0);
    bs::store(res.first, &sinX[i]);
    bs::store(res.second, &cosX[i]);
  }
  //! [transcendental-calc-combine]

  //! [transcendental-calc-small]
  for (int i = 0; i < num_elements; i += pack_t::static_size) {
    pack_t v0 = bs::load<pack_t>(&X[i]);
    bs::store(bs::sin(v0, bs::tag::small_), &sinX[i]);
  }
  //! [transcendental-calc-small]
}

ext: cpp


text:
#define BOOST_TEST_MODULE tetrimino_l
#include <boost/test/unit_test.hpp>

#include <yatc/coordinate.h>
#include <yatc/tetriminos/tetrimino_l.h>
#include <yatc/tetriminos/tetrimino_base.h>
#include <yatc/shape.h>

using namespace yatc;

BOOST_AUTO_TEST_CASE(constructor)
{
	const tetrimino_base mold(
		coordinate{ 0, -1 }, coordinate{ 0, 0 },
		coordinate{ 0, 1 }, coordinate{ 1, 1 },
		shape::L
	);
	const tetrimino_l l;
	BOOST_TEST(l == mold);
}

max_stars_repo_name: mateka/yatc

max_issues_repo_name: mateka/yatc

max_forks_repo_name: mateka/yatc


text:
// Definition of the extension module

#include "hack.h"

#include <boost/python/module.hpp>

#include "common.h"

BOOST_PYTHON_MODULE(native) {
  capnp_python::defineSchemaCapnp();
  capnp_python::defineResourceTypes();
  capnp_python::defineValueTypes();
}

ext: cc

max_stars_repo_name: clchiou/garage

max_issues_repo_name: clchiou/garage

max_forks_repo_name: clchiou/garage


text:
/* /libs/serialization/xml_performance/macro.hpp *******************************

(C) Copyright 2010 Bryce Lelbach

Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)

*******************************************************************************/

#if !defined(BOOST_SERIALIZATION_XML_PERFORMANCE_MACRO_HPP)
#define BOOST_SERIALIZATION_XML_PERFORMANCE_MACRO_HPP

#if defined(_MSC_VER) && (_MSC_VER >= 1020)
  #pragma once
#endif

#include <boost/preprocessor.hpp>

#if !defined(BSL_NODE_MAX)
  #define BSL_NODE_MAX 4
#endif

#if !defined(BSL_DEPTH)
  #define BSL_DEPTH 2
#endif

#if !defined(BSL_ROUNDS)
  #define BSL_ROUNDS 256
#endif

#if !defined(BSL_TYPE)
  #define BSL_TYPE int
#endif

#if !defined(BSL_SAVE_TMPFILE)
  #define BSL_SAVE_TMPFILE 0
#endif

#if !defined(BSL_RESULTS_FILE)
  #define BSL_RESULTS_FILE                                \
    BOOST_PP_STRINGIZE(BSL_TYPE)                          \
    BOOST_PP_STRINGIZE(BSL_EXP(BSL_NODE_MAX, BSL_DEPTH))  \
    "_results.xml"                                        \
  /**/
#endif

// utility print macro

#define BSL_PRINT(Z, N, T) T

// preprocessor power function, BSL_EXP

#define BSL_EXP_PRED(B, D) BOOST_PP_TUPLE_ELEM(3, 0, D)

#define BSL_EXP_OP(B, D)                                                       \
   (                                                                           \
      BOOST_PP_DEC(BOOST_PP_TUPLE_ELEM(3, 0, D)),                              \
      BOOST_PP_TUPLE_ELEM(3, 1, D),                                            \
      BOOST_PP_MUL_D(                                                          \
         B,                                                                    \
         BOOST_PP_TUPLE_ELEM(3, 2, D),                                         \
         BOOST_PP_TUPLE_ELEM(3, 1, D)                                          \
      )                                                                        \
   )                                                                           \
   /**/

#define BSL_EXP(X, N)                                                          \
  BOOST_PP_TUPLE_ELEM(                                                         \
    3, 2, BOOST_PP_WHILE(BSL_EXP_PRED, BSL_EXP_OP, (N, X, 1))                  \
  )                                                                            \
  /**/

// boost::archive::xml::node macros

#define BSL_NODE_DECL_MEMBER(Z, N, _)   T ## N  element ## N  ;
#define BSL_NODE_DECL_NONE(Z, N, _)     unused_type  element ## N  ;
#define BSL_NODE_xDECL_CTOR()           node (void) { }

#define BSL_NODE_DECL_CTOR(P)                                                  \
  BOOST_PP_IF(P,                                                               \
    BSL_NODE_xDECL_CTOR,                                                       \
    BOOST_PP_EMPTY                                                             \
  )()                                                                          \
  /**/

#define BSL_NODE_SERIALIZE(Z, N, _)                                            \
  & BOOST_SERIALIZATION_NVP(BOOST_PP_CAT(element, N))                          \
  /**/

#define BSL_NODE_INIT_LIST(Z, N, _)                                            \
  BOOST_PP_COMMA_IF(N)  BOOST_PP_CAT(element, N)                               \
  BOOST_PP_LPAREN() BOOST_PP_CAT(p, N) BOOST_PP_RPAREN()                       \
  /**/

#define BSL_NODE_DECL(Z, N, _)                                                 \
  template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename T)>                           \
  struct node<                                                                 \
    BOOST_PP_ENUM_PARAMS_Z(Z, N, T)                                            \
    BOOST_PP_COMMA_IF(N)                                                       \
    BOOST_PP_ENUM_ ## Z(BOOST_PP_SUB(BSL_NODE_MAX, N), BSL_PRINT, unused_type) \
  > {                                                                          \
    BOOST_PP_REPEAT_ ## Z(N, BSL_NODE_DECL_MEMBER, _)                          \
                                                                               \
    BOOST_PP_REPEAT_FROM_TO_ ## Z(N, BSL_NODE_MAX, BSL_NODE_DECL_NONE, _)      \
                                                                               \
    template<class ARC>                                                        \
    void serialize (ARC& ar, const unsigned int) {                             \
      ar BOOST_PP_REPEAT_ ## Z(N, BSL_NODE_SERIALIZE, _);                      \
    }                                                                          \
                                                                               \
    BSL_NODE_DECL_CTOR(N)                                                      \
                                                                               \
    node (BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, T, p)):                          \
      BOOST_PP_REPEAT_ ## Z(N, BSL_NODE_INIT_LIST, _) { }                      \
  };                                                                           \
  /**/

// instantiation macros

#define BSL_INST_BASE(Z, N, L)                                                 \
  T0 T0 ## _ ## N(BOOST_PP_ENUM_ ## Z(                                         \
    BSL_NODE_MAX, BSL_PRINT,                                                   \
    boost::archive::xml::random<BSL_TYPE> BOOST_PP_LPAREN() BOOST_PP_RPAREN()  \
  ));                                                                          \
  /**/

#define BSL_INST_yNODES(Z, N, L)                                               \
  BOOST_PP_COMMA_IF(N)                                                         \
  BOOST_PP_CAT(T,                                                              \
    BOOST_PP_CAT(BOOST_PP_LIST_AT(L, 1),                                       \
      BOOST_PP_CAT(_,                                                          \
        BOOST_PP_ADD(N,                                                        \
          BOOST_PP_LIST_AT(L, 0)                                               \
        )                                                                      \
      )                                                                        \
    )                                                                          \
  )                                                                            \
  /**/

#define BSL_INST_xNODES(Z, N, L)                                               \
  T ## L T ## L ## _ ## N(                                                     \
    BOOST_PP_REPEAT_ ## Z(                                                     \
      BSL_NODE_MAX, BSL_INST_yNODES,                                           \
      (BOOST_PP_MUL(N, BSL_NODE_MAX), (BOOST_PP_SUB(L, 1), BOOST_PP_NIL))      \
    )                                                                          \
  );                                                                           \
  /**/

#define BSL_INST_NODES(Z, N, L)                                                \
  BOOST_PP_REPEAT_ ## Z(                                                       \
    BSL_EXP(BSL_NODE_MAX, BOOST_PP_SUB(BSL_DEPTH, N)),                         \
    BSL_INST_xNODES, N                                                         \
  )                                                                            \
  /**/

#define BSL_TYPEDEF_NODES(Z, N, L)                                             \
  typedef boost::archive::xml::node<                                           \
    BOOST_PP_ENUM_ ## Z(                                                       \
      BSL_NODE_MAX, BSL_PRINT, BOOST_PP_CAT(T, BOOST_PP_SUB(N, 1))             \
    )                                                                          \
  > T ## N;                                                                    \
  /**/

// main macro

#define BSL_MAIN                                                               \
  int main (void) {                                                            \
    using namespace boost::archive;                                            \
    using namespace boost::archive::xml;                                       \
                                                                               \
    typedef node<BOOST_PP_ENUM(BSL_NODE_MAX, BSL_PRINT, BSL_TYPE)> T0;         \
                                                                               \
    BOOST_PP_REPEAT_FROM_TO(1, BSL_DEPTH, BSL_TYPEDEF_NODES, _)                \
                                                                               \
    typedef node<BOOST_PP_ENUM(                                                \
      BSL_NODE_MAX, BSL_PRINT,                                                 \
      BOOST_PP_CAT(T, BOOST_PP_SUB(BSL_DEPTH, 1))                              \
    )> HEAD;                                                                   \
                                                                               \
    result_set results;                                                        \
    std::size_t rounds = BSL_ROUNDS;                                           \
                                                                               \
    while (rounds --> 0) {                                                     \
      BOOST_PP_REPEAT(BSL_EXP(BSL_NODE_MAX, BSL_DEPTH), BSL_INST_BASE, _)      \
                                                                               \
      BOOST_PP_REPEAT_FROM_TO(1, BSL_DEPTH, BSL_INST_NODES, _)                 \
                                                                               \
      HEAD h(BOOST_PP_ENUM_PARAMS(                                             \
        BSL_NODE_MAX,                                                          \
        BOOST_PP_CAT(T, BOOST_PP_CAT(BOOST_PP_SUB(BSL_DEPTH, 1), _))           \
      ));                                                                      \
                                                                               \
      std::string fn = save_archive(h);                                        \
                                                                               \
      std::pair<double, HEAD> r = restore_archive<HEAD>(fn);                   \
                                                                               \
      std::cout << "round "                                                    \
                << ((BSL_ROUNDS - 1) - rounds)                                 \
                << " -> " << fn << "\n";                                       \
                                                                               \
      BOOST_PP_IF(BSL_SAVE_TMPFILE,                                            \
        BOOST_PP_EMPTY(),                                                      \
        std::remove(fn.c_str());                                               \
      )                                                                        \
                                                                               \
      results.entries.push_back(entry(                                         \
         BOOST_PP_STRINGIZE(BSL_TYPE),                                         \
         BSL_EXP(BSL_NODE_MAX, BSL_DEPTH), r.first                             \
      ));                                                                      \
    }                                                                          \
                                                                               \
    std::fstream fs(BSL_RESULTS_FILE, std::fstream::in);                       \
                                                                               \
    if (fs.good()) {                                                           \
      xml_iarchive ia(fs);                                                     \
      ia >> BOOST_SERIALIZATION_NVP(results);                                  \
      fs.close();                                                              \
    }                                                                          \
                                                                               \
    fs.open(BSL_RESULTS_FILE, std::fstream::out | std::fstream::trunc);        \
    xml_oarchive oa(fs);                                                       \
    oa << BOOST_SERIALIZATION_NVP(results);                                    \
                                                                               \
    fs.close();                                                                \
  }                                                                            \
  /**/

#endif // BOOST_SERIALIZATION_XML_PERFORMANCE_MACRO_HPP


text:
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, Indiana University,
// Bloomington, IN 47405.
//
// Permission to modify the code and to distribute the code is
// granted, provided the text of this NOTICE is retained, a notice if
// the code was modified is included with the above COPYRIGHT NOTICE
// and with the COPYRIGHT NOTICE in the LICENSE file, and that the
// LICENSE file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/kruskal_min_spanning_tree.hpp>
#include <fstream>
#include <iostream>

int
main()
{
  using namespace boost;
  typedef adjacency_list < vecS, vecS, undirectedS,
    no_property, property < edge_weight_t, int > > Graph;
  typedef graph_traits < Graph >::edge_descriptor Edge;
  typedef graph_traits < Graph >::vertex_descriptor Vertex;
  typedef std::pair<int, int> E;

  const int num_nodes = 5;
  E edge_array[] = { E(0, 2), E(1, 3), E(1, 4), E(2, 1), E(2, 3),
    E(3, 4), E(4, 0), E(4, 1)
  };
  int weights[] = { 1, 1, 2, 7, 3, 1, 1, 1 };
  int num_edges = sizeof(edge_array) / sizeof(E);
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
  Graph g(num_nodes);
  property_map<Graph, edge_weight_t>::type weightmap = get(edge_weight, g);
  for (std::size_t j = 0; j < num_edges; ++j) {
    Edge e; bool inserted;
    tie(e, inserted) = add_edge(edge_array[j].first, edge_array[j].second, g);
    weightmap[e] = weights[j];
  }
#else
  Graph g(edge_array, edge_array + num_edges, weights, num_nodes);
#endif
  property_map < Graph, edge_weight_t >::type weight = get(edge_weight, g);
  std::vector < Edge > spanning_tree;

  kruskal_minimum_spanning_tree(g, std::back_inserter(spanning_tree));

  std::cout << "Print the edges in the MST:" << std::endl;
  for (std::vector < Edge >::iterator ei = spanning_tree.begin();
       ei != spanning_tree.end(); ++ei) {
    std::cout << source(*ei, g) << " <--> " << target(*ei, g)
      << " with weight of " << weight[*ei]
      << std::endl;
  }

  std::ofstream fout("figs/kruskal-eg.dot");
  fout << "graph A {\n"
    << " rankdir=LR\n"
    << " size=\"3,3\"\n"
    << " ratio=\"filled\"\n"
    << " edge[style=\"bold\"]\n" << " node[shape=\"circle\"]\n";
  graph_traits<Graph>::edge_iterator eiter, eiter_end;
  for (tie(eiter, eiter_end) = edges(g); eiter != eiter_end; ++eiter) {
    fout << source(*eiter, g) << " -- " << target(*eiter, g);
    if (std::find(spanning_tree.begin(), spanning_tree.end(), *eiter)
        != spanning_tree.end())
      fout << "[color=\"black\"]\n";
    else
      fout << "[color=\"gray\"]\n";
  }
  fout << "}\n";
  return EXIT_SUCCESS;
}

max_stars_repo_name: HenrikBengtsson/RBGL

max_issues_repo_name: HenrikBengtsson/RBGL

max_forks_repo_name: HenrikBengtsson/RBGL


text:
#include <cstdlib>
#include <iostream>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/bindings/lower.hpp>
#include <boost/numeric/bindings/upper.hpp>
#include <boost/numeric/bindings/ublas/vector.hpp>
#include <boost/numeric/bindings/ublas/matrix.hpp>
#include <boost/numeric/bindings/blas/level2.hpp>
#include "print.hpp"
#include "random.hpp"

namespace ublas=boost::numeric::ublas;
namespace blas=boost::numeric::bindings::blas;

int main(int argc, char *argv[]) {
  {
    typedef ublas::vector<double> vector;
    typedef ublas::matrix<double, ublas::column_major> matrix;
    typedef vector::size_type size_type;
    rand_normal<double>::reset();
    size_type n=8;
    matrix A(n, n);
    for (size_type j=0; j<n; ++j) {
      A(j, j)=rand_normal<double>::get();
      for (size_type i=0; i<j; ++i) {
	A(i, j)=rand_normal<double>::get();
	A(j, i)=A(i, j);
      }
    }
    vector x(n);
    for (size_type i=0; i<n; ++i)
      x(i)=rand_normal<double>::get();
    double alpha(rand_normal<double>::get());
    matrix P;
    {
      P=alpha*ublas::outer_prod(x, x);
      for (size_type j=0; j<n; ++j)
	for (size_type i=0; i<j; ++i)
	  P(i, j)=0;
      matrix A1(P+A);
      matrix A2(A);
      blas::syr(alpha, x, blas::lower(A2));
      std::cout << print_mat(A1) << '\n'
		<< print_mat(A2) << '\n';
    }
    {
      P=alpha*ublas::outer_prod(x, x);
      for (size_type j=0; j<n; ++j)
	for (size_type i=j+1; i<n; ++i)
	  P(i, j)=0;
      matrix A1(P+A);
      matrix A2(A);
      blas::syr(alpha, x, blas::upper(A2));
      std::cout << print_mat(A1) << '\n'
		<< print_mat(A2) << '\n';
    }
  }
  return EXIT_SUCCESS;
}


text:
/*
 * Copyright 2021 4Paradigm
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gflags/gflags.h>
#include <sched.h>
#include <unistd.h>

#include <boost/bind.hpp>

#include "base/glog_wapper.h"
#include "base/kv_iterator.h"
#include "common/timer.h"
#include "gtest/gtest.h"
#include "proto/tablet.pb.h"
#include "tablet/tablet_impl.h"

DECLARE_string(endpoint);
DECLARE_string(db_root_path);
DECLARE_string(zk_cluster);
DECLARE_string(zk_root_path);
DECLARE_int32(zk_session_timeout);
DECLARE_int32(zk_keep_alive_check_interval);

using ::openmldb::zk::ZkClient;

namespace openmldb {
namespace tablet {

uint32_t counter = 10;
static bool call_invoked = false;
static size_t endpoint_size = 1;

inline std::string GenRand() { return std::to_string(rand() % 10000000 + 1); }  // NOLINT

void WatchCallback(const std::vector<std::string>& endpoints) {
    if (call_invoked) {
        return;
    }
    ASSERT_EQ(endpoint_size, endpoints.size());
    ASSERT_EQ("127.0.0.1:9527", endpoints[0]);
    call_invoked = true;
}

class MockClosure : public ::google::protobuf::Closure {
 public:
    MockClosure() {}
    ~MockClosure() {}
    void Run() {}
};

class TabletImplTest : public ::testing::Test {
 public:
    TabletImplTest() {}
    ~TabletImplTest() {}
};

TEST_F(TabletImplTest, KeepAlive) {
    FLAGS_endpoint = "127.0.0.1:9527";
    FLAGS_zk_cluster = "127.0.0.1:6181";
    FLAGS_zk_root_path = "/rtidb2";
    ZkClient zk_client(FLAGS_zk_cluster, "", 1000, "test1", FLAGS_zk_root_path);
    bool ok = zk_client.Init();
    ASSERT_TRUE(ok);
    ok = zk_client.Mkdir("/rtidb2/nodes");
    ASSERT_TRUE(ok);
    zk_client.WatchNodes(boost::bind(&WatchCallback, _1));
    ok = zk_client.WatchNodes();
    ASSERT_TRUE(ok);
    TabletImpl tablet;
    ok = tablet.Init("");
    ASSERT_TRUE(ok);
    ok = tablet.RegisterZK();
    ASSERT_TRUE(ok);
    sleep(5);
    ASSERT_TRUE(call_invoked);
}

}  // namespace tablet
}  // namespace openmldb

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);
    srand(time(NULL));
    ::openmldb::base::SetLogLevel(DEBUG);
    ::google::ParseCommandLineFlags(&argc, &argv, true);
    FLAGS_db_root_path = "/tmp/" + ::openmldb::tablet::GenRand();
    return RUN_ALL_TESTS();
}

max_stars_repo_name: jasleon/OpenMLDB

max_issues_repo_name: jasleon/OpenMLDB

max_forks_repo_name: jasleon/OpenMLDB


text:
#define BOOST_TEST_MODULE SolutionTest

#include "solution.hpp"

//#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(SolutionSuite)

BOOST_AUTO_TEST_CASE(PlainTest1)
{
    vector<int> nums{-2,1,-3,4,-1,2,1,-5,4};
    int result = Solution().maxSubArray(nums);

    int expected = 6;

    BOOST_CHECK_EQUAL(result, expected);
}

BOOST_AUTO_TEST_CASE(PlainTest2)
{
    vector<int> nums{-2, -5, 6, -2, -3, 1, 5, -6};
    int result = Solution().maxSubArray(nums);

    int expected = 7;

    BOOST_CHECK_EQUAL(result, expected);
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: johnhany/leetcode

max_issues_repo_name: johnhany/leetcode

max_forks_repo_name: johnhany/leetcode


text:
//
// Created by krab1k on 31/10/18.
//

#include <vector>
#include <cmath>
#include <Eigen/LU>

#include "denr.h"
#include "../structures/molecule.h"
#include "../parameters.h"

CHARGEFW2_METHOD(DENR)

std::vector<double> DENR::calculate_charges(const Molecule &molecule) const {

    size_t n = molecule.atoms().size();

    Eigen::MatrixXd eta = Eigen::MatrixXd::Zero(n, n);
    Eigen::MatrixXd L = Eigen::MatrixXd::Zero(n, n);
    Eigen::VectorXd chi = Eigen::VectorXd::Zero(n);
    Eigen::VectorXd q = Eigen::VectorXd::Zero(n);

    for (size_t i = 0; i < n; i++) {
        auto &atom_i = molecule.atoms()[i];
        chi(i) = parameters_->atom()->parameter(atom::electronegativity)(atom_i);
        eta(i, i) = parameters_->atom()->parameter(atom::hardness)(atom_i);
    }

    for (const auto &bond: molecule.bonds()) {
        auto i1 = bond.first().index();
        auto i2 = bond.second().index();
        L(i1, i1) += 1;
        L(i2, i2) += 1;
        L(i1, i2) -= 1;
        L(i2, i1) -= 1;
    }

    double step = parameters_->common()->parameter(common::step);

    Eigen::PartialPivLU<Eigen::MatrixXd> x = (Eigen::MatrixXd::Identity(n, n) + step * L * eta).partialPivLu();
    Eigen::VectorXd tmp = step * L * chi;
    for (int i = 0; i < parameters_->common()->parameter(common::iterations); i++) {
        q = x.solve(q - tmp);
    }

    return std::vector<double>(q.data(), q.data() + q.size());
}


text:
/*

Copyright (c) 2017-2018, Steven Siloti
Copyright (c) 2010, 2014, 2016-2021, Arvid Norberg
Copyright (c) 2020, Alden Torres
All rights reserved.

You may use, distribute and modify this code under the terms of the BSD license,
see LICENSE file.
*/

#include "libtorrent/aux_/disk_io_job.hpp"
#include "libtorrent/disk_buffer_holder.hpp"

#include "libtorrent/aux_/disable_warnings_push.hpp"
#include <boost/variant/get.hpp>
#include "libtorrent/aux_/disable_warnings_pop.hpp"

namespace libtorrent {
namespace aux {

namespace {
	struct caller_visitor
	{
		explicit caller_visitor(disk_io_job& j) : m_job(j) {}

		void operator()(job::read& j) const
		{
			if (!j.handler) return;
			j.handler(std::move(j.buf), m_job.error);
		}

		void operator()(job::write& j) const
		{
			if (!j.handler) return;
			j.handler(m_job.error);
		}

		void operator()(job::hash& j) const
		{
			if (!j.handler) return;
			j.handler(j.piece, j.piece_hash, m_job.error);
		}

		void operator()(job::hash2& j) const
		{
			if (!j.handler) return;
			j.handler(j.piece, j.piece_hash2, m_job.error);
		}

		void operator()(job::move_storage& j) const
		{
			if (!j.handler) return;
			j.handler(m_job.ret, std::move(j.path), m_job.error);
		}

		void operator()(job::release_files& j) const
		{
			if (!j.handler) return;
			j.handler();
		}

		void operator()(job::delete_files& j) const
		{
			if (!j.handler) return;
			j.handler(m_job.error);
		}

		void operator()(job::check_fastresume& j) const
		{
			if (!j.handler) return;
			j.handler(m_job.ret, m_job.error);
		}

		void operator()(job::rename_file& j) const
		{
			if (!j.handler) return;
			j.handler(std::move(j.name), j.file_index, m_job.error);
		}

		void operator()(job::stop_torrent& j) const
		{
			if (!j.handler) return;
			j.handler();
		}

		void operator()(job::file_priority& j) const
		{
			if (!j.handler) return;
			j.handler(m_job.error, std::move(j.prio));
		}

		void operator()(job::clear_piece& j) const
		{
			if (!j.handler) return;
			j.handler(j.piece);
		}

		void operator()(job::partial_read& j) const
		{
			if (!j.handler) return;
			j.handler(std::move(j.buf), m_job.error);
		}

	private:
		disk_io_job& m_job;
	};
}
	void disk_io_job::call_callback()
	{
		std::visit(caller_visitor(*this), action);
	}
}
}


text:
#ifndef TBODEINT_HPP_
#define TBODEINT_HPP_

/* Boost libs/numeric/odeint/examples/solar_system.cpp
 Copyright 2010-2012 Karsten Ahnert
 Copyright 2011 Mario Mulansky
 Solar system example for Hamiltonian stepper
 Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or
 copy at http://www.boost.org/LICENSE_1_0.txt)
 */

#include <iostream>
#include <array.hpp>

#include <boost/numeric/odeint.hpp>

//#include "point_type.hpp"
#include "body.hpp"
#include "threebodies.hpp"
#include <glm/vec3.hpp>
class Body;

class TB_odeint {
 public:
  static void updateSystem(ThreeBodies system, float deltaTime);
 private:
  friend OpenGLWindow;

  //Define universal gravitation constant
  double G = 6.67408e-11; //N-m2/kg2

  const size_t n = 3;

  typedef glm::vec3 point_type;
  typedef boost::array< point_type , n > container_type;
  typedef boost::array< double , n > mass_type;
    //]

  //[ coordinate_function
  //const double gravitational_constant = 2.95912208286e-4;
  const double gravitational_constant = 1.0;

  struct tb_system_coor{
    const mass_type &m_masses;

    tb_system_coor( const mass_type &masses ) : m_masses( masses ) { }

    void operator()( const container_type &p , container_type &dqdt ) const
    {
        for( size_t i=0 ; i<n ; ++i )
            dqdt[i] = p[i] / m_masses[i];
    }
  };
    //]

    //[ momentum_function
  struct tb_system_momentum{
    const mass_type &m_masses;

    tb_system_momentum( const mass_type &masses ) : m_masses( masses ) { }

    void operator()( const container_type &q , container_type &dpdt ) const
    {
        const size_t n = q.size();
        for( size_t i=0 ; i<n ; ++i )
        {
            dpdt[i] = 0.0;
            for( size_t j=0 ; j<i ; ++j )
            {
                point_type diff = q[j] - q[i];
                double d = abs( diff );
                diff *= ( gravitational_constant * m_masses[i] * m_masses[j] / d / d / d );
                dpdt[i] += diff;
                dpdt[j] -= diff;
            }
        }
    }
  };
    //]

  //[ streaming_observer
  struct streaming_observer{
    std::ostream& m_out;

    streaming_observer( std::ostream &out ) : m_out( out ) { }

    template< class State >
    void operator()( const State &x , double t ) const
    {
        container_type &q = x.first;
        m_out << t;
        for( size_t i=0 ; i<q.size() ; ++i ) m_out << "\t" << q[i];
        m_out << "\n";
    }
  };
//]

  point_type center_of_mass( const container_type &x , const mass_type &m );
  double energy( const container_type &q , const container_type &p , const mass_type &masses );
};

#endif

max_stars_repo_name: Lucas-Muniz/abcg

max_issues_repo_name: Lucas-Muniz/abcg

max_forks_repo_name: Lucas-Muniz/abcg