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
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
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
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
00120 template< typename T >
00121 Consumer< T > consumer( const ConsumerInterface< T > &t ) {
00122 return t;
00123 }
00124
00125 }
00126
00127 #endif