LH78
LH78

Reputation: 21

Using boost::geometry::index::indexable within an IndexableGetter in Windows

Building on top of this example:

https://www.boost.org/doc/libs/1_75_0/libs/geometry/doc/html/geometry/spatial_indexes/rtree_examples/using_indexablegetter_function_object___storing_indexes_of_external_container_s_elements.html

I have constructed the following MWE to build and query spatial trees based on indices onto non-trivial containers. The example this was based upon assumes that Container::value_type is already a leaf of the tree. I simply adapted the example to work with any indexable type, i.e., any type understood by bgi::indexable<typename Container::value_type>.

The included MWE works just fine on Linux and Mac, but fails to compile on Windows, and I'm struggling in understanding what the problem may be. A working example is here https://godbolt.org/z/vTT5r5MWc, where you can see that if you switch to gcc or clang, everything works, but with MSVC19 we get the errors reported below.

Any idea on how to modify the IndexableGetter/anything else to make this work under MSVC?

#include <boost/geometry/index/rtree.hpp>
#include <boost/geometry/strategies/strategies.hpp>
#include <boost/range/irange.hpp>

#include <iostream>


namespace bg  = boost::geometry;
namespace bgi = boost::geometry::index;

template <typename LeafType,
          typename IndexType       = bgi::linear<16>,
          typename IndexableGetter = bgi::indexable<LeafType>>
using RTree = bgi::rtree<LeafType, IndexType, IndexableGetter>;

using Point = bg::model::point<double, 2, bg::cs::cartesian>;

template <typename Container>
class IndexableGetterFromIndices
{
public:
  using IndexableGetter =
    typename bgi::indexable<typename Container::value_type>;

  using result_type = typename IndexableGetter::result_type;

  using size_t = typename Container::size_type;

  explicit IndexableGetterFromIndices(Container const &c)
    : container(c)
  {}

  result_type
  operator()(size_t i) const
  {
    return getter(container[i]);
  }

private:
  const Container &container;

  IndexableGetter getter;
};


template <typename IndexType = boost::geometry::index::linear<16>,
          typename ContainerType>
RTree<typename ContainerType::size_type,
      IndexType,
      IndexableGetterFromIndices<ContainerType>>
pack_rtree_of_indices(const ContainerType &container)
{
  boost::integer_range<typename ContainerType::size_type> indices(
    0, container.size());
  return RTree<typename ContainerType::size_type,
               IndexType,
               IndexableGetterFromIndices<ContainerType>>(
    indices.begin(),
    indices.end(),
    IndexType(),
    IndexableGetterFromIndices<ContainerType>(container));
}



int
main()
{
  std::vector<std::pair<Point, int>> points;
  // create some points
  for (unsigned i = 0; i < 10; ++i)
    points.push_back(std::make_pair(Point(i + 0.0, i + 0.0), i * 10));

  const auto tree = pack_rtree_of_indices(points);

  for (const auto result :
       tree | bgi::adaptors::queried(bgi::nearest(Point(3.0, 4.0), 1)))
    {
      std::cout << "Nearest point: " << bg::wkt<Point>(points[result].first)
                << ", index = " << points[result].second << std::endl;
    }
}

The error I get on Windows is

example.cpp
C:/data/libraries/installed/x64-windows/include\boost/geometry/index/rtree.hpp(1762): error C2664: 'boost::geometry::index::detail::translator<IndexableGetter,EqualTo>::translator(const boost::geometry::index::indexable<std::pair<Point,int>> &,const EqualTo &)': cannot convert argument 1 from 'const IndGet' to 'const boost::geometry::index::indexable<std::pair<Point,int>> &'
        with
        [
            IndexableGetter=IndexableGetterFromIndices<std::vector<std::pair<Point,int>,std::allocator<std::pair<Point,int>>>>,
            EqualTo=boost::geometry::index::equal_to<std::_Default_allocator_traits<std::allocator<std::pair<Point,int>>>::size_type>
        ]
        and
        [
            IndGet=IndexableGetterFromIndices<std::vector<std::pair<Point,int>,std::allocator<std::pair<Point,int>>>>
        ]
C:/data/libraries/installed/x64-windows/include\boost/geometry/index/rtree.hpp(1768): note: Reason: cannot convert from 'const IndGet' to 'const boost::geometry::index::indexable<std::pair<Point,int>>'
        with
        [
            IndGet=IndexableGetterFromIndices<std::vector<std::pair<Point,int>,std::allocator<std::pair<Point,int>>>>
        ]
C:/data/libraries/installed/x64-windows/include\boost/geometry/index/rtree.hpp(1762): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
C:/data/libraries/installed/x64-windows/include\boost/geometry/index/detail/translator.hpp(51): note: see declaration of 'boost::geometry::index::detail::translator<IndexableGetter,EqualTo>::translator'
        with
        [
            IndexableGetter=IndexableGetterFromIndices<std::vector<std::pair<Point,int>,std::allocator<std::pair<Point,int>>>>,
            EqualTo=boost::geometry::index::equal_to<std::_Default_allocator_traits<std::allocator<std::pair<Point,int>>>::size_type>
        ]

....

Upvotes: 2

Views: 518

Answers (1)

sehe
sehe

Reputation: 392893

Thanks for a very neat self-contained example.

It does compile with /std::latest:

In retrospect there was the clue:

cl : Command line warning D9002 : ignoring unknown option '-std=c++2a'

Upvotes: 1

Related Questions