Boost logo

Boost Users :

Subject: Re: [Boost-users] Multi Index: Nested std::pair
From: JOAQUIN M. LOPEZ MUÑOZ (joaquin_at_[hidden])
Date: 2009-04-26 10:49:17


________________________________________
De: boost-users-bounces_at_[hidden] [boost-users-bounces_at_[hidden]] En nombre de Etienne Philip Pretorius [icewolfhunter_at_[hidden]]
Enviado el: domingo, 26 de abril de 2009 16:17
Para: boost-users_at_[hidden]
Asunto: Re: [Boost-users] Multi Index: Nested std::pair

JOAQUIN M. LOPEZ MUÑOZ wrote:

> > First of all, you're defining a multi_index_container of *lists*,
> > i.e. each element of the container is a list of triplets (value,x,y).
> > Is this what you really meant, or maybe the std::list part has to be
> > dropped?
>
> Thank you. Yes, I'll drop the list. Each element should only be (value,x,y);

OK, let's analyze the problem then. For the sake of brevity we
first introduce the following typedef:

  typedef std::pair<
      /*value*/
      unsigned char,
      std::pair<
          /*x co-ordinate*/
          unsigned char,
          /*y co-ordinate*/
          unsigned char
>
> value_type;

The value extractor can be specified using boost::multi_index::member:

  boost::multi_index::member<
      value_type,
      unsigned char,
      &value_type::first
>

As for x and y, there is no way to do it with predefined extractors and we
have to write our own custom key extractor (http://tinyurl.com/dafk2f ):

  struct x_extractor
  {
      typedef unsigned char result_type;
      result_type operator()(const value_type& x)const
      {
          return x.second.first;
      }
  };

  struct y_extractor
  {
      typedef unsigned char result_type;
      result_type operator()(const value_type& x)const
      {
          return x.second.second;
      }
  };

So the final declaration looks like this:

  boost::multi_index_container<
      value_type,
      boost::multi_index::indexed_by<
          /*value*/
          boost::multi_index::ordered_non_unique<
              boost::multi_index::member<
                  value_type,
                  unsigned char,
                  &value_type::first
>
>,
          /*x co-ordinate*/
          boost::multi_index::ordered_non_unique<x_extractor>,
          /*y co-ordinate*/
          boost::multi_index::ordered_non_unique<y_extractor>
>
> m;

Nevertheless, I don't see any good reason why you have to define
your elements using such a convoluted combination of std::pairs.
You can have it in a more user friendly way, say:

  struct value_type
  {
      value_type(unsigned char value,unsigned char x,unsigned char y):
          value(value),x(x),y(y){}
      unsigned char value;
      unsigned char x;
      unsigned char y;
  };

which allows us you to define your multi_index_container without
resorting to custom key extractors:

  boost::multi_index_container<
      value_type,
      boost::multi_index::indexed_by<
          /*value*/
          boost::multi_index::ordered_non_unique<
              boost::multi_index::member<
                  value_type,
                  unsigned char,
                  &value_type::value
>
>,
          /*x co-ordinate*/
          boost::multi_index::ordered_non_unique<
              boost::multi_index::member<
                  value_type,
                  unsigned char,
                  &value_type::x
>
>,
          /*y co-ordinate*/
          boost::multi_index::ordered_non_unique<
              boost::multi_index::member<
                  value_type,
                  unsigned char,
                  &value_type::y
>
>
>
> m;

HTH.

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net