Boost logo

Boost Users :

Subject: Re: [Boost-users] [Range] Range adaptors and compatibility with non-adapted iterators
From: Akira Takahashi (faithandbrave_at_[hidden])
Date: 2012-01-11 00:48:09


Hi John,

2012/1/11 John M. Dlugosz <mpbecey7gu_at_[hidden]>:
> Consider something like this:
>
>    themap_type::iterator search_for (int val)
>    {
>        return boost::find_if (themap|map_values, my_predicate(val));
>    }
>
>...
> Is there a good reason why the filtered iterator can't give up the inner
> original iterator?
> How do you use range adaptors in these situations?
>

I think this situation's better way is wrap by function template and
use boost::optional.
example:

#include <iostream>
#include <map>
#include <boost/optional.hpp>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/find_if.hpp>

template <class Range, class Predicate>
boost::optional<typename boost::range_value<Range>::type>
    search_for(const Range& r, Predicate pred)
{
    auto it = boost::find_if(r, pred);
    if (it == boost::end(r))
        return boost::none;
    return *it;
}

template <class MapRange, class Predicate>
boost::optional<typename MapRange::mapped_type>
    map_search_for(const MapRange& r, Predicate pred)
{
    return search_for(r | boost::adaptors::map_values, pred);
}

bool is_alice(const std::string& name)
{
    return name == "Alice";
}

int main()
{
    std::map<int, std::string> m = {{3, "Alice"}, {1,"Bob"}, {4, "Carol"}};
    if (boost::optional<std::string> name = map_search_for(m, is_alice)) {
        std::cout << "found:" << name.get() << std::endl;
    }
    else {
        std::cout << "not found" << std::endl;
    }
}

Thanks,

>>========================
 Akira Takahashi
blog : http://d.hatena.ne.jp/faith_and_brave/


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