MeshKit
1.0
|
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 }