#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>

using namespace std;

//folgendes wäre Teil der Standardlibrary
//nur minimale features implementiert (zeitgründe)
class Integer {
public:
    typedef int BaseType;
    int value;

    Integer(int value=0) : value(value) {}
    Integer(Integer const& other) : value(other.value) {}

    Integer& operator=(Integer const& other) {
        value=other.value;
        return *this;
    }
};

Integer operator+(Integer const& lhs, Integer const& rhs) {
    return Integer(lhs.value+rhs.value);
}

class PositiveInteger : protected Integer {
public:
    typedef int BaseType;

    PositiveInteger(int value=0) : Integer(value) { if(value<0) throw "Negative Value"; }
    PositiveInteger(Integer const& other) : Integer(other) { if(value<0) throw "Negative Value"; }

    PositiveInteger& operator=(Integer const& other) {
        if(other.value < 0) throw "Negative Value";
        value=other.value;
        return *this;
    }

    operator Integer() { return *this; }
};



template<typename T>
class Vector {
private:
    vector<T> impl;

public:
    void add(T const& val) {
        impl.push_back(val);
    }

    template<typename F>
    void for_each(F f) {
        for(auto& obj : impl) {
            f(obj);
        }
    }
};

template<typename T>
class ChangeObserver : public Vector<function<void(T const&, T const&)> > {
public:
    void change(T const& oldVal, T const& newVal) {
        this->for_each([&](function<void(T const&, T const&)> f) { f(oldVal, newVal); });
    }
};

template<typename ValueType>
class ChangeObservableArithmeticType : private ValueType, public ChangeObserver<ValueType> {
public:
    typedef typename ValueType::BaseType BaseType;
    ChangeObservableArithmeticType(typename ValueType::BaseType value=0) : ValueType(value) {}
    ChangeObservableArithmeticType(ChangeObservableArithmeticType const& other) : ValueType(other) {}
    ChangeObservableArithmeticType(ValueType const& other) : ValueType(other) {}

    ChangeObservableArithmeticType& operator=(ChangeObservableArithmeticType const& other) {
        this->change(*this, other);
        this->value=other.value;
        return *this;
    }

    operator ValueType() {
        return *this;
    }
};

class Radius : public ChangeObservableArithmeticType<PositiveInteger> {
};

class Kreis : public Radius {
public:
    Kreis() {
        add([&](::PositiveInteger const&, ::PositiveInteger const&) {
            redraw();
        });

        redraw();
    }

    void redraw() {
        cout<<"Radius changed, Kreis redrawn\n";
    }
};

int main() {
    //2x redraw ausführen:
    Kreis k;
    k.ChangeObservableArithmeticType::operator=(7);

    try {
        k.ChangeObservableArithmeticType::operator=(-7);
    } catch(...) {
        cout<<"Error\n";
    }

    return 0;
}

