// 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 <memory> #include <typeinfo> 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 <typename T> any ( const T& item ) { typedef typename basic_type<T>::type U; data.reset(new derived<U>(item)); } void clear ( ) { data.reset(); } template <typename T> bool contains ( ) const { typedef typename basic_type<T>::type U; return dynamic_cast<derived<U>*>(data.get()) != 0; } bool is_empty( ) const { return data.get() == 0; } template <typename T> T& cast_to( ) { typedef typename basic_type<T>::type U; derived<U>* d = dynamic_cast<derived<U>*>(data.get()); if (d == 0) { throw bad_any_cast(); } return d->item; } template <typename T> const T& cast_to( ) const { typedef typename basic_type<T>::type U; derived<U>* d = dynamic_cast<derived<U>*>(data.get()); if (d == 0) { throw bad_any_cast(); } return d->item; } template <typename T> T& get( ) { typedef typename basic_type<T>::type U; derived<U>* d = dynamic_cast<derived<U>*>(data.get()); if (d == 0) { d = new derived<U>(); 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<base>& dest ) const = 0; }; template <typename T> struct derived : public base { T item; derived() {} derived(const T& val) : item(val) {} virtual void copy_to ( std::unique_ptr<base>& dest ) const { dest.reset(new derived<T>(item)); } }; std::unique_ptr<base> data; }; // ---------------------------------------------------------------------------------------- inline void swap ( any& a, any& b ) { a.swap(b); } // ---------------------------------------------------------------------------------------- template <typename T> T& any_cast(any& a) { return a.cast_to<T>(); } template <typename T> const T& any_cast(const any& a) { return a.cast_to<T>(); } // ---------------------------------------------------------------------------------------- } #endif // DLIB_AnY_H_