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: 2010/01/14 13:17:27 $
00006   Version:   $Revision: 1.8 $
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 
00036 #ifndef __BBTKANY_H_INCLUDED__
00037 #define __BBTKANY_H_INCLUDED__
00038 
00039 /*
00040 #include <string>
00041 #include <iostream>
00042 #include <typeinfo>
00043 #include <set>
00044 #include <map>
00045 #include <sstream>
00046 #include <exception>
00047 
00048 #include <cxxabi.h>
00049 */
00050 #include <sstream>
00051 #include "bbtkRTTI.h"
00052 #include "bbtkMessageManager.h"
00053 #include "bbtkException.h"
00054 
00055 #include <boost/type_traits/is_pointer.hpp>
00056 
00057 namespace bbtk 
00058 {
00059 
00060 
00061 
00062 
00063 
00064   //=========================================================
00066   class anyplaceholder
00067   {
00068   public: // structors
00069     
00070     virtual ~anyplaceholder() {}
00071     
00072   public: // queries
00073     
00075     virtual const std::type_info & type() const = 0;
00077     virtual const std::type_info & pointed_type() const = 0;
00078     
00080     virtual bool is_pointer() const = 0;
00081     
00084     virtual void* get_pointer() const = 0;
00085  
00087     virtual void* get_pointer_to( const std::type_info& ) const = 0;
00088    
00089     virtual anyplaceholder * clone() const = 0;
00090     
00091   };
00092   //=========================================================
00093   
00094   //=========================================================
00097   template<typename ValueType>
00098   class anyholder : public anyplaceholder
00099   {
00100   public: // structors
00101     
00102     anyholder(const ValueType & value)
00103       : held(value)
00104     {}
00105     
00106   public: // queries
00107     
00108     virtual const std::type_info & type() const { return typeid(ValueType);}
00109     virtual bool is_pointer() const { return false; }
00110     virtual const std::type_info & pointed_type() const { return typeid(void); }
00111     virtual void* get_pointer() const { return 0; }
00112     virtual void* get_pointer_to( const std::type_info& ) const { return 0; }
00113     virtual anyplaceholder * clone() const { return new anyholder(held); }
00114     
00115     public: // representation
00116     
00117     ValueType held;
00118     
00119   };
00120   //=========================================================
00121   
00122   //=========================================================
00124   template<typename ValueType>
00125   class anyholder<ValueType*> : public anyplaceholder
00126   {
00127   public: // structors
00128 
00129     anyholder(ValueType* const & value)
00130       : held(value)
00131     { }
00132 
00133   public: // queries
00134 
00135     virtual const std::type_info & type() const
00136     {
00137       return typeid(ValueType*);
00138     }
00139 
00140     virtual bool is_pointer() const { return true; }
00141     virtual const std::type_info & pointed_type() const { return typeid(ValueType); }
00142     virtual void* get_pointer() const { 
00143       return (void*)held; 
00144     }
00145     virtual void* get_pointer_to( const std::type_info& t) const 
00146     { 
00147       return run_time_up_or_down_cast(t,typeid(ValueType),held);
00148     }
00149 
00150     virtual anyplaceholder * clone() const { return new anyholder(held); }
00151 
00152   public: // representation
00153 
00154     ValueType* held;
00155 
00156   };
00157   //=========================================================
00158 
00159 
00183   template <template <class> class TypeTraits >
00184   class any
00185   {
00186   public:
00187     typedef any< TypeTraits > self;
00188     // structors
00189 
00191     any()
00192       : content(0)
00193     {
00194     }
00195 
00197     template<typename ValueType>
00198     any(const ValueType & value)
00199       : content(0)
00200     {
00201       bbtkDebugMessage("Data",1,
00202                        bbtk::HumanTypeName<self>()<<" construction with <"
00203                        <<bbtk::HumanTypeName<ValueType>()<<">"<<std::endl);
00204       //      ValueType v = value;
00205       //      int** i = (int**)(&v);
00206       //      std::cout << "v="<<*i<<std::endl;
00207       
00208       if (accepts<ValueType>()) 
00209         { 
00210           content = new anyholder<ValueType>(value);
00211         }
00212       else 
00213         {
00214           bbtkError(bbtk::HumanTypeName<self>()
00215                     <<" constructor : data of type <"
00216                     <<bbtk::HumanTypeName<ValueType>()
00217                     <<"> are not accepted by traits <"
00218                     <<bbtk::HumanTypeName<TypeTraits<void> >()<<"> ");
00219         }
00220     }
00221   
00223     any(const any & other)
00224       : content(other.content ? other.content->clone() : 0)
00225     {
00226       bbtkDebugMessage("Data",1,
00227                        HumanTypeName<self>()
00228                        <<" copy construction with new content : "
00229                        <<HumanTypeName(type())
00230                        <<std::endl);
00231     }
00232   
00234     ~any()
00235     {
00236       delete content;
00237     }
00238 
00239 
00241     any & swap(any & rhs)
00242     {
00243       std::swap(content, rhs.content);
00244       return *this;
00245     }
00246 
00248     template<typename ValueType>
00249     any & operator=(const ValueType & rhs)
00250     {
00251       bbtkDebugMessage("Data",1,
00252                        HumanTypeName<self>()
00253                        <<" operator= with data of type <"
00254                        <<HumanTypeName<ValueType>()
00255                        <<">"<<std::endl);
00256       if (accepts<ValueType>()) 
00257         {
00258           any(rhs).swap(*this);
00259           return *this;
00260         }
00261       else 
00262         {
00263           bbtkError(HumanTypeName<self>()
00264                     <<" operator= : data of type <"
00265                     <<HumanTypeName<ValueType>()
00266                     <<"> are not accepted by traits <"
00267                     <<HumanTypeName<TypeTraits<void> >()<<"> ");
00268         }
00269     
00270     }
00271   
00273     any & operator=(const any & rhs)
00274     {
00275         bbtkDebugMessage("Data",1,
00276                          HumanTypeName<self >()
00277                          <<" operator=(const any&) with content : "
00278                          <<HumanTypeName(rhs.type())<<std::endl);
00279 
00280       any(rhs).swap(*this);
00281       return *this;
00282     }
00283   
00284 
00286     bool empty() const
00287     {
00288       return !content;
00289     }
00290   
00292     const std::type_info & type() const
00293     {
00294       return content ? content->type() : typeid(void);
00295     }
00296 
00298     const std::type_info & pointed_type() const
00299     {
00300       return content ? content->pointed_type() : typeid(void);
00301     }
00302 
00303 
00305     template<typename Type>
00306     inline bool contains()
00307     {
00308       return ( type() == typeid(Type) );
00309     }
00310 
00312     inline bool contains_pointer()
00313     {
00314       return content ? content->is_pointer() : false;
00315     }
00316 
00318     inline bool contains(TypeInfo t)
00319     {
00320       return ( (bool)((type() == t)!=0) );
00321      }
00322 
00324     template<typename Type>
00325     inline bool accepts()
00326     {
00327       return TypeTraits<Type>::value; //is_valid();
00328     }
00329 
00332     template<typename ValueType>
00333     inline const ValueType& get() const
00334     {
00335         bbtkDebugMessage("Data",1,
00336                          HumanTypeName<self >()
00337                          <<" get<"<<HumanTypeName<ValueType>()
00338                          <<"> with content : "
00339                          <<HumanTypeName(type())<<std::endl);
00340 
00341       if ( type() == typeid(ValueType) )
00342         return static_cast< anyholder<ValueType> *>(content)->held;
00343 
00344       bbtkError(HumanTypeName<self >()
00345                 <<" get with type <"
00346                 <<bbtk::HumanTypeName<ValueType>()
00347                 <<"> does not match content type <"
00348                 <<bbtk::HumanTypeName<>(type())<<">");
00349     }
00350 
00351     template<typename ValueType>
00352     inline const ValueType* getP() const
00353     {
00354       if ( type() == typeid(ValueType) )
00355         return &static_cast< anyholder<ValueType> *>(content)->held;
00356  
00357       bbtkError(HumanTypeName<self >()
00358                 <<" getP with type <"
00359                 <<bbtk::HumanTypeName<ValueType>()
00360                 <<"> does not match content type <"
00361                 <<bbtk::HumanTypeName<>(type())<<">");
00362     }
00363 
00368     template<typename ValueType>
00369     inline const ValueType& unsafe_get() const
00370     {
00371         bbtkDebugMessage("Data",1,
00372                          HumanTypeName<self>()
00373                          <<"::unsafe_get<"
00374                          <<HumanTypeName<ValueType>()<<"> with content : "
00375                          <<HumanTypeName(this->type())
00376                          <<std::endl);
00377 
00378         //      PrintValueIfIsPointer<ValueType>(static_cast< anyholder<ValueType> * >(content)->held);
00379         //      int** i = (int**)(&static_cast< anyholder<ValueType> * >(content)->held);
00380         //      std::cout << "v="<<*i<<std::endl;
00381 
00382         if (content) 
00383           return static_cast< anyholder<ValueType> * >(content)->held;
00384         
00385         bbtkError(HumanTypeName<self >()
00386                   <<"::usafe_get<"
00387                   <<bbtk::HumanTypeName<ValueType>()
00388                   <<"> : void content");
00389     }
00390 
00391 
00392     inline void* get_pointer() const 
00393     {
00394       void* p = content->get_pointer();
00395       bbtkDebugMessage("Data",1,
00396                        HumanTypeName<self>()
00397                        <<"::get_pointer() with content <"
00398                        <<HumanTypeName(this->type())
00399                        <<"> : result = "
00400                        << p
00401                        <<std::endl);
00402       return p;
00403     }
00404     
00405     inline void* get_pointer_to(const std::type_info& t) const 
00406     {
00407       void* p = content->get_pointer_to(t);
00408       bbtkDebugMessage("Data",1,
00409                        HumanTypeName<self>()
00410                        <<"::get_pointer_to("<<HumanTypeName(t)
00411                        <<") with content <"
00412                        <<HumanTypeName(this->type())
00413                        <<"> : result = "
00414                        << p
00415                        <<std::endl);
00416       return p;
00417     }
00418     
00419   private: 
00421     anyplaceholder * content;
00422     
00423   };
00424 
00425   
00426 
00428   template <typename T> struct thing { static const bool value = true; };
00429 
00430   BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(bbtk::any<bbtk::thing>,"anything");
00431 
00432 
00434   template <typename T> struct integer { static const bool value; };
00435   template <class T> const bool integer<T>::value = false;
00436 
00438   template <typename T> struct floating_point { static const bool value; };
00439   template <class T> const bool floating_point<T>::value = false;
00440 
00441 
00443   template <typename T> struct number { static const bool value; };
00444   template <class T> const bool number<T>::value = 
00445              integer<T>::value || floating_point<T>::value ;
00446   
00447   
00452 #define BBTK_DECLARE_TYPE_TRAITS(NAME)                                  \
00453   template <typename T> struct NAME { static const bool value; };       \
00454     template <class T> const bool NAME<T>::value = false;
00455   
00456 #define BBTK_ADD_TO_TYPE_TRAITS(NAME,TYPE)      \
00457   template <> bool NAME<TYPE>::value = true;
00458 
00459 
00460 }
00461 
00462 
00463 
00464 
00465 
00466 #endif
00467 

Generated on Thu May 31 14:12:02 2012 for BBTK by  doxygen 1.5.7.1