/*========================================================================= Program: bbtk Module: $RCSfile: bbtkData.h,v $ Language: C++ Date: $Date: 2008/01/22 15:02:00 $ Version: $Revision: 1.1 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See doc/license.txt or http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /** *\file *\brief Defines Data and TypeInfo * * Data is bbtk general type exchanged between black boxes (adapted from boost::any). * TypeInfo is the bbtk type of object storing informations on a data type (typedef on std::type_info). */ #ifndef __bbtkData_h__ #define __bbtkData_h__ //#include "bbtkSystem.h" //#include "bbtkMessageManager.h" //#include //#include //#include "bbtkany.h" //#include "bbtkReferenceCountedObject.h" #include "bbtkAny.h" namespace bbtk { typedef any Data; /* /// Can transport any kind of data (adaptation of boost::any) class Data { public: // structors Data() : content(0) { } template Data(const ValueType & value) : content(new holder(value)) { } Data(const Data & other) : content(other.content ? other.content->clone() : 0) { } ~Data() { delete content; } public: // modifiers Data & swap(Data & rhs) { std::swap(content, rhs.content); return *this; } template Data & operator=(const ValueType & rhs) { Data(rhs).swap(*this); return *this; } Data & operator=(const Data & rhs) { Data(rhs).swap(*this); return *this; } public: // queries bool empty() const { return !content; } const std::type_info & type() const { return content ? content->type() : typeid(void); } #ifndef BBTK_NO_MEMBER_TEMPLATE_FRIENDS private: // types #else public: // types (public so Data_cast can be non-friend) #endif class placeholder { public: // structors virtual ~placeholder() { } public: // queries virtual const std::type_info & type() const = 0; virtual placeholder * clone() const = 0; }; template class holder : public placeholder { public: // structors holder(const ValueType & value) : held(value) { } public: // queries virtual const std::type_info & type() const { return typeid(ValueType); } virtual placeholder * clone() const { return new holder(held); } public: // representation ValueType held; }; #ifndef BBTK_NO_MEMBER_TEMPLATE_FRIENDS private: // representation // template // friend ValueType * Data_cast(Data *); template friend ValueType * unsafe_Data_cast(Data *); template friend ValueType unsafe_Data_cast(Data &); #else public: // representation (public so Data_cast can be non-friend) #endif placeholder * content; }; class bad_Data_cast : public std::bad_cast { public: virtual const char * what() const throw() { return "bbtk::bad_Data_cast: " "failed conversion using bbtk::Data_cast"; } }; */ /* template ValueType * Data_cast(Data * operand) { return operand && operand->type() == typeid(ValueType) ? &static_cast *>(operand->content)->held : 0; } template const ValueType * Data_cast(const Data * operand) { return Data_cast(const_cast(operand)); } // Removed Data_cast template ValueType Data_cast(const Data & operand) { typedef BBTK_DEDUCED_TYPENAME remove_reference::type nonref; #ifdef BBTK_NO_TEMPLATE_PARTIAL_SPECIALIZATION // If 'nonref' is still reference type, it means the user has not // specialized 'remove_reference'. // Please use BBTK_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro // to generate specialization of remove_reference for your class // See type traits library documentation for details BBTK_STATIC_ASSERT(!is_reference::value); #endif const nonref * result = Data_cast(&operand); if(!result) bbtk::throw_exception(bad_Data_cast()); return *result; } template ValueType Data_cast(Data & operand) { typedef BBTK_DEDUCED_TYPENAME remove_reference::type nonref; #ifdef BBTK_NO_TEMPLATE_PARTIAL_SPECIALIZATION // The comment in the above version of 'Data_cast' explains when this // assert is fired and what to do. BBTK_STATIC_ASSERT(!is_reference::value); #endif nonref * result = Data_cast(&operand); if(!result) bbtk::throw_exception(bad_Data_cast()); return *result; } */ // Note: The "unsafe" versions of Data_cast are not part of the // public interface and may be removed at Data time. They are // required where we know what type is stored in the Data and can't // use typeid() comparison, e.g., when our types may travel across // different shared libraries. // LG : This is precisely our case ! /* template inline ValueType * unsafe_Data_cast(Data * operand) { return &static_cast *>(operand->content)->held; } template inline const ValueType * unsafe_Data_cast(const Data * operand) { return unsafe_Data_cast(const_cast(operand)); } template inline ValueType unsafe_Data_cast(Data & operand) { return static_cast *>(operand.content)->held; } template inline ValueType unsafe_Data_cast(const Data & operand) { return *unsafe_Data_cast(const_cast(&operand)); } */ }// namespace bbtk #endif