|
Boost : |
Subject: [boost] [iterators]: collection_keys and collection_values
From: Igor Lubashev (igorlord_at_[hidden])
Date: 2012-07-25 14:06:26
I'd like to propose adding collection_keys and collection_values to iterators library.
======== Motivation ========
I find myself very often having to iterate over all keys or values of a map (or multimap). The best I can do is to use BOOST_FOREACH to iterate over the collection value_type pairs and then work with .first or .second. That makes for awkward and unclear code.
BOOST_FOREACH( const foo_bar_map_t::value_type &foo_bar_pair, my_map )
{
baz(foo_bar_pair.second);
}
Instead, I'd like to do something like:
BOOST_FOREACH( const bar_t &bar, collection_values(my_map) )
{
baz(bar);
}
BOOST_FOREACH( const foo_t &foo, collection_keys(my_map) )
{
baz(foo);
}
======== Proposal ========
Add this to iterators library as collection_iterators.hpp
Thanks,
- Igor
#ifndef ....
#define ....
#include <boost/iterator/transform_iterator.hpp>
namespace boost
{
namespace detail
{
template<typename CollectionT>
struct key_function : public std::unary_function<const typename CollectionT::value_type&,
const typename CollectionT::key_type&>
{
typename key_function::result_type operator()(typename key_function::argument_type p) const
{
return p.first;
}
};
template<typename CollectionT>
struct value_function : public std::unary_function<const typename CollectionT::value_type&,
const typename CollectionT::mapped_type&>
{
typename value_function::result_type operator()(typename value_function::argument_type p) const
{
return p.second;
}
};
template<typename CollectionT, typename AdapterF>
class collection_adapter
{
const CollectionT &c;
public:
typedef boost::transform_iterator<AdapterF, typename CollectionT::const_iterator> const_iterator;
typedef const_iterator iterator;
collection_adapter(const CollectionT &c) : c(c) {}
const_iterator begin() const { return boost::make_transform_iterator(c.begin(), AdapterF()); }
const_iterator end() const { return boost::make_transform_iterator(c.end(), AdapterF()); }
};
}
// Adapter for map-like collection -> iterable keys collection
template<typename CollectionT>
const detail::collection_adapter<CollectionT, detail::key_function<CollectionT> >
collection_keys(const CollectionT &c)
{
return detail::collection_adapter<CollectionT, detail::key_function<CollectionT> >(c);
}
// Adapter for map-like collection -> iterable values collection
template<typename CollectionT>
const detail::collection_adapter<CollectionT, detail::value_function<CollectionT> >
collection_values(const CollectionT &c)
{
return detail::collection_adapter<CollectionT, detail::value_function<CollectionT> >(c);
}
} // namespace boost
#endif // ....
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk