Skip to content

Dirty tricks

Fixing constructor issues (The dirty way)

if you have a class MyClass having some custom constructors or deleted constructors. A way to avoid dealing with constructors issues is to wrap the class in a std::unique_ptr.

Exemple :

struct MyClass{
    int* ptr;

    MyClass(){
        prt = new int(0);
    }

    ~MyClass(){
        delete ptr;
    }

}

Such class is ill formed in a non trivial way because it doesn't follow the rule of Three/Five/whatever c++ weird mechanics.

But if you wrap this type in a std::unique_ptr then it will behave correctly.

Container template

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;
}

Register function with static init

using fct_sig = std::function<void()>;

inline std::vector<fct_sig> static_init_fct_list {};

struct StaticInitClass{
    inline explicit MPIDTypeinit(fct_sig t){
        static_init_fct_list.push_back(std::move(t));
    }
};

If in the code you write the following code block :

void fct_to_register(){...}

void (*fct_ptr)() =fct_to_register;

StaticInitClass static_init_instance (fct_ptr);

The function fct_to_register will be in static_init_fct_list when the main function is ran.

Defining a protocol with hiden implementation

enum ProtocolMode{
    Mode1, Mode2, Mode3
};

namespace details{
    template<class T, ProtocolMode mode>
    class ProtocolImpl;
}


template<class T>
class VariantProtocol{public:

    template<ProtocolMode mode>
    using Impl = std::unique_ptr<details::ProtocolImpl<T,mode>>;

    std::variant<
        Impl<Mode1>, Impl<Mode2>, Impl<Mode3>
    > var_protocol;

    VariantProtocol(T arg, ProtocolMode mode){
        switch(mode){
        case Mode1:
            var_protocol = std::make_unique<details::ProtocolImpl<T,Mode1>>(arg);
            break;
        case Mode2:
            var_protocol = std::make_unique<details::ProtocolImpl<T,Mode2>>(arg);
            break;
        case Mode3:
            var_protocol = std::make_unique<details::ProtocolImpl<T,Mode3>>(arg);
            break;
        default:
            throw std::invalid_argument("unknown mode");
            break;
        }
    }

    void call(){
        std::visit([](auto & protocol){
            if(!protocol){
                throw std::invalid_argument("the protocol is not initialized");
            }
            protocol->call();
        }, var_protocol);
    }

};


int main(void){

    float in = 0.f;

    VariantProtocol prot {in, Mode1};

    prot.call();

}
namespace details{
    template<class T>
    class ProtocolImpl<T,Mode1>{
        T val;
        public:
        ProtocolImpl(T arg) : val(arg) {}
        void call(){
            std::cout << "protocol mode 1 " << val << std::endl;
        }
    };

    template<class T>
    class ProtocolImpl<T,Mode2>{
        T val;
        public:
        ProtocolImpl(T arg) : val(arg) {}
        void call(){
            std::cout << "protocol mode 2 " << val << std::endl;
        }
    };

    template<class T>
    class ProtocolImpl<T,Mode3>{
        T val;
        public:
        ProtocolImpl(T arg) : val(arg) {}
        void call(){
            std::cout << "protocol mode 3 " << val << std::endl;
        }
    };
}