00001
00006 #include <iterator>
00007
00008 #include <wibble/amorph.h>
00009 #include <wibble/range.h>
00010 #include <wibble/cast.h>
00011
00012 #ifndef WIBBLE_CONSUMER_H
00013 #define WIBBLE_CONSUMER_H
00014
00015 namespace wibble {
00016
00017 template< typename T > struct Consumer;
00018
00019 template< typename T >
00020 struct ConsumerInterface
00021 {
00022 typedef T InputType;
00023 virtual void consume( const T &a ) = 0;
00024 virtual void consume( Range< T > s ) = 0;
00025 virtual ~ConsumerInterface() {}
00026 };
00027
00028 template< typename T, typename W >
00029 struct ConsumerMorph : Morph< ConsumerMorph< T, W >, W, ConsumerInterface< T > >
00030 {
00031 ConsumerMorph() {}
00032 ConsumerMorph( const W &w ) : Morph< ConsumerMorph, W, ConsumerInterface< T > >( w ) {}
00033
00034 virtual void consume( const T &a ) {
00035 return this->wrapped().consume( a );
00036 }
00037
00038 virtual void consume( Range< T > s ) {
00039 while ( !s.empty() ) {
00040 consume( s.head() );
00041 s = s.tail();
00042 }
00043 }
00044 };
00045
00046 template< typename T, typename Self >
00047 struct ConsumerMixin : mixin::Comparable< Self >
00048 {
00049 Self &self() { return *static_cast< const Self * >( this ); }
00050 typedef std::output_iterator_tag iterator_category;
00051 typedef T ConsumedType;
00052
00053 bool operator<=( const Self &o ) const { return this <= &o; }
00054 Consumer< T > &operator++() { return self(); }
00055 Consumer< T > &operator++(int) { return self(); }
00056 Consumer< T > &operator*() { return self(); }
00057 Consumer< T > &operator=( const T &a ) {
00058 self()->consume( a );
00059 return self();
00060 }
00061 };
00062
00063 template< typename T >
00064 struct Consumer: Amorph< Consumer< T >, ConsumerInterface< T > >,
00065 ConsumerMixin< T, Consumer< T > >
00066 {
00067 typedef Amorph< Consumer< T >, ConsumerInterface< T > > Super;
00068
00069 typedef void value_type;
00070 typedef void difference_type;
00071 typedef void pointer;
00072 typedef void reference;
00073
00074 Consumer( const MorphInterface< ConsumerInterface< T > > &i ) : Super( i ) {}
00075 Consumer() {}
00076
00077 void consume( const T &a ) {
00078 return this->implementation()->consume( a );
00079 }
00080
00081 Consumer< T > &operator=( const T &a ) {
00082 consume( a );
00083 return *this;
00084 }
00085
00086 };
00087
00088 template< typename T, typename Out >
00089 struct ConsumerFromIterator : ConsumerMixin< T, ConsumerFromIterator< T, Out > >
00090 {
00091 ConsumerFromIterator( Out out ) : m_out( out ) {}
00092 void consume( const T& a ) {
00093 *(*m_out) = a;
00094 ++(*m_out);
00095 }
00096 protected:
00097 Out m_out;
00098 };
00099
00100 template< typename R >
00101 Consumer< typename R::ConsumedType > consumerMorph( R r ) {
00102 return ConsumerMorph< typename R::ConsumedType , R >( r );
00103 }
00104
00105
00106 template< typename Out >
00107 Consumer< typename Out::container_type::value_type > consumer( Out out ) {
00108 return consumerMorph(
00109 ConsumerFromIterator< typename Out::container_type::value_type, Out >( out ) );
00110 }
00111
00112
00113 template< typename T >
00114 typename IsType< Consumer< typename T::value_type >, typename T::iterator >::T consumer( T &c ) {
00115 return consumer( std::inserter( c, c.end() ) );
00116 }
00117
00118
00119 template< typename T >
00120 Consumer< T > consumer( const ConsumerInterface< T > &t ) {
00121 return t;
00122 }
00123
00124 }
00125
00126 #endif