Salome HOME
PR: first version from Antony GEAY, with directory restructuration
[modules/yacs.git] / src / basicData / TypeCheckerDataFlow.hxx
1 #ifndef __TYPECHECKERDATAFLOW_HXX__
2 #define __TYPECHECKERDATAFLOW_HXX__
3
4 #include "define.hxx"
5 #include "ConversionException.hxx"
6
7 #include <string>
8 #include <sstream>
9
10 namespace YACS
11 {
12   namespace ENGINE
13   {
14     /**
15      *
16      * @ note : container in all this file is a concept that stores any data of any data into container::Type type.
17      *          container concept must at least implement
18      *                 - createNewContent method
19      *                 - readContent method
20      *          and container must define Type class that stores data independently of type.
21      *          ContentOfDataFlow is one class fulfilling this concept !
22      *
23      */
24     template< template< DynType type> class TREATMENTPERTYPE >
25     class DynToStaticTypeDispatcher1
26     {
27     public:
28       template<class  T, class U>
29       static void perform(YACS::DynType myTypeDyn, T input, U& output) throw(Exception)
30       {
31         switch(myTypeDyn)
32           {
33           case Double:
34             TREATMENTPERTYPE<Double>::perform(input, output);
35             break;
36           case Int:
37             TREATMENTPERTYPE<Int>::perform(input, output);
38             break;
39           case String:
40             TREATMENTPERTYPE<String>::perform(input, output);
41             break;
42           case Bool:
43             TREATMENTPERTYPE<Bool>::perform(input, output);
44             break;
45           default:
46             throw Exception("Unknow type enum");
47           }
48       }
49     };
50
51     template< template< DynType fromType, DynType toType> class TREATMENTPERTYPE >
52     class DynToStaticTypeDispatcher2
53     {
54       template<DynType toType> class TREATMENTPERTYPEDOUBLE : public TREATMENTPERTYPE<Double,toType> { };
55       template<DynType toType> class TREATMENTPERTYPEINT : public TREATMENTPERTYPE<Int,toType> { };
56       template<DynType toType> class TREATMENTPERTYPEBOOL : public TREATMENTPERTYPE<Bool,toType> { };
57       template<DynType toType> class TREATMENTPERTYPESTRING : public TREATMENTPERTYPE<String,toType> { };
58     public:
59       template<class  T, class U>
60       static void perform(YACS::DynType myTypeDynFrom, YACS::DynType myTypeDynTo, T input, U& output) throw(Exception)
61       {
62         switch(myTypeDynFrom)
63           {
64           case Double:
65 #ifndef __OLD_GCC__
66             DynToStaticTypeDispatcher1<TREATMENTPERTYPEDOUBLE>::perform(myTypeDynTo, input, output);
67 #else
68             switch(myTypeDynTo)
69               {
70               case Double:
71                 TREATMENTPERTYPE<Double,Double>::perform(input, output);
72                 break;
73               case Int:
74                 TREATMENTPERTYPE<Double,Int>::perform(input, output);
75                 break;
76               case String:
77                 TREATMENTPERTYPE<Double,String>::perform(input, output);
78                 break;
79               case Bool:
80                 TREATMENTPERTYPE<Double,Bool>::perform(input, output);
81                 break;
82               default:
83                 throw Exception("Unknow type enum");
84               }
85 #endif
86             break;
87           case Int:
88 #ifndef __OLD_GCC__
89             DynToStaticTypeDispatcher1<TREATMENTPERTYPEINT>::perform(myTypeDynTo, input, output);
90 #else
91             switch(myTypeDynTo)
92               {
93               case Double:
94                 TREATMENTPERTYPE<Int,Double>::perform(input, output);
95                 break;
96               case Int:
97                 TREATMENTPERTYPE<Int,Int>::perform(input, output);
98                 break;
99               case String:
100                 TREATMENTPERTYPE<Int,String>::perform(input, output);
101                 break;
102               case Bool:
103                 TREATMENTPERTYPE<Int,Bool>::perform(input, output);
104                 break;
105               default:
106                 throw Exception("Unknow type enum");
107               }
108 #endif
109             break;
110           case String:
111 #ifndef __OLD_GCC__
112             DynToStaticTypeDispatcher1<TREATMENTPERTYPESTRING>::perform(myTypeDynTo, input, output);
113 #else
114             switch(myTypeDynTo)
115               {
116               case Double:
117                 TREATMENTPERTYPE<String,Double>::perform(input, output);
118                 break;
119               case Int:
120                 TREATMENTPERTYPE<String,Int>::perform(input, output);
121                 break;
122               case String:
123                 TREATMENTPERTYPE<String,String>::perform(input, output);
124                 break;
125               case Bool:
126                 TREATMENTPERTYPE<String,Bool>::perform(input, output);
127                 break;
128               default:
129                 throw Exception("Unknow type enum");
130               }
131 #endif
132             break;
133           case Bool:
134 #ifndef __OLD_GCC__
135             DynToStaticTypeDispatcher1<TREATMENTPERTYPESTRING>::perform(myTypeDynTo, input, output);
136 #else
137             switch(myTypeDynTo)
138               {
139               case Double:
140                 TREATMENTPERTYPE<Bool,Double>::perform(input, output);
141                 break;
142               case Int:
143                 TREATMENTPERTYPE<Bool,Int>::perform(input, output);
144                 break;
145               case String:
146                 TREATMENTPERTYPE<Bool,String>::perform(input, output);
147                 break;
148               case Bool:
149                 TREATMENTPERTYPE<Bool,Bool>::perform(input, output);
150                 break;
151               default:
152                 throw Exception("Unknow type enum");
153               }
154 #endif
155             break;
156           default:
157             throw Exception("Unknow type enum");
158           }
159       }
160     };
161
162     template<YACS::DynType baseTyp>
163     class TypeDescriptorTraits
164     {
165     };
166
167     template<class T>
168     class TypeDescriptorTraitsInv
169     {
170     };
171
172     template<>
173     class TypeDescriptorTraits<YACS::Double>
174     {
175     public:
176       typedef double ConcreteType;
177       static const char _name[];
178     };
179
180     template<>
181     class TypeDescriptorTraitsInv<double>
182     {
183     public:
184       static const YACS::DynType _typeEnum=Double;
185     };
186
187     template<>
188     class TypeDescriptorTraits<YACS::Int>
189     {
190     public:
191       typedef int ConcreteType;
192       static const char _name[];
193     };
194
195     template<>
196     class TypeDescriptorTraitsInv<int>
197     {
198     public:
199       static const YACS::DynType _typeEnum=Int;
200     };
201
202     template<>
203     class TypeDescriptorTraits<YACS::Bool>
204     {
205     public:
206       typedef bool ConcreteType;
207       static const char _name[];
208     };
209
210     template<>
211     class TypeDescriptorTraitsInv<bool>
212     {
213     public:
214       static const YACS::DynType _typeEnum=Bool;
215     };
216
217     template<>
218     class TypeDescriptorTraits<YACS::String>
219     {
220     public:
221       typedef std::string ConcreteType;
222       static const char _name[];
223     };
224
225     template<>
226     class TypeDescriptorTraitsInv<std::string>
227     {
228     public:
229       static const YACS::DynType _typeEnum=String;
230     };
231
232     /**
233      *
234      * This class has the responsability of the validity of the content of data regarding only statically its types from and to.
235      *
236      */
237     template<DynType fromType, DynType toType >
238     class StaticTypeConverter
239     {
240     public:
241       enum { _staticallyCompatible=0 };
242       static typename TypeDescriptorTraits<toType>::ConcreteType traduce(typename TypeDescriptorTraits<fromType>::ConcreteType input) throw(ConversionException)
243       {
244         throw ConversionException(TypeDescriptorTraits<fromType>::_name, TypeDescriptorTraits<toType>::_name);
245       }
246     };
247
248     //Specialisation of the previously declared StaticTypeConverter class when 'fromType' and 'toType' are equal.
249     template<DynType aType>
250     class StaticTypeConverter<aType, aType>
251     {
252     public:
253       enum { _staticallyCompatible=1 };
254       static typename TypeDescriptorTraits<aType>::ConcreteType traduce(typename TypeDescriptorTraits<aType>::ConcreteType input) throw(ConversionException)
255       {
256         return input;
257       }
258     };
259
260     template<>
261     class StaticTypeConverter<YACS::Double, YACS::Int>
262     {
263     public:
264       enum { _staticallyCompatible=1 };
265       static TypeDescriptorTraits<YACS::Int>::ConcreteType traduce(TypeDescriptorTraits<YACS::Double>::ConcreteType input) throw(ConversionException)
266       {
267         return (TypeDescriptorTraits<YACS::Int>::ConcreteType) input;
268       }
269     };
270
271     template<>
272     class StaticTypeConverter<YACS::Int, YACS::Double>
273     {
274     public:
275       enum { _staticallyCompatible=1 };
276       static TypeDescriptorTraits<YACS::Double>::ConcreteType traduce(TypeDescriptorTraits<YACS::Int>::ConcreteType input) throw(ConversionException)
277       {
278         return (TypeDescriptorTraits<YACS::Double>::ConcreteType) input;
279       }
280     };
281
282     template<>
283     class StaticTypeConverter<YACS::Int, YACS::Bool>
284     {
285     public:
286       enum { _staticallyCompatible=1 };
287       static TypeDescriptorTraits<YACS::Bool>::ConcreteType traduce(TypeDescriptorTraits<YACS::Int>::ConcreteType input) throw(ConversionException)
288       {
289         if(input!=0)
290           return true;
291         else
292           return false;
293       }
294     };
295
296     template<>
297     class StaticTypeConverter<YACS::Bool, YACS::Int>
298     {
299     public:
300       enum { _staticallyCompatible=1 };
301       static TypeDescriptorTraits<YACS::Int>::ConcreteType traduce(TypeDescriptorTraits<YACS::Bool>::ConcreteType input) throw(ConversionException)
302       {
303         if(input)
304           return 1;
305         else
306           return 0;
307       }
308     };
309
310     /**
311      *
312      * This class has the responsability of the validity of the content of data regarding statically and dynamically its types from and to.
313      *
314      */
315     template<class container, DynType fromType, DynType toType >
316     class StaticAndDynamicTypeConverter
317     {
318     public:
319       static typename container::Type convert(typename container::Type source) throw(ConversionException)
320       {
321         if(!StaticTypeConverter<fromType, toType>::_staticallyCompatible)
322           throw ConversionException(TypeDescriptorTraits<fromType>::_name, TypeDescriptorTraits<toType>::_name);
323         typename TypeDescriptorTraits<fromType>::ConcreteType sourceValue;
324         container::readContent(source,sourceValue);
325         typename TypeDescriptorTraits<toType>::ConcreteType targetValue=StaticTypeConverter<fromType, toType>::traduce(sourceValue);
326         return container::createNewContent(targetValue);
327       }
328     };
329   }
330 }
331
332 #endif