wibble 0.1.28
consumer.h
Go to the documentation of this file.
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< Self * >( this ); }
00050     const Self &self() const { return *static_cast< const Self * >( this ); }
00051     typedef std::output_iterator_tag iterator_category;
00052     typedef T ConsumedType;
00053 
00054     bool operator<=( const Self &o ) const { return this <= &o; }
00055     Consumer< T > &operator++() { return self(); }
00056     Consumer< T > &operator++(int) { return self(); }
00057     Consumer< T > &operator*() { return self(); }
00058     Consumer< T > &operator=( const T &a ) {
00059         self()->consume( a );
00060         return self();
00061     }
00062 };
00063 
00064 template< typename T >
00065 struct Consumer: Amorph< Consumer< T >, ConsumerInterface< T > >,
00066                  ConsumerMixin< T, Consumer< T > >
00067 {
00068     typedef Amorph< Consumer< T >, ConsumerInterface< T > > Super;
00069 
00070     typedef void value_type;
00071     typedef void difference_type;
00072     typedef void pointer;
00073     typedef void reference;
00074 
00075     Consumer( const MorphInterface< ConsumerInterface< T > > &i ) : Super( i ) {}
00076     Consumer() {}
00077 
00078     void consume( const T &a ) {
00079         return this->implementation()->consume( a );
00080     }
00081 
00082     Consumer< T > &operator=( const T &a ) {
00083         consume( a );
00084         return *this;
00085     }
00086     // output iterator - can't read or move
00087 };
00088 
00089 template< typename T, typename Out >
00090 struct ConsumerFromIterator : ConsumerMixin< T, ConsumerFromIterator< T, Out > >
00091 {
00092     ConsumerFromIterator( Out out ) : m_out( out ) {}
00093     void consume( const T& a ) {
00094         *(*m_out) = a;
00095         ++(*m_out);
00096     }
00097 protected:
00098     Out m_out;
00099 };
00100 
00101 template< typename R >
00102 Consumer< typename R::ConsumedType > consumerMorph( R r ) {
00103     return ConsumerMorph< typename R::ConsumedType , R >( r );
00104 }
00105 
00106 // insert iterators
00107 template< typename Out >
00108 Consumer< typename Out::container_type::value_type > consumer( Out out ) {
00109     return consumerMorph(
00110         ConsumerFromIterator< typename Out::container_type::value_type, Out >( out ) );
00111 }
00112 
00113 // containers
00114 template< typename T >
00115 typename IsType< Consumer< typename T::value_type >, typename T::iterator >::T consumer( T &c ) {
00116     return consumer( std::inserter( c, c.end() ) );
00117 }
00118 
00119 // consumers
00120 template< typename T >
00121 Consumer< T > consumer( const ConsumerInterface< T > &t ) {
00122     return t;
00123 }
00124 
00125 }
00126 
00127 #endif