Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / type_erasure / detail / storage.hpp
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/remove_cv.hpp>
17
18 #ifdef BOOST_MSVC
19 #pragma warning(push)
20 #pragma warning(disable:4521)
21 #endif
22
23 namespace boost {
24 namespace type_erasure {
25 namespace detail {
26
27 struct storage
28 {
29     storage() {}
30 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
31     storage(storage& other) : data(other.data) {}
32     storage(const storage& other) : data(other.data) {}
33     storage(storage&& other) : data(other.data) {}
34     storage& operator=(const storage& other) { data = other.data; return *this; }
35     template<class T>
36     storage(T&& arg) : data(new typename remove_cv<
37         typename remove_reference<T>::type>::type(std::forward<T>(arg))) {}
38 #else
39     template<class T>
40     storage(const T& arg) : data(new T(arg)) {}
41 #endif
42     void* data;
43 };
44
45
46 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
47
48 template<class T>
49 T extract(T arg) { return std::forward<T>(arg); }
50
51 #else
52
53 template<class T>
54 T extract(T arg) { return arg; }
55
56 #endif
57
58 template<class T>
59 T extract(storage& arg)
60 {
61     return *static_cast<typename ::boost::remove_reference<T>::type*>(arg.data);
62 }
63
64 template<class T>
65 T extract(const storage& arg)
66 {
67     return *static_cast<const typename ::boost::remove_reference<T>::type*>(arg.data);
68 }
69
70 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
71
72 template<class T>
73 T extract(storage&& arg)
74 {
75     return std::move(*static_cast<typename ::boost::remove_reference<T>::type*>(arg.data));
76 }
77
78 #endif
79
80 }
81 }
82 }
83
84 #ifdef BOOST_MSVC
85 #pragma warning(pop)
86 #endif
87
88 #endif