Boost logo

Boost :

From: Bruno Lalande (bruno.lalande_at_[hidden])
Date: 2008-03-26 15:55:28


Hi,

> I'm not a big fan of the init_option constructor. Isn't the
> init_option almost always going to be defined at compile-time, thus the
> switch-case is wasteful.

I had also noticed this when reading the code, but I told myself that
the compiler can figure this out by itself and optimize. Just to
verify this, I've replaced the enum stuff by policies. On the way,
those policies also replace runtime indexing by compile-time indexing:

template <class P, int I>
struct initialize_point
{
        static void init(P& p, typename P::coordinate_type value)
        {
                p.template value<I-1>(value);
                initialize_point<P, I-1>::init(p, value);
        }
};

template <class P>
struct initialize_point<P, 0>
{ static void init(P&, typename P::coordinate_type) {} };

struct init_zero_t
{
        template <class P>
        static void init(P& p)
        { initialize_point<P, P::coordinate_count>::init(p, typename
P::coordinate_type()); }
};
init_zero_t init_zero;

struct init_min_infinite_t
{
        template <class P>
        static void init(P& p)
        { initialize_point<P, P::coordinate_count>::init(p,
boost::numeric::bounds<typename P::coordinate_type>::lowest()); }
};
init_min_infinite_t init_min_infinite;

struct init_max_infinite_t
{
        template <class P>
        static void init(P& p)
        { initialize_point<P, P::coordinate_count>::init(p,
boost::numeric::bounds<typename P::coordinate_type>::highest()); }
};
init_max_infinite_t init_max_infinite;

struct init_inverse_t {};
init_inverse_t init_inverse;

The constructor of point that used to do a switch on the enum is now a
template that can handle one of the policies defined (except for
init_inverse). This obviously makes it much shorter:

template <class init_policy>
inline point(init_policy policy)
{ policy.init(*this); }

The init_inverse is empty since it's handled in the box class itself:

template <class init_policy>
inline box(init_policy policy)
    : m_min(policy)
    , m_max(policy)
{}

inline box(init_inverse_t)
    : m_min(init_max_infinite)
    , m_max(init_min_infinite)
{}

The point_ll and point_xy classes' constructors are also adapted:

template <class init_policy>
inline point_ll(init_policy policy) : point<T, 2>(policy) {}

template <class init_policy>
inline point_xy(init_policy policy) : point<T, 2>(policy) {}

Tests show that the performances obtained are quite the same. The
compile-time version is not really faster since the for loops were
probably already unrolled by the compiler, and the switch statement
was also precomputed since it was based on a compile-time value. So
the choice between one version or the other is really a matter of
taste...

Bruno


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk