// Copyright (C) 2010 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_AnY_H_ #define DLIB_AnY_H_ #include "any_abstract.h" #include "../algs.h" #include #include namespace dlib { // ---------------------------------------------------------------------------------------- class bad_any_cast : public std::bad_cast { public: virtual const char * what() const throw() { return "bad_any_cast"; } }; // ---------------------------------------------------------------------------------------- class any { public: any() { } any ( const any& item ) { if (item.data) { item.data->copy_to(data); } } template any ( const T& item ) { typedef typename basic_type::type U; data.reset(new derived(item)); } void clear ( ) { data.reset(); } template bool contains ( ) const { typedef typename basic_type::type U; return dynamic_cast*>(data.get()) != 0; } bool is_empty( ) const { return data.get() == 0; } template T& cast_to( ) { typedef typename basic_type::type U; derived* d = dynamic_cast*>(data.get()); if (d == 0) { throw bad_any_cast(); } return d->item; } template const T& cast_to( ) const { typedef typename basic_type::type U; derived* d = dynamic_cast*>(data.get()); if (d == 0) { throw bad_any_cast(); } return d->item; } template T& get( ) { typedef typename basic_type::type U; derived* d = dynamic_cast*>(data.get()); if (d == 0) { d = new derived(); data.reset(d); } return d->item; } any& operator= ( const any& item ) { any(item).swap(*this); return *this; } void swap ( any& item ) { data.swap(item.data); } private: struct base { virtual ~base() {} virtual void copy_to ( std::unique_ptr& dest ) const = 0; }; template struct derived : public base { T item; derived() {} derived(const T& val) : item(val) {} virtual void copy_to ( std::unique_ptr& dest ) const { dest.reset(new derived(item)); } }; std::unique_ptr data; }; // ---------------------------------------------------------------------------------------- inline void swap ( any& a, any& b ) { a.swap(b); } // ---------------------------------------------------------------------------------------- template T& any_cast(any& a) { return a.cast_to(); } template const T& any_cast(const any& a) { return a.cast_to(); } // ---------------------------------------------------------------------------------------- } #endif // DLIB_AnY_H_