I am not very familiar with boost geometry but it seems you have to iterate through the coordinates at compile time. The way to do this is by creating a recursion. The class apply
below will perform such recursion and call a functor on each coordinate of the point.
All you have to do is to write your own functor and overload its operator() in case you want to specialise behaviour for certain coordinates. The functor in the example below simply prints the coordinates and is specialised when reading the 3rd coordinate.
#include <boost/geometry.hpp>
#include <iostream>
#include <type_traits>
namespace bg = boost::geometry;
template <int I>
using int_ = std::integral_constant<int, I>;
//recursive call that iterates the point and calls F on its coordinate
template <class Point, class F, std::size_t I = 0>
struct apply {
static void call(Point& point, F& f) {
f(point, int_<I>());
apply<Point, F, I+1>::call(point, f);
}
};
//specialisation to end the recursion
template <class CT, std::size_t DIM, class S, template <class, std::size_t, class> class Point, class F>
struct apply<Point<CT, DIM, S>, F, DIM> {
static void call(Point<CT, DIM, S>& point, F& f){}
};
//interface for calling the function
template <class Point, class F>
void apply_functor(Point& point, F& f) {
apply<Point, F>::call(point, f);
}
//example functor
template <class Point>
struct functor {
template <class Index>
void operator()(Point& point, Index I) {
std::cout << "I am coordinate " << Index::value << " and my value is " << bg::get<Index::value>(point) << std::endl;
}
// used for overloading when reading the 3rd coordinate
void operator()(Point& point, int_<2>) {
std::cout << "I am coordinate " << 2 << " and I am specialised with value " << bg::get<2>(point) << std::endl;
}
};
//3-dimensional point type
using point_type = bg::model::point<double, 3, bg::cs::cartesian>;
int main(int argc, char** argv) {
point_type point(1,2,3);
functor<point_type> f;
apply_functor(point, f);
return 0;
}