#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