Boost logo

Boost Users :

Subject: Re: [Boost-users] [multi_index and flyweight]
From: Joaquin M Lopez Munoz (joaquin_at_[hidden])
Date: 2009-12-08 15:01:08


Samuel Charron <chammm <at> gmail.com> writes:
> On Fri, Dec 4, 2009 at 9:58 PM, Joaquin M Lopez Munoz
> <joaquin <at> tid.es> wrote:
> > Samuel Charron <samuel.charron <at> gmail.com> writes:
> >> I'd want to have a multi_index storing containers, and have one index
> >> based on all the contained elements.
> >> For example:
> >> two vectors [1 2 3] and [3 4] would be indexed as
> >> 1 -> [1 2 3]
> >> 2 -> [1 2 3]
> >> 3 -> [1 2 3] [3 4]
> >> 4 -> [3 4]
> >>
> >> How would you do that ?
> >
> > If I'm understanding your question well, you can do like
> > this:
> > [...]
>
> With your solution, my containers are sorted using all their values,
> it's not what I meant.
>
> My problem is that from any element from the container, I want to be
> able to retrieve the whole container.
>
> My index type would be the element contained, and the type of element
> contained in the multi_index would be the container type.
> The indices inserted would be all elements from my container, and the
> element would be one occurence of the container.

Ok, now I got it. The short ansewer is that Boost.MultiIndex
does not provide any off-the-shelf way to do what you want,
basically because each element (each vector in your case)
appears exactly once in any given index.

Long answer: you can approach your scenario by storing
"container positions" rather than containers and manually
inserting for each new conainer as many different positions
as elements has the container. Kind of as sketched in the
following program:

  #include <boost/assign/list_of.hpp>
  #include <boost/multi_index_container.hpp>
  #include <boost/multi_index/ordered_index.hpp>
  #include <boost/multi_index/mem_fun.hpp>
  #include <boost/shared_ptr.hpp>
  #include <vector>

  template<typename Container>
  struct container_pos
  {
    typedef typename Container::value_type value_type;
    typedef boost::shared_ptr<Container> container_ptr;

    container_pos(container_ptr ptr,std::size_t pos):ptr(ptr),pos(pos){}

    const value_type& get()const{return (*ptr)[pos];}

    container_ptr ptr;
    std::size_t pos;
  };

  typedef std::vector<int> container_type;
  typedef boost::shared_ptr<container_type> container_ptr;
  typedef container_pos<container_type> element;

  using namespace boost::multi_index;

  typedef multi_index_container<
    element,
    indexed_by<
      ordered_non_unique<
        const_mem_fun<element,const int&,&element::get>
>
>
> multi_t;

  template<typename PosContainer,typename Container>
  void multi_insert(PosContainer& c,boost::shared_ptr<Container> ptr)
  {
    for(std::size_t i=0,n=ptr->size();i<n;++i){
      c.insert(container_pos<Container>(ptr,i));
    }
  }

  int main()
  {
    multi_t m;
    container_ptr x(new container_type(boost::assign::list_of(1)(2)(3)));
    container_ptr y(new container_type(boost::assign::list_of(3)(4)));
    multi_insert(m,x);
    multi_insert(m,y);
  }

Is this what you're after?

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