#ifndef _router_ #define _router_ #include #include #include #include namespace gdfa { template void distribute(InputIterator begin, InputIterator end, OutputIteratorIfTrue out1, OutputIteratorIfFalse out2, Predicate p) { while (begin != end) { typename std::iterator_traits::value_type item=*begin++; p(item) ? *out1++=item : *out2++=item; } } template class destination { public: virtual ~destination() {} virtual bool distribute(const T& element)=0; }; template class router { public: typedef unsigned int priority_level; static const priority_level low_priority=0; static const priority_level normal_priority=1; static const priority_level high_priority=2; static const priority_level urgent_priority=3; private: class destination_handle { private: destination *dest; std::size_t *referenceCount; void destroy() { if(--*referenceCount==0) { delete referenceCount; delete dest; } } priority_level priority; public: template destination_handle(const Destination& d, priority_level _priority) :priority(_priority), dest(new Destination(d)), referenceCount(new std::size_t(1)){} destination_handle(const destination_handle& copy) :dest(copy.dest), referenceCount(copy.referenceCount) { ++*referenceCount; priority=copy.priority; } destination_handle& operator= (const destination_handle& rhs) { ++*rhs.referenceCount; destroy(); dest=rhs.dest; referenceCount=rhs.referenceCount; priority=rhs.priority; return *this; } bool operator< (const destination_handle& rhs) const { return priority(const destination_handle& rhs) const { return rhs<*this; } ~destination_handle() { destroy(); } bool distribute(const T& element) { return dest->distribute(element); } }; std::vector destinations; destination_handle *defaultDestination; // not implemented: prohibited router(const router& copy); router& operator=(const router& rhs); public: router() : defaultDestination(NULL) {} template router(OutputIterator first, OutputIterator last) :defaultDestination(NULL) { std::copy(first, last, std::back_inserter(destinations)); std::make_heap(first, last); } ~router() { remove_default(); } template void distribute(InputIterator item) { typename std::vector::iterator i; for (i=destinations.begin(); i!=destinations.end(); ++i) { if(i->distribute(*item)) { break; } } if(i==destinations.end() && defaultDestination) { defaultDestination->distribute(*item); } } template void distribute(InputIterator first, InputIterator last) { while(first!=last) { distribute(first++); } } template void add_destination(const Destination& d, int _priority=normal_priority) { destinations.push_back(destination_handle(d,_priority)); std::push_heap(destinations.begin(), destinations.end()); } template void set_default(const Destination& d) { remove_default(); defaultDestination= new destination_handle(d,normal_priority); } void remove_default() { if(defaultDestination) { delete defaultDestination; defaultDestination=NULL; } } }; } #endif