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)52 T extract(T arg) { return std::forward<T>(arg); }
53 
54 #else
55 
56 template<class T>
extract(T arg)57 T extract(T arg) { return arg; }
58 
59 #endif
60 
61 template<class T>
extract(storage & arg)62 T 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)68 T 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)76 T 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