Search code examples
c++boostconstantsboost-geometry

Initialization of a Boost point C++


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 !


Solution

  • 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.