Adaptors: returning underlying container iterator (root) of adapted range (view)
- Dominant language
- C++
- Stars
- 45
- Forks
- 104
- PR merge metrics
- No merged PRs in 30d
Description
When I keep using iterators of adapted ranges (aka views) I find it very useful not having to use `range_iterator::base()` in order to access the underlying container iterator and currently iterated object.
I often find code like
if (auto rng = find(c | transformed(std::bind(&Object::name, _1)), v))
{
const Object& o = *rng.begin().base();
// ...
}
// or
if (auto it = find(c | transformed(std::bind(&Object::name, _1)), v);
it.base() != c.end())
{
const Object& o = *it.base();
// ...
}
Yes, it's just a matter of adding the call to `.base()`, however I always find less clutter to be worthwhile. The issue gets more obvious the more adaptors get chained.
Instead the intent can be expressed by additional `enum range_return_value` values.
Currently this is exactly what I am doing, using this header file:
#pragma once
#include
namespace kj
{
inline constexpr auto return_base_found = boost::range_return_value(boost::return_begin_end + 1);
inline constexpr auto return_base_found_end = boost::range_return_value(return_base_found + boost::return_found_end);
}
namespace boost
{
template
struct range_return
{
using iterator = typename range_iterator::type;
using type = typename iterator::base_type;
static type pack(iterator found, SinglePassRange&)
{
return found.base();
}
};
template
struct range_return
{
using iterator = typename range_iterator::type;
using base_iterator = typename iterator::base_type;
using type = boost::iterator_range;
static type pack(iterator found, SinglePassRange& rng)
{
return type(found.base(), boost::end(rng).base());
}
};
}
But extending the range_return handling in this way isn't perfect, and I think others can benefit as well.
That's why I propose extending `enum range_return_value` with the following enum values:
return_root_found,
return_root_next,
return_root_prior,
return_root_begin_found,
return_root_begin_next,
return_root_begin_prior,
return_root_found_end,
return_root_next_end,
return_root_prior_end,
return_root_begin_end,
At the very least I'd like to see a function, e.g. named `root_of()`, which walks the adaptor iterator chain and returns the root iterator, such that ...
const Object& o = *root_of(it);
... works transparently no matter how many iterator are layered on top of each other.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.