July 15, 2004
Given the following algorithm:

template Utility(T)
{
    alias NotionalRange!(T)         notional_range_type;
    alias RandomAccessRange!(T)     random_access_range_type;

    size_type r_distance(notional_range_type r)
    in
    {
        assert(null !== r);
    }
    body
    {
        size_type   n   =   0;

        for(; r.is_open; r.advance())
        {
            ++n;
        }

        return n;
    }

    size_type r_distance(random_access_range_type r)
    in
    {
        assert(null !== r);
    }
    body
    {
        return r.length();
    }

} // template Numeric

The compiler fails to select the RandomAccessRange overload of r_distance when given a range instance that derives from that interface.

The range interface inheritance hierarchy is as follows:

First, the range categories:

interface NotionalRangeTag
{}

    interface IterableRangeTag
        : public NotionalRangeTag
    {}

        interface SubscriptableRangeTag
            : public IterableRangeTag
        {}

            interface RandomAccessRangeTag
                : public SubscriptableRangeTag
            {}

Then the range interfaces:

template NotionalRange(T) { interface NotionalRange
    : public NotionalRangeTag
{
/// \name Member types
/// @{
public:
    alias   T                   value_type;
    alias   NotionalRangeTag    range_category;
/// @}

/// \name Notional range methods
/// @{
public:
    bool        is_open();
    value_type  current();
    void        advance();
/// @}
}}

template SubscriptableRange(T) { interface SubscriptableRange
    : public NotionalRange!(T)
    , public SubscriptableRangeTag
{
/// \name Member types
/// @{
public:
    alias   NotionalRange!(T)       parent_class_type;
public:
    alias   T                       value_type;
    alias   ptrdiff_t               index_type;
    alias   size_t                  size_type;
    alias   ptrdiff_t               difference_type;
    alias   RandomAccessRangeTag    range_category;
/// @}

/// \name Notional range methods
/// @{
public:
    bool        is_open();
    value_type  current();
    void        advance();
/// @}

/// \name Random access range methods
/// @{
public:
    size_type   length();
    value_type  opIndex(index_type index);
    void        advance(difference_type increment);
/// @}
}}


template RandomAccessRange(T) { interface RandomAccessRange
    : public SubscriptableRange!(T)
    , public RandomAccessRangeTag
{
}}

Bet you want me to boil that down, eh? :-)



July 17, 2004
"Matthew Wilson" <admin.hat@stlsoft.dot.org> wrote in message news:cd5gg6$1rnv$1@digitaldaemon.com...
> Bet you want me to boil that down, eh? :-)

Yes, please.