An example of using base iterator in C++

The code below demonstrates how to access underlying range iterator by transformed iterator:

struct A
{
    int x;
};

struct B
{
    A* a;
};

std::vector<B> v;

int main()
{
    auto a_range = v | std::views::transform(std::mem_fn(&B::a));

    auto i = std::ranges::find(a_range, 5, std::mem_fn(&A::x));

    A* a = *i;

    B& b = *(i.base());
}

It is also possible to do something like this:

auto accounts = facades() | std::views::transform(std::mem_fn(&MarketFacade::account));

auto found_range = accounts | std::views::filter(std::bind(std::equal_to(), account, std::placeholders::_1));

auto base_range = std::ranges::subrange(found_range.begin().base(), found_range.end().base());

Another alternative:

// For using with std::ranges::filter without std::bind.
template <class Field, class Proj>
class projected_equal_to
{
public:

    projected_equal_to(Field field, Proj proj) :
        m_proj(proj),
        m_field(std::move(field))
    {}

    bool operator() (const auto& object_val) const
    {
        return std::invoke(m_proj, object_val) == m_field;
    }

private:

    Proj m_proj;
    Field m_field;
};

template <class Value, class Field>
auto bound_mem_fn(Field(Value::* field_ptr)() const, Field field)
{
    return projected_equal_to<Field, decltype(field_ptr)>(field, field_ptr);
}

auto accountFacades(data::AccountType account) const
{
    return facades() | std::views::filter(awl::bound_mem_fn(&MarketFacade::account, account));
}

1 Response to An example of using base iterator in C++

  1. dmitriano says:

    https://stackoverflow.com/questions/65912645/is-there-any-possible-way-to-get-origin-value-using-transformed-iterator
    It’s possible to get an iterator to the underlying range by calling .base().

Leave a Reply

Your email address will not be published. Required fields are marked *