[C++-sig] Re: indexing_v2 status update

Raoul Gough RaoulGough at yahoo.co.uk
Wed Jan 21 21:28:27 CET 2004


Raoul Gough <RaoulGough at yahoo.co.uk> writes:

> David Abrahams <dave at boost-consulting.com> writes:
>
>> Raoul Gough <RaoulGough at yahoo.co.uk> writes:
[snip]
>>> I've been wondering about what the container suite
>>> interface should look like after moving to feature sets instead of
>>> static boolean constants. I'm thinking along these lines:
>>>
>>> template<
>>>      class Container,
>>>      SOME_KIND_OF_SET features = supported_features<Container>,
>>>      class Algorithms = algorithms<Container>
>>>> container_suite;
[snip]
>>
>> Nope; so far it sounds great.
>
> OK, thanks! I think I'll go with the supported_features approach.

This is how the new implementation is actually looking:

  template<
      class Container,
      unsigned int MethodMask = all_methods,  // All supported by algorithms
      class Algorithms = algorithms<Container>
  >
  struct container_suite /* ... */;

The second template parameter is an unsigned bitmask that gets
combined with a "supported_methods" value provided by the Algorithms
argument. It worked out this way because determining what features
should be supported by default depends on the value type as well as
the type of container (i.e. it needs to know equality_comparable and
less_than_comparable from the value_traits template).

Here is the new vector_traits template, which works out what methods
to provide (by default) for instances of std::vector:

  template<typename Container, typename ValueTraits = detail::no_override>
  class vector_traits
    : public default_container_traits<Container, ValueTraits>
  {
    typedef default_container_traits<Container, ValueTraits> base_class;
    BOOST_STATIC_CONSTANT(bool, is_mutable = !is_const<Container>::value);

  public:
    typedef typename base_class::value_traits_type value_traits_type;

    BOOST_STATIC_CONSTANT(
        unsigned int,
        supported_methods = (
              method_len
            | method_getitem
            | method_getitem_slice

            | detail::unsigned_if<
                  value_traits_type::equality_comparable,
                    method_index
                  | method_contains
                  | method_count
              >::value

            | detail::unsigned_if<
                  is_mutable,
                    method_setitem
                  | method_setitem_slice
                  | method_delitem
                  | method_delitem_slice
                  | method_reverse
                  | method_append
                  | method_insert
                  | method_extend
              >::value

            | detail::unsigned_if<
                  type_traits::ice_and<
                      is_mutable, value_traits_type::less_than_comparable
                  >::value,
                  method_sort
              >::value

        ));

        // Never supported: method_iter, method_has_key
  };

In case you really wanted to know, unsigned_if looks like this:

  namespace detail {
    template<bool Cond, unsigned int TrueValue, unsigned int FalseValue = 0>
    struct unsigned_if {
      struct true_type {
        BOOST_STATIC_CONSTANT(unsigned int, value = TrueValue);
      };

      struct false_type {
        BOOST_STATIC_CONSTANT(unsigned int, value = FalseValue);
      };

      typedef typename mpl::if_c<Cond, true_type, false_type>::type
          result_type;

      BOOST_STATIC_CONSTANT(unsigned int, value = result_type::value);
    };
  }

I've tested this much under gcc 3.3.1 and MSVC6.0 and 7.1. So before I
get too carried away and convert everything to this new style, does
Dave, Joel, or anyone else have comments or suggestions?

-- 
Raoul Gough.
export LESS='-X'





More information about the Cplusplus-sig mailing list