Skip to content

Replacing C preprocessors

X macros

template< template<class> class Container >
class VariantContainer {
    std::variant<Container<f32>,Container<f64>> variant;
}

Such Variant container can be used as such

template<class T>
struct Field{
    std::vector<T> vec;
}

using VariantField = VariantContainer<Field>;

here VariantField is equivalent to a type like this :

class VariantField {
    std::variant<Field<f32>,Field<f64>> variant;
}

If defs

Usually you may have a Compile flag to toogle some features in C or Fortran code, in order to do so we usually write something like this

void func(){
    #ifdef DOSTUFF
        do_stuff();
    #else
        dont_do_stuff();
    #endif
}

In c++ such patern can be replaced by constexpr bool's.

// somewhere in the code
#ifdef DOSTUFF
    constexpr bool do_stuff_defined = true;
#else
    constexpr bool do_stuff_defined = false;
#endif

void func(){
    if constexpr (do_stuff_defined){
        do_stuff();
    }else{
        dont_do_stuff();
    }
}

since this if is marked as constexpr it will be evaluated at compile time, even without optimisation:

For clang 13.0.1 without any flags :

func():                               # @func()
    push    rbp
    mov     rbp, rsp
    call    dont_do_stuff()
    pop     rbp
    ret

here we have no comparaison, and do_stuff is not even referenced as expected