Boost logo

Boost :

From: Joaquín Mª López Muñoz (joaquin_at_[hidden])
Date: 2003-10-30 05:34:36


Hi Vladimir

Vladimir Prus ha escrito:

> some time ago I wrote a class called numbered_set. It was like a set (i.e
> efficiently checked for duplicates) but had additional integer index, so
> that all elements could be obtained by the index in constant time.
>
> Will it be possible to mimic this functionality using your library? I've
> quickly browsed the docs and did not find if it's possible.
>

I don't think so. Lookup in indexed_set is logarithmic, not constant.
Your class resembles more an "ordered vector" container, I think
Matt Austern wrote something about this some years ago.

>
> One more small comment. The 'tagged indices' might not be the right
> solution: they mean that I need to introduce more-or-less global type
> 'name' just because I want to store employee in an indexed_set. Is it
> workable to use 'member' function to specify index. E.g. instead of
>
> typedef employee_set::index_type<name>::type employee_set_by_name;
>
> to write
>
> typedef employee_set::index_type<
> member<employee, std::string, &employee::name> >::type
> employee_set_by_name;
>

You can do that. Any type can be specified as a tag, even member<...>
as you propose. No modifications needed in the library, just use member<...>
as the tag when declaring your indexed_set instantiations.
If you're concerned about global namespace polluting, you can have the
tags typedefed inside the employee class, for instance:

class employee
{
  ...
  struct name_tag{};
}

typedef indexed_set<
  employee,
  index_list<
    unique<identity<employee> >,

non_unique<tag<employee::name_tag>,member<employee,std::string,&employee::name> >
>
> employee_set;

typedef employee_set::index_type<employee::name_tag>::type employee_set_by_name;

Get the idea?

>
> I also think that
>
> member<employee, std::string, &employee::name>
>
> is too verbose, though I'm not all all sure it can be made shorter.

There was a discussion about this some months ago, and the general
consensus is that it cannot be shortened (no way to extract
the info from say just &employee_name.)
The macro BOOST_INDEXED_MEMBER, though not intended as
an abbreviation utility, provides a slightly simpler syntax. Take a look
at the advanced topics section for more info on this macro.

>
> And the final note: what if employee::name is a method, not member variable?
> This does not seem to be supported. It it by design, technical problems or
> lack of time?

It is supported. Key extractors need not be instantiations of member<> or
identity<>, the user can provide her own extractors. Continuing with your
proposed example, one would do as follows:

#include <boost/indexed_set.hpp>
#include <iostream>
#include <string>

using namespace std;
using namespace boost::indexed_sets;

struct employee
{
  employee(string given_name,string family_name):
    given_name(given_name),family_name(family_name)
  {}

  string name()const
  {
    string str=family_name;
    str+=" ";
    str+=given_name;
    return str;
  }

private:
  string given_name;
  string family_name;
};

struct employee_name_extractor
{
  typedef employee argument_type;
  typedef string result_type;

  string operator()(const employee& e)const{return e.name();}
};

typedef indexed_set<
  employee,
  index_list<
    unique<employee_name_extractor>
>
> employee_set;

int main()
{
  employee_set es;

  es.insert(employee("Joe","Smith"));
  es.insert(employee("Robert","Nightingale"));
  es.insert(employee("Robert","Brown"));
  es.insert(employee("Marc","Tuxedo"));

  for(employee_set::iterator it=es.begin();it!=es.end();++it){
    cout<<it->name()<<endl;
  }

  return 0;
}

Here key extraction is made thru employee_name_extractor. Naturally,
one cannot use modify_key() with such extractor (it does not return references),
but this is perfectly logical.

Whether this kind of constructs (key extractors based on members) should
be provided as a predefined utility or not depends, I guess, on how common a
situation we deem this to be.

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


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