// Boost.TypeErasure library // // Copyright 2011 Steven Watanabe // // Distributed under the Boost Software License Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // $Id$ #ifndef BOOST_TYPE_ERASURE_DETAIL_STORAGE_HPP_INCLUDED #define BOOST_TYPE_ERASURE_DETAIL_STORAGE_HPP_INCLUDED #include #include #include #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES # include // for std::forward, std::move #endif #ifdef BOOST_MSVC #pragma warning(push) #pragma warning(disable:4521) #endif namespace boost { namespace type_erasure { namespace detail { struct storage { storage() {} #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES storage(storage& other) : data(other.data) {} storage(const storage& other) : data(other.data) {} storage(storage&& other) : data(other.data) {} storage& operator=(const storage& other) { data = other.data; return *this; } template explicit storage(T&& arg) : data(new typename boost::decay::type(std::forward(arg))) {} #else template explicit storage(const T& arg) : data(new typename boost::decay::type(arg)) {} #endif void* data; }; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template T extract(T arg) { return std::forward(arg); } #else template T extract(T arg) { return arg; } #endif template T extract(storage& arg) { return *static_cast::type*>(arg.data); } template T extract(const storage& arg) { return *static_cast::type*>(arg.data); } #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template T extract(storage&& arg) { return std::move(*static_cast::type*>(arg.data)); } #endif } } } #ifdef BOOST_MSVC #pragma warning(pop) #endif #endif