OSDN Git Service

88b144db26cdde7a830194be63fc28048b939ee1
[moflib/moflib.git] / moflib-1.0 / moflib / moflib / mof / stream / Cascade.hpp
1 #pragma once
2 #include "mof/stream/Manipulator.hpp"
3 #include "mof/stream/Cache.hpp"
4 #include <vector> 
5
6 namespace mof
7 {
8     #define DEFAULT_CASCADOR Multiply
9 //{{{ struct Add
10     template<typename T>
11     struct Add
12     {
13             inline static T apply(const T& a , const T& b)
14         {
15                 return a + b;
16             }
17     };
18 //}}}
19 //{{{ struct Multiply
20     template<typename T>
21     struct Multiply
22     {
23             inline static T apply(const T& a , const T& b)
24         {
25                     return a * b;
26             }
27     };
28 //}}}
29 //{{{ struct Overwrite
30     template<typename T>
31     struct Overwrite
32     {
33             inline static T apply(const T& , const T& b)
34         {
35                     return b;
36             }
37     };
38 //}}}
39 //{{{ class Cascade
40     template< typename T , class Cascador = DEFAULT_CASCADOR< T > >
41     class Cascade : public Manipulator< T >{
42     public:
43         typedef typename std::shared_ptr< Cascade > Handler;
44
45             virtual ~Cascade()
46         {
47             }
48
49             virtual T value( FrameNumber frame) const
50         {
51                     T obj = m_list[0]->value(frame);
52                     for(unsigned int i = 1 ; i < m_list.size() ; i++)
53             {
54                             obj = Cascador::apply(obj , m_list[i]->value(frame));
55                     }
56                     return obj;
57             }
58
59             void clear()
60         {
61                     m_list.clear();
62                         mof::state_changed();
63             }
64
65             void add( const typename Manipulator<T>::Handler& handler )
66         {
67                     m_list.push_back( handler );
68                         mof::state_changed();
69         }
70
71     private:    
72             typedef std::vector< typename Manipulator< T >::Handler > List;
73             List m_list;
74         
75         Cascade
76         (
77                     const typename Manipulator< T >::Handler& front , 
78                     const typename Manipulator< T >::Handler& back 
79         )
80             {
81                     int length = &back - &front + 1;
82                     if(length <= 0)throw std::invalid_argument("list size is 0");
83
84                     for( int i = 0 ; i < length ; i++)
85             {
86                         m_list.push_back( (&front)[i] );
87                 }
88             }
89     
90
91         Cascade(){}
92         
93         template< typename T , class Cascador >
94         friend typename std::shared_ptr< Cascade< T , Cascador > >
95         makeCascadeHandler
96         (
97                 const typename Manipulator< T >::Handler& front , 
98                 const typename Manipulator< T >::Handler& back 
99         );
100
101         template< typename T , class Cascador >
102         friend typename std::shared_ptr< Cascade< T , Cascador > > makeCascadeHandler();
103
104
105     };
106 //}}}
107 //{{{ ヘルパ関数 
108     template< typename T , class Cascador >
109     std::shared_ptr< Cascade< T , Cascador > >
110     makeCascadeHandler
111     (
112             const typename Manipulator< T >::Handler& front , 
113             const typename Manipulator< T >::Handler& back 
114     )
115         {
116         return typename Cascade< T , Cascador >::Handler
117             (
118                 new Cascade< T , Cascador >( front , back ) 
119             );
120         }
121     
122     template< typename T , class Cascador >
123     typename std::shared_ptr< Cascade< T , Cascador > >
124     makeCascadeHandler( )
125         {
126         return typename Cascade< T , Cascador >::Handler
127             (
128                 new Cascade< T , Cascador >
129             );
130         }
131
132     template<typename T >
133     typename std::shared_ptr< Cascade< T , DEFAULT_CASCADOR< T > > >
134     makeCascadeHandler
135     (
136             const typename Manipulator< T >::Handler& front , 
137             const typename Manipulator< T >::Handler& back 
138     )
139         {
140         return makeCascadeHandler< T , DEFAULT_CASCADOR< T > >( front , back );
141         }
142     
143     template<typename T >
144     typename std::shared_ptr< Cascade< T , DEFAULT_CASCADOR< T > > >
145     makeCascadeHandler( )
146         {
147         return makeCascadeHandler< T , DEFAULT_CASCADOR< T > >();
148         }
149 //}}}
150 //{{{ ストリーム演算子
151     template< typename T , class Cascador >
152     std::shared_ptr< Cascade< T , Cascador > >& 
153     operator << 
154     (
155         std::shared_ptr< Cascade< T , Cascador > >& a ,
156         const typename Manipulator< T >::Handler& b 
157     )
158     {
159         a->add( b );
160         return a;
161     }
162
163     template< typename T , class Cascador >
164     typename std::shared_ptr< Cascade< T , Cascador > >& 
165     operator << 
166     (
167         std::shared_ptr< Cascade< T , Cascador > >& a ,
168         const T& b 
169     )
170     {
171         a->add( mof::makeConstantHandler( b ) );
172         return a;
173     }
174 //}}}
175 } //namespace mof
176