]> Creatis software - bbtk.git/blob - kernel/src/bbtkData.h
Recreated the complete cvs tree because the project architecture deeply changed
[bbtk.git] / kernel / src / bbtkData.h
1 /*=========================================================================
2                                                                                 
3   Program:   bbtk
4   Module:    $RCSfile: bbtkData.h,v $
5   Language:  C++
6   Date:      $Date: 2008/01/22 15:02:00 $
7   Version:   $Revision: 1.1.1.1 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See doc/license.txt or
11   http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18 /**
19  *\file
20  *\brief  Defines Data and TypeInfo 
21  * 
22  * Data is bbtk general type exchanged between black boxes (adapted from boost::any).
23  * TypeInfo is the bbtk type of object storing informations on a data type (typedef on std::type_info). 
24  */
25
26 #ifndef __bbtkData_h__
27 #define __bbtkData_h__
28
29 //#include "bbtkSystem.h"
30 //#include "bbtkMessageManager.h"
31 //#include <string>
32 //#include <typeinfo>
33
34 //#include "bbtkany.h"
35
36 //#include "bbtkReferenceCountedObject.h"
37
38 #include "bbtkAny.h"
39
40 namespace bbtk
41 {
42   
43   typedef any<thing> Data;
44
45   /*
46
47   /// Can transport any kind of data (adaptation of boost::any)
48     class Data
49     {
50     public: // structors
51
52         Data()
53           : content(0)
54         {
55         }
56
57         template<typename ValueType>
58         Data(const ValueType & value)
59           : content(new holder<ValueType>(value))
60         {
61         }
62
63         Data(const Data & other)
64           : content(other.content ? other.content->clone() : 0)
65         {
66         }
67
68         ~Data()
69         {
70             delete content;
71         }
72
73     public: // modifiers
74
75         Data & swap(Data & rhs)
76         {
77             std::swap(content, rhs.content);
78             return *this;
79         }
80
81         template<typename ValueType>
82         Data & operator=(const ValueType & rhs)
83         {
84             Data(rhs).swap(*this);
85             return *this;
86         }
87
88         Data & operator=(const Data & rhs)
89         {
90             Data(rhs).swap(*this);
91             return *this;
92         }
93
94     public: // queries
95
96         bool empty() const
97         {
98             return !content;
99         }
100
101         const std::type_info & type() const
102         {
103             return content ? content->type() : typeid(void);
104         }
105
106 #ifndef BBTK_NO_MEMBER_TEMPLATE_FRIENDS
107     private: // types
108 #else
109     public: // types (public so Data_cast can be non-friend)
110 #endif
111
112         class placeholder
113         {
114         public: // structors
115
116             virtual ~placeholder()
117             {
118             }
119
120         public: // queries
121
122             virtual const std::type_info & type() const = 0;
123
124             virtual placeholder * clone() const = 0;
125
126         };
127
128         template<typename ValueType>
129         class holder : public placeholder
130         {
131         public: // structors
132
133             holder(const ValueType & value)
134               : held(value)
135             {
136             }
137
138         public: // queries
139
140             virtual const std::type_info & type() const
141             {
142                 return typeid(ValueType);
143             }
144
145             virtual placeholder * clone() const
146             {
147                 return new holder(held);
148             }
149
150         public: // representation
151
152             ValueType held;
153
154         };
155
156 #ifndef BBTK_NO_MEMBER_TEMPLATE_FRIENDS
157
158     private: // representation
159
160       //       template<typename ValueType>
161       //       friend ValueType * Data_cast(Data *);
162
163         template<typename ValueType>
164         friend ValueType * unsafe_Data_cast(Data *);
165  
166         template<typename ValueType>
167         friend ValueType  unsafe_Data_cast(Data &);
168
169 #else
170
171     public: // representation (public so Data_cast can be non-friend)
172
173 #endif
174
175         placeholder * content;
176
177     };
178
179     class bad_Data_cast : public std::bad_cast
180     {
181     public:
182         virtual const char * what() const throw()
183         {
184             return "bbtk::bad_Data_cast: "
185                    "failed conversion using bbtk::Data_cast";
186         }
187     };
188   */
189   /*
190     template<typename ValueType>
191     ValueType * Data_cast(Data * operand)
192     {
193         return operand && operand->type() == typeid(ValueType)
194                     ? &static_cast<Data::holder<ValueType> *>(operand->content)->held
195                     : 0;
196     }
197
198     template<typename ValueType>
199     const ValueType * Data_cast(const Data * operand)
200     {
201         return Data_cast<ValueType>(const_cast<Data *>(operand));
202     }
203
204 // Removed Data_cast
205     template<typename ValueType>
206     ValueType Data_cast(const Data & operand)
207     {
208         typedef BBTK_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
209
210 #ifdef BBTK_NO_TEMPLATE_PARTIAL_SPECIALIZATION
211         // If 'nonref' is still reference type, it means the user has not
212         // specialized 'remove_reference'.
213
214         // Please use BBTK_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro
215         // to generate specialization of remove_reference for your class
216         // See type traits library documentation for details
217         BBTK_STATIC_ASSERT(!is_reference<nonref>::value);
218 #endif
219
220         const nonref * result = Data_cast<nonref>(&operand);
221         if(!result)
222             bbtk::throw_exception(bad_Data_cast());
223         return *result;
224     }
225
226     template<typename ValueType>
227     ValueType Data_cast(Data & operand)
228     {
229         typedef BBTK_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
230
231 #ifdef BBTK_NO_TEMPLATE_PARTIAL_SPECIALIZATION
232         // The comment in the above version of 'Data_cast' explains when this
233         // assert is fired and what to do.
234         BBTK_STATIC_ASSERT(!is_reference<nonref>::value);
235 #endif
236
237         nonref * result = Data_cast<nonref>(&operand);
238         if(!result)
239             bbtk::throw_exception(bad_Data_cast());
240         return *result;
241     }
242   */
243     // Note: The "unsafe" versions of Data_cast are not part of the
244     // public interface and may be removed at Data time. They are
245     // required where we know what type is stored in the Data and can't
246     // use typeid() comparison, e.g., when our types may travel across
247     // different shared libraries.
248     // LG : This is precisely our case !
249   /*
250     template<typename ValueType>
251     inline ValueType * unsafe_Data_cast(Data * operand)
252     {
253         return &static_cast<Data::holder<ValueType> *>(operand->content)->held;
254     }
255
256     template<typename ValueType>
257     inline const ValueType * unsafe_Data_cast(const Data * operand)
258     {
259         return unsafe_Data_cast<ValueType>(const_cast<Data *>(operand));
260     }
261
262     template<typename ValueType>
263     inline ValueType  unsafe_Data_cast(Data & operand)
264     {
265         return static_cast<Data::holder<ValueType> *>(operand.content)->held;
266     }
267
268     template<typename ValueType>
269     inline ValueType unsafe_Data_cast(const Data & operand)
270     {
271         return *unsafe_Data_cast<ValueType>(const_cast<Data *>(&operand));
272     }
273   */
274
275 }// namespace bbtk
276
277 #endif
278