bbtkAny.h

Go to the documentation of this file.
00001 /*=========================================================================                                                                               
00002   Program:   bbtk
00003   Module:    $RCSfile: bbtkAny.h,v $
00004   Language:  C++
00005   Date:      $Date: 2008/10/17 08:18:12 $
00006   Version:   $Revision: 1.5 $
00007 =========================================================================*/
00008 
00009 /* ---------------------------------------------------------------------
00010 
00011 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
00012 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
00013 *
00014 *  This software is governed by the CeCILL-B license under French law and 
00015 *  abiding by the rules of distribution of free software. You can  use, 
00016 *  modify and/ or redistribute the software under the terms of the CeCILL-B 
00017 *  license as circulated by CEA, CNRS and INRIA at the following URL 
00018 *  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
00019 *  or in the file LICENSE.txt.
00020 *
00021 *  As a counterpart to the access to the source code and  rights to copy,
00022 *  modify and redistribute granted by the license, users are provided only
00023 *  with a limited warranty  and the software's author,  the holder of the
00024 *  economic rights,  and the successive licensors  have only  limited
00025 *  liability. 
00026 *
00027 *  The fact that you are presently reading this means that you have had
00028 *  knowledge of the CeCILL-B license and that you accept its terms.
00029 * ------------------------------------------------------------------------ */                                                                         
00030 
00031 
00032 /* ---------------------------------------------------------------------
00033 
00034 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
00035 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
00036 *
00037 *  This software is governed by the CeCILL-B license under French law and 
00038 *  abiding by the rules of distribution of free software. You can  use, 
00039 *  modify and/ or redistribute the software under the terms of the CeCILL-B 
00040 *  license as circulated by CEA, CNRS and INRIA at the following URL 
00041 *  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
00042 *  or in the file LICENSE.txt.
00043 *
00044 *  As a counterpart to the access to the source code and  rights to copy,
00045 *  modify and redistribute granted by the license, users are provided only
00046 *  with a limited warranty  and the software's author,  the holder of the
00047 *  economic rights,  and the successive licensors  have only  limited
00048 *  liability. 
00049 *
00050 *  The fact that you are presently reading this means that you have had
00051 *  knowledge of the CeCILL-B license and that you accept its terms.
00052 * ------------------------------------------------------------------------ */                                                                         
00053 
00058 #ifndef __BBTKANY_H_INCLUDED__
00059 #define __BBTKANY_H_INCLUDED__
00060 
00061 /*
00062 #include <string>
00063 #include <iostream>
00064 #include <typeinfo>
00065 #include <set>
00066 #include <map>
00067 #include <sstream>
00068 #include <exception>
00069 
00070 #include <cxxabi.h>
00071 */
00072 #include <sstream>
00073 #include "bbtkRTTI.h"
00074 #include "bbtkMessageManager.h"
00075 #include "bbtkException.h"
00076 
00077 #include <boost/type_traits/is_pointer.hpp>
00078 
00079 namespace bbtk 
00080 {
00081 
00082 
00083 
00084 
00085 
00086   //=========================================================
00088   class anyplaceholder
00089   {
00090   public: // structors
00091     
00092     virtual ~anyplaceholder() {}
00093     
00094   public: // queries
00095     
00097     virtual const std::type_info & type() const = 0;
00099     virtual const std::type_info & pointed_type() const = 0;
00100     
00102     virtual bool is_pointer() const = 0;
00103     
00106     virtual void* get_pointer() const = 0;
00107  
00109     virtual void* get_pointer_to( const std::type_info& ) const = 0;
00110    
00111     virtual anyplaceholder * clone() const = 0;
00112     
00113   };
00114   //=========================================================
00115   
00116   //=========================================================
00119   template<typename ValueType>
00120   class anyholder : public anyplaceholder
00121   {
00122   public: // structors
00123     
00124     anyholder(const ValueType & value)
00125       : held(value)
00126     {}
00127     
00128   public: // queries
00129     
00130     virtual const std::type_info & type() const { return typeid(ValueType);}
00131     virtual bool is_pointer() const { return false; }
00132     virtual const std::type_info & pointed_type() const { return typeid(void); }
00133     virtual void* get_pointer() const { return 0; }
00134     virtual void* get_pointer_to( const std::type_info& ) const { return 0; }
00135     virtual anyplaceholder * clone() const { return new anyholder(held); }
00136     
00137     public: // representation
00138     
00139     ValueType held;
00140     
00141   };
00142   //=========================================================
00143   
00144   //=========================================================
00146   template<typename ValueType>
00147   class anyholder<ValueType*> : public anyplaceholder
00148   {
00149   public: // structors
00150 
00151     anyholder(ValueType* const & value)
00152       : held(value)
00153     { }
00154 
00155   public: // queries
00156 
00157     virtual const std::type_info & type() const
00158     {
00159       return typeid(ValueType*);
00160     }
00161 
00162     virtual bool is_pointer() const { return true; }
00163     virtual const std::type_info & pointed_type() const { return typeid(ValueType); }
00164     virtual void* get_pointer() const { 
00165       return (void*)held; 
00166     }
00167     virtual void* get_pointer_to( const std::type_info& t) const 
00168     { 
00169       return run_time_up_or_down_cast(t,typeid(ValueType),held);
00170     }
00171 
00172     virtual anyplaceholder * clone() const { return new anyholder(held); }
00173 
00174   public: // representation
00175 
00176     ValueType* held;
00177 
00178   };
00179   //=========================================================
00180 
00181 
00205   template <template <class> class TypeTraits >
00206   class any
00207   {
00208   public:
00209     typedef any< TypeTraits > self;
00210     // structors
00211 
00213     any()
00214       : content(0)
00215     {
00216     }
00217 
00219     template<typename ValueType>
00220     any(const ValueType & value)
00221       : content(0)
00222     {
00223       bbtkDebugMessage("Data",1,
00224                        bbtk::HumanTypeName<self>()<<" construction with <"
00225                        <<bbtk::HumanTypeName<ValueType>()<<">"<<std::endl);
00226       //      ValueType v = value;
00227       //      int** i = (int**)(&v);
00228       //      std::cout << "v="<<*i<<std::endl;
00229       
00230       if (accepts<ValueType>()) 
00231         { 
00232           content = new anyholder<ValueType>(value);
00233         }
00234       else 
00235         {
00236           bbtkError(bbtk::HumanTypeName<self>()
00237                     <<" constructor : data of type <"
00238                     <<bbtk::HumanTypeName<ValueType>()
00239                     <<"> are not accepted by traits <"
00240                     <<bbtk::HumanTypeName<TypeTraits<void> >()<<"> ");
00241         }
00242     }
00243   
00245     any(const any & other)
00246       : content(other.content ? other.content->clone() : 0)
00247     {
00248       bbtkDebugMessage("Data",1,
00249                        HumanTypeName<self>()
00250                        <<" copy construction with new content : "
00251                        <<HumanTypeName(type())
00252                        <<std::endl);
00253     }
00254   
00256     ~any()
00257     {
00258       delete content;
00259     }
00260 
00261 
00263     any & swap(any & rhs)
00264     {
00265       std::swap(content, rhs.content);
00266       return *this;
00267     }
00268 
00270     template<typename ValueType>
00271     any & operator=(const ValueType & rhs)
00272     {
00273       bbtkDebugMessage("Data",1,
00274                        HumanTypeName<self>()
00275                        <<" operator= with data of type <"
00276                        <<HumanTypeName<ValueType>()
00277                        <<">"<<std::endl);
00278       if (accepts<ValueType>()) 
00279         {
00280           any(rhs).swap(*this);
00281           return *this;
00282         }
00283       else 
00284         {
00285           bbtkError(HumanTypeName<self>()
00286                     <<" operator= : data of type <"
00287                     <<HumanTypeName<ValueType>()
00288                     <<"> are not accepted by traits <"
00289                     <<HumanTypeName<TypeTraits<void> >()<<"> ");
00290         }
00291     
00292     }
00293   
00295     any & operator=(const any & rhs)
00296     {
00297         bbtkDebugMessage("Data",1,
00298                          HumanTypeName<self >()
00299                          <<" operator=(const any&) with content : "
00300                          <<HumanTypeName(rhs.type())<<std::endl);
00301 
00302       any(rhs).swap(*this);
00303       return *this;
00304     }
00305   
00306 
00308     bool empty() const
00309     {
00310       return !content;
00311     }
00312   
00314     const std::type_info & type() const
00315     {
00316       return content ? content->type() : typeid(void);
00317     }
00318 
00320     const std::type_info & pointed_type() const
00321     {
00322       return content ? content->pointed_type() : typeid(void);
00323     }
00324 
00325 
00327     template<typename Type>
00328     inline bool contains()
00329     {
00330       return ( type() == typeid(Type) );
00331     }
00332 
00334     inline bool contains_pointer()
00335     {
00336       return content->is_pointer() ;
00337     }
00338 
00340     inline bool contains(TypeInfo t)
00341     {
00342       return ( (bool)(type() == t) );
00343      }
00344 
00346     template<typename Type>
00347     inline bool accepts()
00348     {
00349       return TypeTraits<Type>::value; //is_valid();
00350     }
00351 
00354     template<typename ValueType>
00355     inline const ValueType& get() const
00356     {
00357         bbtkDebugMessage("Data",1,
00358                          HumanTypeName<self >()
00359                          <<" get<"<<HumanTypeName<ValueType>()
00360                          <<"> with content : "
00361                          <<HumanTypeName(type())<<std::endl);
00362 
00363       if ( type() == typeid(ValueType) )
00364         return static_cast< anyholder<ValueType> *>(content)->held;
00365 
00366       bbtkError(HumanTypeName<self >()
00367                 <<" get with type <"
00368                 <<bbtk::HumanTypeName<ValueType>()
00369                 <<"> does not match content type <"
00370                 <<bbtk::HumanTypeName<>(type())<<">");
00371     }
00372 
00373     template<typename ValueType>
00374     inline const ValueType* getP() const
00375     {
00376       if ( type() == typeid(ValueType) )
00377         return &static_cast< anyholder<ValueType> *>(content)->held;
00378  
00379       bbtkError(HumanTypeName<self >()
00380                 <<" getP with type <"
00381                 <<bbtk::HumanTypeName<ValueType>()
00382                 <<"> does not match content type <"
00383                 <<bbtk::HumanTypeName<>(type())<<">");
00384     }
00385 
00390     template<typename ValueType>
00391     inline const ValueType& unsafe_get() const
00392     {
00393         bbtkDebugMessage("Data",1,
00394                          HumanTypeName<self>()
00395                          <<"::unsafe_get<"
00396                          <<HumanTypeName<ValueType>()<<"> with content : "
00397                          <<HumanTypeName(this->type())
00398                          <<std::endl);
00399 
00400         //      PrintValueIfIsPointer<ValueType>(static_cast< anyholder<ValueType> * >(content)->held);
00401         //      int** i = (int**)(&static_cast< anyholder<ValueType> * >(content)->held);
00402         //      std::cout << "v="<<*i<<std::endl;
00403 
00404         if (content) 
00405           return static_cast< anyholder<ValueType> * >(content)->held;
00406         
00407         bbtkError(HumanTypeName<self >()
00408                   <<"::usafe_get<"
00409                   <<bbtk::HumanTypeName<ValueType>()
00410                   <<"> : void content");
00411     }
00412 
00413 
00414     inline void* get_pointer() const 
00415     {
00416       void* p = content->get_pointer();
00417       bbtkDebugMessage("Data",1,
00418                        HumanTypeName<self>()
00419                        <<"::get_pointer() with content <"
00420                        <<HumanTypeName(this->type())
00421                        <<"> : result = "
00422                        << p
00423                        <<std::endl);
00424       return p;
00425     }
00426     
00427     inline void* get_pointer_to(const std::type_info& t) const 
00428     {
00429       void* p = content->get_pointer_to(t);
00430       bbtkDebugMessage("Data",1,
00431                        HumanTypeName<self>()
00432                        <<"::get_pointer_to("<<HumanTypeName(t)
00433                        <<") with content <"
00434                        <<HumanTypeName(this->type())
00435                        <<"> : result = "
00436                        << p
00437                        <<std::endl);
00438       return p;
00439     }
00440     
00441   private: 
00443     anyplaceholder * content;
00444     
00445   };
00446 
00447   
00448 
00450   template <typename T> struct thing { static const bool value = true; };
00451 
00452   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(bbtk::any<bbtk::thing>,"anything");
00453 
00454 
00456   template <typename T> struct integer { static const bool value; };
00457   template <class T> const bool integer<T>::value = false;
00458 
00460   template <typename T> struct floating_point { static const bool value; };
00461   template <class T> const bool floating_point<T>::value = false;
00462 
00463 
00465   template <typename T> struct number { static const bool value; };
00466   template <class T> const bool number<T>::value = 
00467              integer<T>::value || floating_point<T>::value ;
00468   
00469   
00474 #define BBTK_DECLARE_TYPE_TRAITS(NAME)                                  \
00475   template <typename T> struct NAME { static const bool value; };       \
00476     template <class T> const bool NAME<T>::value = false;
00477   
00478 #define BBTK_ADD_TO_TYPE_TRAITS(NAME,TYPE)      \
00479   template <> bool NAME<TYPE>::value = true;
00480 
00481 
00482 }
00483 
00484 
00485 
00486 
00487 
00488 #endif
00489 

Generated on Wed Nov 12 11:37:08 2008 for BBTK by  doxygen 1.5.6