<commit_before>#ifndef TE_OBSERVER_H
#define TE_OBSERVER_H

namespace te
{
	template <class EventType>
	class Observer
	{
	public:
        virtual ~Observer() {}
        virtual void onNotify(const EventType& evt) = 0;
	};
}

#endif<commit_msg>Add Notifier base class, complements Observer<commit_after>#ifndef TE_OBSERVER_H
#define TE_OBSERVER_H

#include <vector>
#include <memory>
#include <cassert>

namespace te
{
	template <class EventType>
	class Observer
	{
	public:
        virtual ~Observer() {}
        virtual void onNotify(const EventType& evt) = 0;
	};

    template <class EventType>
    class Notifier
    {
    public:
        virtual ~Notifier() {}
        void addObserver(std::shared_ptr<Observer<EventType>> newObserver)
        {
            assert(newObserver);
            if (std::find(mObservers.begin(), mObservers.end(), newObserver) == mObservers.end()) {
                mObservers.push_back(newObserver);
            }
        }
    protected:
        void notify(const EventType& evt)
        {
            std::for_each(std::begin(mObservers), std::end(mObservers), [&evt](std::shared_ptr<Observer<EventType>>& pObserver) {
                pObserver->onNotify(evt);
            });
        }
    private:
        std::vector<std::shared_ptr<Observer<EventType>>> mObservers;
    };
}

#endif
{'fraction_non_alphanumeric': 0.12009063444108761, 'fraction_numerical': 0.0015105740181268882, 'mean_word_length': 2.8517441860465116, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 17, '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': '3369394', 'n_tokens_mistral': 415, 'n_tokens_neox': 426, 'n_words': 83}