• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

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< 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     // output iterator - can't read or move
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 // insert iterators
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 // containers
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 // consumers
00119 template< typename T >
00120 Consumer< T > consumer( const ConsumerInterface< T > &t ) {
00121     return t;
00122 }
00123 
00124 }
00125 
00126 #endif

Generated on Tue May 10 2011 16:51:50 for wibble by  doxygen 1.7.1