I'm using the Boost libraries to manipulate points in a N-dimensional domain. The problem is that I cannot find a way to initialize them without setting each coordinate separately.
To get or set coordinates with this library, one should use :
bg::model::point<double, 2, bg::cs::cartesian> point1; // Declaration
point1.set<0>(1.0); // Coordinate 0 set
point1.set<1>(2.0); // Coordinate 1 set
double x = point1.get<0>(); // Coordinate 0 get
double y = point1.get<1>(); // Coordinate 1 get
You can find example and information at https://www.boost.org/doc/libs/1_67_0/libs/geometry/doc/html/geometry/reference/models/model_point.html
However, I work with points in a N-dimensional space, with N > 100, and I cannot afford to write a line of code for each coordinate manually. But something like this :
bg::model::point<double, 2, bg::cs::cartesian> point1;
for(int i(0); i<NDIM; ++i){
point1.set<i>(1.0);
}
does not work, because the index of the coordinates needs to be a const value. Could you help me find a way to automatically initialize the coordinates? I tried a lot of things, nothing worked !
You could use variadic templates and std::index_sequence
to deduce indexes from NDIM
and process all together using the unpacking syntax:
template <class Point, size_t... I>
void init(Point& p, std::index_sequence<I...>)
{
int dummy[] = { (p.set<I>(1.0), 0)... };
(void)dummy;
}
The syntax (void_func(), 0)
calls a void function, but returns 0
. This is necessary because you cannot use the unpack syntax ...
for void functions. Assigning it to an array and using that (e.g. casting it to void
) makes sure nothing gets optimized away.
Then call this function like so:
init(point1, std::make_index_sequence<NDIM>());
Note that NDIM
must be const
.
For more details on how index_sequence
works take a look here.