1 // Boost.TypeErasure library 2 // 3 // Copyright 2011 Steven Watanabe 4 // 5 // Distributed under the Boost Software License Version 1.0. (See 6 // accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 // 9 // $Id$ 10 11 #ifndef BOOST_TYPE_ERASURE_DETAIL_STORAGE_HPP_INCLUDED 12 #define BOOST_TYPE_ERASURE_DETAIL_STORAGE_HPP_INCLUDED 13 14 #include <boost/config.hpp> 15 #include <boost/type_traits/remove_reference.hpp> 16 #include <boost/type_traits/decay.hpp> 17 18 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 19 # include <utility> // for std::forward, std::move 20 #endif 21 22 #ifdef BOOST_MSVC 23 #pragma warning(push) 24 #pragma warning(disable:4521) 25 #endif 26 27 namespace boost { 28 namespace type_erasure { 29 namespace detail { 30 31 struct storage 32 { storageboost::type_erasure::detail::storage33 storage() {} 34 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES storageboost::type_erasure::detail::storage35 storage(storage& other) : data(other.data) {} storageboost::type_erasure::detail::storage36 storage(const storage& other) : data(other.data) {} storageboost::type_erasure::detail::storage37 storage(storage&& other) : data(other.data) {} operator =boost::type_erasure::detail::storage38 storage& operator=(const storage& other) { data = other.data; return *this; } 39 template<class T> storageboost::type_erasure::detail::storage40 explicit storage(T&& arg) : data(new typename boost::decay<T>::type(std::forward<T>(arg))) {} 41 #else 42 template<class T> storageboost::type_erasure::detail::storage43 explicit storage(const T& arg) : data(new typename boost::decay<T>::type(arg)) {} 44 #endif 45 void* data; 46 }; 47 48 49 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 50 51 template<class T> extract(T arg)52T extract(T arg) { return std::forward<T>(arg); } 53 54 #else 55 56 template<class T> extract(T arg)57T extract(T arg) { return arg; } 58 59 #endif 60 61 template<class T> extract(storage & arg)62T extract(storage& arg) 63 { 64 return *static_cast<typename ::boost::remove_reference<T>::type*>(arg.data); 65 } 66 67 template<class T> extract(const storage & arg)68T extract(const storage& arg) 69 { 70 return *static_cast<const typename ::boost::remove_reference<T>::type*>(arg.data); 71 } 72 73 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES 74 75 template<class T> extract(storage && arg)76T extract(storage&& arg) 77 { 78 return std::move(*static_cast<typename ::boost::remove_reference<T>::type*>(arg.data)); 79 } 80 81 #endif 82 83 } 84 } 85 } 86 87 #ifdef BOOST_MSVC 88 #pragma warning(pop) 89 #endif 90 91 #endif 92