storage.hpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. #ifndef BOOST_TYPE_ERASURE_DETAIL_STORAGE_HPP_INCLUDED
  11. #define BOOST_TYPE_ERASURE_DETAIL_STORAGE_HPP_INCLUDED
  12. #include <boost/config.hpp>
  13. #include <boost/type_traits/remove_reference.hpp>
  14. #include <boost/type_traits/decay.hpp>
  15. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  16. # include <utility> // for std::forward, std::move
  17. #endif
  18. #ifdef BOOST_MSVC
  19. #pragma warning(push)
  20. #pragma warning(disable:4521)
  21. #endif
  22. namespace boost {
  23. namespace type_erasure {
  24. namespace detail {
  25. struct storage
  26. {
  27. storage() {}
  28. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  29. storage(storage& other) : data(other.data) {}
  30. storage(const storage& other) : data(other.data) {}
  31. storage(storage&& other) : data(other.data) {}
  32. storage& operator=(const storage& other) { data = other.data; return *this; }
  33. template<class T>
  34. explicit storage(T&& arg) : data(new typename boost::decay<T>::type(std::forward<T>(arg))) {}
  35. #else
  36. template<class T>
  37. explicit storage(const T& arg) : data(new typename boost::decay<T>::type(arg)) {}
  38. #endif
  39. void* data;
  40. };
  41. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  42. template<class T>
  43. T extract(T arg) { return std::forward<T>(arg); }
  44. #else
  45. template<class T>
  46. T extract(T arg) { return arg; }
  47. #endif
  48. template<class T>
  49. T extract(storage& arg)
  50. {
  51. return *static_cast<typename ::boost::remove_reference<T>::type*>(arg.data);
  52. }
  53. template<class T>
  54. T extract(const storage& arg)
  55. {
  56. return *static_cast<const typename ::boost::remove_reference<T>::type*>(arg.data);
  57. }
  58. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  59. template<class T>
  60. T extract(storage&& arg)
  61. {
  62. return std::move(*static_cast<typename ::boost::remove_reference<T>::type*>(arg.data));
  63. }
  64. #endif
  65. }
  66. }
  67. }
  68. #ifdef BOOST_MSVC
  69. #pragma warning(pop)
  70. #endif
  71. #endif