Opened 8 years ago

Closed 8 years ago

Last modified 7 years ago

#11113 closed Feature Requests (fixed)

Support easy enumeration of all elements with BOOST_FOREACH

Reported by: Thomas Trummer <th.trummer@…> Owned by: awulkiew
Milestone: Boost 1.59.0 Component: geometry
Version: Boost 1.57.0 Severity: Cosmetic
Keywords: rtree, iterator, range, for Cc:

Description

using namespace boost::geometry;
typedef model::d2::point_xy<double> point2_t; 

index::rtree<point2_t, index::quadratic<16>> tree;

BOOST_FOREACH(point2_t const& pt, tree)
{
    std::cout << wkt(pt) << std::endl;
}

Alternatively provide a predicate bgi:all that returns all elements and can be used with the queried adaptor.

Change History (3)

comment:1 by Barend Gehrels, 8 years ago

Owner: changed from Barend Gehrels to awulkiew

comment:2 by awulkiew, 8 years ago

Keywords: rtree iterator range for added
Resolution: fixed
Status: newclosed

Thanks for the suggestion!

Boost.Foreach and Boost.Range is now supported in develop branch and will be in Boost 1.59. I added const_iterator, begin() and end() members to the rtree. The category of iterator is ForwardIterator so the rtree is now adapted to (const) ForwardRange concept. It should be possible to adapt it to BidirectionalRange so if this was needed, just let me know.

Unfortunately the thing with queried() adaptor is more complicated. Currently it isn't a lazy-range but a container (wrapped std::vector). If it was used to iterate over all values stored in the rtree all of them would be copied into this container. I probably shouldn't change it to lazy-range now since currently it's a RandomAccessRange so e.g. it can be sorted, etc. A lazy-range would be ForwardRange, this could be a breaking change. But if you think it should be done please write a suggestion e.g. on the mailing list so we could discuss. I plan to fix it by implementing the "new" view::query() and cont::query() adaptors (currently a proposal so I'm waiting for the committee to know what names I could use) and deprecating the queried() adaptor.

For now (Boost <= 1.58) I propose a workaround. You could create a range representing all of the values stored in the rtree by yourself. You need to pass bgi::satisfies() predicate with a UnaryFunction always returning true into qbegin(). Well, there may be a problem, until now const_query_iterator was InputIterator. This might cause problems in some cases, e.g. related to Boost.Range concept checks. Besides the change you proposed I also upgraded const_query_iterator to ForwardIterator. But, I think that something like this could work:

struct always_true
{
    template <typename T>
    bool operator()(T const&) const { return true; }
};

// Return a range containing all Rtree elements
template <typename Rtree>
std::pair
    <
        typename Rtree::const_query_iterator,
        typename Rtree::const_query_iterator
    >
all(Rtree const& tree)
{
    return std::make_pair(tree.qbegin(bgi::satisfies(always_true())),
                          tree.qend());
}

/*...*/

BOOST_FOREACH(point2_t const& pt, all(tree))
{
    // ...
}

comment:3 by awulkiew, 7 years ago

Milestone: To Be DeterminedBoost 1.59.0
Note: See TracTickets for help on using tickets.