// // Any.h // // $Id: //poco/Main/Foundation/include/Poco/Any.h#2 $ // // Library: Foundation // Package: Core // Module: Any // // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. // Extracted from Boost 1.33.1 lib and adapted for poco: Peter Schojer/AppliedInformatics 2006-02-02 // // Permission is hereby granted, free of charge, to any person or organization // obtaining a copy of the software and accompanying documentation covered by // this license (the "Software") to use, reproduce, display, distribute, // execute, and transmit the Software, and to prepare derivative works of the // Software, and to permit third-parties to whom the Software is furnished to // do so, all subject to the following: // // The copyright notices in the Software and this entire statement, including // the above license grant, this restriction and the following disclaimer, // must be included in all copies of the Software, in whole or in part, and // all derivative works of the Software, unless such copies or derivative // works are solely in the form of machine-executable object code generated by // a source language processor. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // #ifndef Foundation_Any_INCLUDED #define Foundation_Any_INCLUDED #include "Poco/Exception.h" #include #include namespace Poco { class Any /// An Any class represents a general type and is capable of storing any type, supporting type-safe extraction /// of the internally stored data. /// /// Code taken from the Boost 1.33.1 library. Original copyright by Kevlin Henney. Modified for Poco /// by Applied Informatics. { public: Any(): _content(0) /// Creates an empty any type. { } template Any(const ValueType& value): _content(new Holder(value)) /// Creates an any which stores the init parameter inside. /// /// Example: /// Any a(13); /// Any a(string("12345")); { } Any(const Any& other): _content(other._content ? other._content->clone() : 0) /// Copy constructor, works with empty Anys and initialized Any values. { } ~Any() { delete _content; } Any& swap(Any& rhs) /// Swaps the content of the two Anys. { std::swap(_content, rhs._content); return *this; } template Any& operator = (const ValueType& rhs) /// Assignment operator for all types != Any. /// /// Example: /// Any a = 13; /// Any a = string("12345"); { Any(rhs).swap(*this); return *this; } Any& operator = (const Any& rhs) /// Assignment operator for Any. { Any(rhs).swap(*this); return *this; } bool empty() const /// returns true if the Any is empty { return !_content; } const std::type_info& type() const /// Returns the type information of the stored content. /// If the Any is empty typeid(void) is returned. /// It is suggested to always query an Any for its type info before trying to extract /// data via an AnyCast/RefAnyCast. { return _content ? _content->type() : typeid(void); } private: class Placeholder { public: virtual ~Placeholder() { } virtual const std::type_info& type() const = 0; virtual Placeholder* clone() const = 0; }; template class Holder: public Placeholder { public: Holder(const ValueType& value): _held(value) { } virtual const std::type_info& type() const { return typeid(ValueType); } virtual Placeholder* clone() const { return new Holder(_held); } ValueType _held; }; private: template friend ValueType* AnyCast(Any*); template friend ValueType* UnsafeAnyCast(Any*); Placeholder* _content; }; template ValueType* AnyCast(Any* operand) /// AnyCast operator used to extract the ValueType from an Any*. Will return a pointer /// to the stored value. /// /// Example Usage: /// MyType* pTmp = AnyCast(pAny). /// Will return NULL if the cast fails, i.e. types don't match. { return operand && operand->type() == typeid(ValueType) ? &static_cast*>(operand->_content)->_held : 0; } template const ValueType* AnyCast(const Any* operand) /// AnyCast operator used to extract a const ValueType pointer from an const Any*. Will return a const pointer /// to the stored value. /// /// Example Usage: /// const MyType* pTmp = AnyCast(pAny). /// Will return NULL if the cast fails, i.e. types don't match. { return AnyCast(const_cast(operand)); } template ValueType AnyCast(const Any& operand) /// AnyCast operator used to extract a copy of the ValueType from an const Any&. /// /// Example Usage: /// MyType tmp = AnyCast(anAny). /// Will throw a BadCastException if the cast fails. /// Dont use an AnyCast in combination with references, i.e. MyType& tmp = ... or const MyType& = ... /// Some compilers will accept this code although a copy is returned. Use the RefAnyCast in /// these cases. { ValueType* result = AnyCast(const_cast(&operand)); if (!result) throw BadCastException("Failed to convert between const Any types"); return *result; } template ValueType AnyCast(Any& operand) /// AnyCast operator used to extract a copy of the ValueType from an Any&. /// /// Example Usage: /// MyType tmp = AnyCast(anAny). /// Will throw a BadCastException if the cast fails. /// Dont use an AnyCast in combination with references, i.e. MyType& tmp = ... or const MyType& tmp = ... /// Some compilers will accept this code although a copy is returned. Use the RefAnyCast in /// these cases. { ValueType* result = AnyCast(&operand); if (!result) throw BadCastException("Failed to convert between Any types"); return *result; } template const ValueType& RefAnyCast(const Any & operand) /// AnyCast operator used to return a const reference to the internal data. /// /// Example Usage: /// const MyType& tmp = RefAnyCast(anAny); { ValueType* result = AnyCast(const_cast(&operand)); if (!result) throw BadCastException("RefAnyCast: Failed to convert between const Any types"); return *result; } template ValueType& RefAnyCast(Any& operand) /// AnyCast operator used to return a reference to the internal data. /// /// Example Usage: /// MyType& tmp = RefAnyCast(anAny); { ValueType* result = AnyCast(&operand); if (!result) throw BadCastException("RefAnyCast: Failed to convert between Any types"); return *result; } template ValueType* UnsafeAnyCast(Any* operand) /// The "unsafe" versions of AnyCast are not part of the /// public interface and may be removed at any time. They are /// required where we know what type is stored in the any and can't /// use typeid() comparison, e.g., when our types may travel across /// different shared libraries. { return &static_cast*>(operand->_content)->_held; } template const ValueType* UnsafeAnyCast(const Any* operand) /// The "unsafe" versions of AnyCast are not part of the /// public interface and may be removed at any time. They are /// required where we know what type is stored in the any and can't /// use typeid() comparison, e.g., when our types may travel across /// different shared libraries. { return AnyCast(const_cast(operand)); } } // namespace Poco #endif