/*! @file @author Albert Semenov @date 10/2008 */ /* This file is part of MyGUI. MyGUI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. MyGUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with MyGUI. If not, see . */ // -- Based on boost::any, original copyright information follows -- // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. // // Distributed under the Boost Software License, Version 1.0. // (See at http://www.boost.org/LICENSE_1_0.txt) // -- End original copyright -- #ifndef __MYGUI_ANY_H__ #define __MYGUI_ANY_H__ #include "MyGUI_Prerequest.h" #include "MyGUI_Diagnostic.h" #include #ifndef MYGUI_RTTI_DISABLE_TYPE_INFO #include #endif namespace MyGUI { /** @example "Class Any usage" @code void f() { // RU: тестовый класс, с простыми типами все аналогично // EN: test class, with simple types all is similar struct Data { int value; }; // RU: экземпляр и инициализация // EN: instance and initialization Data data; data.value = 0xDEAD; // RU: создастся копия класса Data // EN: copy of class Data will be created MyGUI::Any any = data; // RU: копия класса Data // EN: copy of class Data Data copy_data = *any.castType(); // RU: теперь value == 0xDEAD // EN: now value == 0xDEAD int value = copy_data.value; // RU: создастся копия указателя на класс Data // EN: copy of pointer on class Data will be created any = &data; // RU: копия указателя на класс Data и конкретно на объект data // EN: copy of pointer on class Data and on object data Data* copy_ptr = *any.castType(); // RU: теперь data.value == 0 // EN: now value == 0 copy_ptr->value = 0; } @endcode */ class MYGUI_EXPORT Any { public: struct AnyEmpty { }; static AnyEmpty Null; Any(); Any(const Any::AnyEmpty& value); Any(const Any& other); template Any(const ValueType& value) : mContent(new Holder(value)) { } ~Any(); Any& swap(Any& rhs); template Any& operator = (const ValueType& rhs) { Any(rhs).swap(*this); return *this; } Any& operator = (const Any::AnyEmpty& rhs); Any& operator = (const Any& rhs); bool empty() const; #ifndef MYGUI_RTTI_DISABLE_TYPE_INFO const std::type_info& getType() const; template ValueType* castType(bool _throw = true) const { if (this->getType() == typeid(ValueType)) return &static_cast *>(this->mContent)->held; MYGUI_ASSERT(!_throw, "Bad cast from type '" << getType().name() << "' to '" << typeid(ValueType).name() << "'"); return nullptr; } #else template ValueType* castType(bool _throw = true) const { Any::Holder* data = dynamic_cast *>(this->mContent); if (data != nullptr) return &data->held; MYGUI_ASSERT(!_throw, "Bad cast any"); return nullptr; } #endif void* castUnsafe() const; private: class Placeholder { public: virtual ~Placeholder() { } public: #ifndef MYGUI_RTTI_DISABLE_TYPE_INFO virtual const std::type_info& getType() const = 0; #endif virtual Placeholder* clone() const = 0; }; template class Holder : public Placeholder { public: Holder(const ValueType& value) : held(value) { } public: #ifndef MYGUI_RTTI_DISABLE_TYPE_INFO virtual const std::type_info& getType() const { return typeid(ValueType); } #endif virtual Placeholder* clone() const { return new Holder(held); } public: ValueType held; private: Holder& operator=(const Holder&); }; private: Placeholder* mContent; }; } // namespace MyGUI #endif // __MYGUI_ANY_H__