Main Page   Namespace List   Class Hierarchy   Compound List   File List   Header Files   Namespace Members   Compound Members   File Members  

arg_observer.h

This is the verbatim text of the arg_observer.h include file.

#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

Copyright 1999-2000 Alan Griffiths