Search code examples
c++cmakecompilationaliasusing

Compile same source with diffrent aliases


TLDR: Can you compile the same source code with different headers defining diffrent aliases?

I have created a library, with a set of functions coded using a couple of aliased type in the header.

algorithm_2d.h

using Point = Eigen::Vector2d;
using Vector = Eigen::Vector2d;

algorithm.cpp

Vector& scale_vector(
    Vector &v,
    double s)
{
    double len = v.norm();
    if (len != 0.0) { v *= s/len;}
    return v;
}

double distance_between_points(
    Point const &p1,
    Point const &p2)
{
    return (p2 - p1).norm();
}

Now I would like to compile the same algorithm.cpp but with different aliases:

algorithm_3d.h

using Point = Eigen::Vector3d;
using Vector = Eigen::Vector3d;

I am building using CMake with pybind11 as this is mainly a python library.

I would prefer not having to use templates, as that would cause me to have to define every single type in every function. And as you can see in the snippet, it would make it a lot less readable, and this is already a mathematically complicated algorithm (rest of the code not shown).

EDIT:

Another example to make it clear what I mean by using the aliases. If I were using templates, each time this function is called

.h

using PointSet = std::vector<Point, Eigen::aligned_allocator<Point> >;

.cpp

Vector compute_left_tangent(
    PointSet const &pts,
    int end,
{
    Vector tHat1 = PointSet[end+1] - PointSet[end];
    tHat1 = tHat / distance_between_points(PoinSet[end],PointSet[end+1]) 
}

I don't want to have to add the <Eigen::Vector2d,..., etc> every time I call one of these functions. Maybe there is a way of doing this with templates that I am missing?


Solution

  • Given the following template file: (call it algorithm.cpp.tmpl)

    using Point = @_flavor@;
    using Vector = @_flavor@;
    #include "algorithm.cpp"
    

    You can have CMake generate flavors automatically and build them as part of some_target:

    set(FLAVORS Eigen::Vector2d Eigen::Vector3d)
    foreach(_flavor ${FLAVORS})
      string(MAKE_C_IDENTIFIER ${_flavor} _flavor_slug)
      set(_flavor_out algorithm_${_flavor_slug}.cpp)
      configure_file(algorithm.cpp.tmpl ${_flavor_out} @ONLY)
      target_sources(some_target PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/${_flavor_out})
    endforeach()