#ifndef ARG_OBSERVER_H #define ARG_OBSERVER_H #ifndef ARG_COMPILER_H #include "arg_compiler.h" #endif #ifndef ARG_VECTOR_H #include ARG_STLHDR(vector) #define ARG_VECTOR_H #endif #ifndef ARG_ALGORITHM_H #include ARG_STLHDR(algorithm) #define ARG_ALGORITHM_H #endif #ifndef ARG_FUNCTIONAL_H #include ARG_STLHDR(functional) #define ARG_FUNCTIONAL_H #endif namespace arg { namespace functional { template<class functor> class const_functor_ref_t { public: const_functor_ref_t(const functor& ff) : f(ff) {} template<typename parm> void operator() (parm p) { f(p); } private: const functor& f; }; template<class functor> class functor_ref_t { public: functor_ref_t(functor& ff) : f(ff) {} template<typename parm> void operator() (parm p) { f(p); } private: functor& f; }; template<class functor> const_functor_ref_t<functor> functor_ref(const functor& ff) { return const_functor_ref_t<functor>(ff); } // MSVC doesn't reliably overload templates on const #ifndef _MSC_VER template<class functor> functor_ref_t<functor> functor_ref(functor& ff) { return functor_ref_t<functor>(ff); } #endif } template<class observer> class subject { public: subject() : refs() {} subject& add_observer(observer* addee) { refs.push_back(addee); return *this; } subject& remove_observer(observer* removee) { using namespace std; refs.erase(partition( refs.begin(), refs.end(), bind2nd(not_equal_to<observer*>(), removee)), refs.end()); return *this; } class notify_strategy { public: virtual void operator()(observer* obs) const = 0; }; const subject& notify(const notify_strategy& notify) const { std::for_each(refs.begin(), refs.end(), functional::functor_ref(notify)); return *this; } private: typedef std::vector<observer*> observers; observers refs; }; } #endif