MeshKit  1.0
myany.hpp
Go to the documentation of this file.
00001 
00002 // myany.hpp
00003 #include <memory>
00004 #include <stdexcept>
00005 #include <utility>
00006 
00007 #ifdef __APPLE__
00008 #  define unique_ptr auto_ptr
00009 #endif
00010 
00011 struct myany
00012 {
00013     myany() = default;
00014     template <typename T> myany(T const& v) : _storage(new storage<T>(v)) { }
00015     myany(myany const& other) : _storage()
00016     {
00017           #ifdef __APPLE__
00018                   if (other._storage.get())
00019                       _storage = other._storage->clone();
00020           #else // __APPLE__
00021                   if (other._storage.get())
00022                       _storage = std::move(other._storage->clone());
00023           #endif // __APPLE__
00024     }
00025 
00026     //void swap(myany& other)               { _storage.swap(other._storage); }
00027         void swap(myany& other)
00028           {
00029     #ifdef __APPLE__
00030           std::unique_ptr<storage_base> tmp = _storage;
00031           _storage = other._storage;
00032           other._storage = tmp;
00033     #else // __APPLE__
00034           _storage.swap(other._storage);
00035     #endif // __APPLE__
00036           }
00037     friend void swap(myany& a, myany& b) { a.swap(b); }
00038     myany& operator=(myany other)        { swap(other); return *this; }
00039 
00040     // todo move semantics
00041 private:
00042     struct storage_base {
00043         virtual std::unique_ptr<storage_base> clone() = 0;
00044         virtual ~storage_base() { }
00045     };
00046     template <typename T>
00047     struct storage : storage_base {
00048         T value;
00049         explicit storage(T const& v) : value(v) {}
00050         std::unique_ptr<storage_base> clone() { return std::unique_ptr<storage_base>(new storage<T>(value)); }
00051     };
00052     std::unique_ptr<storage_base> _storage;
00053     template<typename T> friend T      & any_cast(myany      &);
00054     template<typename T> friend T const& any_cast(myany const&);
00055 };
00056 
00057 template <typename T> T& any_cast(myany& a) {
00058     if (auto p = dynamic_cast<myany::storage<T>*>(a._storage.get()))
00059         return p->value;
00060     else
00061         throw std::bad_cast();
00062 }
00063 
00064 template <typename T> T const& any_cast(myany const& a) {
00065     if (auto p = dynamic_cast<myany::storage<T> const*>(a._storage.get()))
00066         return p->value;
00067     else
00068         throw std::bad_cast();
00069 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines