<commit_before>/**
 *  @author <NAME> <<EMAIL>>
 */

#ifndef ALLPIX_DELEGATE_H
#define ALLPIX_DELEGATE_H

#include <typeinfo>
#include <memory>
#include <cassert>

#include "Message.hpp"
#include "../utils/exceptions.h"

namespace allpix {
    // base class for all delegates (template type erasure)
    class BaseDelegate {
    public:
        BaseDelegate() {}
        virtual ~BaseDelegate() {}
        
        virtual void call(std::shared_ptr<Message> msg) const = 0;
    };

    // delegate for receiver functions
    template<typename T, typename R> class Delegate : public BaseDelegate{
    public:
        using ListenerFunction = void (T::*)(std::shared_ptr<R>);
        
        Delegate(T *obj, ListenerFunction method): obj_(obj), method_(method) {}
        ~Delegate() {}
        
        void call(std::shared_ptr<Message> msg) const {
            // the type names should have been correctly resolved earlier
            assert(typeid(*msg) == typeid(R));
            
            // NOTE: this dynamic cast is not perfect, but otherwise dynamic linking will break
            (obj_->*method_)(std::dynamic_pointer_cast<R>(msg));
        }
    private:
        T *obj_;
        ListenerFunction method_;
    };
    
    // delegate for single bound shared pointer
    template<typename T, typename R> class SingleBindDelegate : public BaseDelegate{
    public:
        using BindType = std::shared_ptr<R> T::*;
        
        SingleBindDelegate(T *obj, BindType member): obj_(obj), member_(member) {}
        ~SingleBindDelegate() {}
        
        void call(std::shared_ptr<Message> msg) const {
            // the type names should have been correctly resolved earlier
            assert(typeid(*msg) == typeid(R));
            
            // FIXME: check that this assignment does not remove earlier information
            
            // NOTE: this dynamic cast is not perfect, but otherwise dynamic linking will break
            obj_->*member_ = std::dynamic_pointer_cast<R>(msg);
        }
    private:
        T *obj_;
        BindType member_;
    };
    
    // delegate for a vector of messages that can be received
    template<typename T, typename R> class VectorBindDelegate : public BaseDelegate{
    public:
        using BindType = std::vector<std::shared_ptr<R>> T::*;
        
        VectorBindDelegate(T *obj, BindType member): obj_(obj), member_(member) {}
        ~VectorBindDelegate() {}
        
        void call(std::shared_ptr<Message> msg) const {
            // the type names should have been correctly resolved earlier
            assert(typeid(*msg) == typeid(R));
            
            // NOTE: this dynamic cast is not perfect, but otherwise dynamic linking will break
            (obj_->*member_).push_back(std::dynamic_pointer_cast<R>(msg));
        }
    private:
        T *obj_;
        BindType member_;
        
    };
}

#endif /* ALLPIX_DELEGATE_H */<commit_msg>use static cast as dynamic cast should never fail<commit_after>/**
 *  @author <NAME> <<EMAIL>>
 */

#ifndef ALLPIX_DELEGATE_H
#define ALLPIX_DELEGATE_H

#include <typeinfo>
#include <memory>
#include <cassert>

#include "Message.hpp"
#include "../utils/exceptions.h"

namespace allpix {
    // base class for all delegates (template type erasure)
    class BaseDelegate {
    public:
        BaseDelegate() {}
        virtual ~BaseDelegate() {}
        
        virtual void call(std::shared_ptr<Message> msg) const = 0;
    };

    // delegate for receiver functions
    template<typename T, typename R> class Delegate : public BaseDelegate{
    public:
        using ListenerFunction = void (T::*)(std::shared_ptr<R>);
        
        Delegate(T *obj, ListenerFunction method): obj_(obj), method_(method) {}
        ~Delegate() {}
        
        void call(std::shared_ptr<Message> msg) const {
            // the type names should have been correctly resolved earlier
            assert(typeid(*msg) == typeid(R));
            
            // NOTE: this dynamic cast is not perfect, but otherwise dynamic linking will break
            (obj_->*method_)(std::static_pointer_cast<R>(msg));
        }
    private:
        T *obj_;
        ListenerFunction method_;
    };
    
    // delegate for single bound shared pointer
    template<typename T, typename R> class SingleBindDelegate : public BaseDelegate{
    public:
        using BindType = std::shared_ptr<R> T::*;
        
        SingleBindDelegate(T *obj, BindType member): obj_(obj), member_(member) {}
        ~SingleBindDelegate() {}
        
        void call(std::shared_ptr<Message> msg) const {
            // the type names should have been correctly resolved earlier
            assert(typeid(*msg) == typeid(R));
            
            // FIXME: check that this assignment does not remove earlier information
            
            // NOTE: this dynamic cast is not perfect, but otherwise dynamic linking will break
            obj_->*member_ = std::static_pointer_cast<R>(msg);
        }
    private:
        T *obj_;
        BindType member_;
    };
    
    // delegate for a vector of messages that can be received
    template<typename T, typename R> class VectorBindDelegate : public BaseDelegate{
    public:
        using BindType = std::vector<std::shared_ptr<R>> T::*;
        
        VectorBindDelegate(T *obj, BindType member): obj_(obj), member_(member) {}
        ~VectorBindDelegate() {}
        
        void call(std::shared_ptr<Message> msg) const {
            // the type names should have been correctly resolved earlier
            assert(typeid(*msg) == typeid(R));
            
            // NOTE: this dynamic cast is not perfect, but otherwise dynamic linking will break
            (obj_->*member_).push_back(std::static_pointer_cast<R>(msg));
        }
    private:
        T *obj_;
        BindType member_;
        
    };
}

#endif /* ALLPIX_DELEGATE_H */
{'fraction_non_alphanumeric': 0.10649482787858233, 'fraction_numerical': 0.0003391555027980329, 'mean_word_length': 2.3190770962296003, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5977524', 'n_tokens_mistral': 1613, 'n_tokens_neox': 1584, 'n_words': 478}