|
Boost Users : |
From: Ovanes Markarian (om_boost_at_[hidden])
Date: 2007-08-21 07:26:34
Joaquin,
thanks for your reply. I have to think about your suggestions. Some ideas
which come up to my mind now are:
1. Locator is clearly a better choice, but not always. In some use cases you
might find a range if a container allows multi-indexed values. In this case
one would need to make second search to find subsequent values??? Or miss
them at all...
2. In the example with:
boost::iterator_range<std::set
>
> <std::string>::const_iterator> r=
> find_range(...);
The class value_retrieval contains a result_type which provides the shortcut
to iterator_range<...>
3. My idea in using iterator range relies on fact that one can retrieve a
valid or invalid range and operate on it within one search. Your idea with
there_exists requires a second search to retrieve the value. Since a typical
use case would be:
if(there_exists(some_container, "some_key"))
some_value = *some_container.find("some_key");
and that is not so efficient as:
iter_range range = find_range(some_container, "some_key");
if(range)
some_value = range.front();
I will think about other suggestions and mail them later in ;)
Many thanks again,
Ovanes
On 8/21/07, "JOAQUIN LOPEZ MU?Z" <joaquin_at_[hidden]> wrote:
>
> Hello Ovanes,
>
> ----- Mensaje original -----
> De: Ovanes Markarian <om_boost_at_[hidden]>
> Fecha: Lunes, Agosto 20, 2007 1:35 pm
> Asunto: [Boost-users] [boost::multi-index] improvement suggestion
> Para: boost-users_at_[hidden]
>
> > Hello all,
> >
> > working with boost multi-index container requires sometimes some
> > effort in regards of correct tagging (or at least some typing
> > work ;). I found the following approach to be useful and may be
> > it can be integrated in the multi-index library.
> >
> > First of all the dealing with searchable collections (STL
> > collections are no exception) can be really nasty in regards of
> > finding an iterator and comparing it with the end iterator. The
> > following function can really be of help:
> >
> [...]
> > template<class T, class K>
> > inline boost::iterator_range<typename T::const_iterator>
> > find_range(T const& container, K const& key)
> > {
> > return
> > boost::make_iterator_range(
> > container.find(key),container.end());
> > }
> >
> > //non-const version follows as well ...
> >
> > Actually iterator_range defines a "bool"- and "!"- (NOT) operators.
> > iterator_range is returned by this function. Therefore constructs
> > like:
> > std::set<std::string> some_set;
> >
> > if(!find_range(some_set, "my_key"))
> > some_set.insert("my_key");
> >
> > are possible without the need of accesing the underlying iterator
> > types or explicitly comparing the found iterator with the end
> > iterator.
>
> I've got some doubts about your construct:
>
> 1. The syntax to check whether a value has been found or not is
> certainly clearer, but at the expense of a more convoluted
> expression to get the value found:
>
> const std::string& v=
> *boost::begin(find_range(some_set,"my_key"));
>
> And the type of the construct returned by find_range is also somewhat
> messy to type down (at least until compilers come with decltype and
> auto):
>
> boost::iterator_range<std::set<std::string>::const_iterator> r=
> find_range(...);
>
> 2. If, given the complexities associated to getting the value with
> find_range, you propose it only as a way to verify whether the value
> exists, there are simpler alternatives which do not use Boost.Range:
>
> template<class T,class K>
> bool there_exists(T const& container, K const& key)
> {
> return container.find(key)!=container.end();
> }
>
> 3. find_range does return a range, but this range is in no
> sensible way related to the key passed, except that its
> first element, if the range is not void, contains the key.
> But the rest of the elements have nothing to do with the key,
> and what is worse, elements with the key might not be
> contained in the range, since find does not guarantee that
> the element found is the first one with the key.
>
> 4. So, if you want a concise syntax to determine whether
> an element is found or not, plus simple access to this element,
> maybe you can write an utility of your own exactly suited
> to this task, rather than relying on Boost.Range. I'm thinking
> about something like this:
>
> // locator can be pointing to an element or not. If the
> // former, dereferencing it is legal.
>
> template<typename Container>
> struct locator
> {
> typedef typename Container::value_type;
> operator bool()const;
> bool operator!()const;
> const value_type& operator*()const;
> ...
> };
>
> template<class T,class K>
> locator<T> find(T const& container, K const& key)
> {
> ...
> }
>
> Don't you find this more convenient?
>
> >
> > The next step dealing with Multi-Index container turned out in
> > multipletypedefs for every tagged type. The main disadvantage in
> > this approach was to constantly retrieve the required container
> > view and related iterator, so I came up the the following class:
> [...]
>
> This also could benefit of a more specific locator-based interface,
> IMHO.
>
> Best,
>
> Joaquín M López Muñoz
> Telefónica, Investigación y Desarrollo
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>
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