make_unique.hpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. Copyright 2012-2015 Glen Joseph Fernandes
  3. (glenjofe@gmail.com)
  4. Distributed under the Boost Software License, Version 1.0.
  5. (http://www.boost.org/LICENSE_1_0.txt)
  6. */
  7. #ifndef BOOST_SMART_PTR_MAKE_UNIQUE_HPP
  8. #define BOOST_SMART_PTR_MAKE_UNIQUE_HPP
  9. #include <boost/config.hpp>
  10. #include <memory>
  11. #include <utility>
  12. namespace boost {
  13. namespace detail {
  14. template<class T>
  15. struct up_if_object {
  16. typedef std::unique_ptr<T> type;
  17. };
  18. template<class T>
  19. struct up_if_object<T[]> { };
  20. template<class T, std::size_t N>
  21. struct up_if_object<T[N]> { };
  22. template<class T>
  23. struct up_if_array { };
  24. template<class T>
  25. struct up_if_array<T[]> {
  26. typedef std::unique_ptr<T[]> type;
  27. };
  28. template<class T>
  29. struct up_remove_reference {
  30. typedef T type;
  31. };
  32. template<class T>
  33. struct up_remove_reference<T&> {
  34. typedef T type;
  35. };
  36. template<class T>
  37. struct up_remove_reference<T&&> {
  38. typedef T type;
  39. };
  40. template<class T>
  41. struct up_element { };
  42. template<class T>
  43. struct up_element<T[]> {
  44. typedef T type;
  45. };
  46. } /* detail */
  47. template<class T>
  48. inline typename detail::up_if_object<T>::type
  49. make_unique()
  50. {
  51. return std::unique_ptr<T>(new T());
  52. }
  53. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  54. template<class T, class... Args>
  55. inline typename detail::up_if_object<T>::type
  56. make_unique(Args&&... args)
  57. {
  58. return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
  59. }
  60. #endif
  61. template<class T>
  62. inline typename detail::up_if_object<T>::type
  63. make_unique(typename detail::up_remove_reference<T>::type&& value)
  64. {
  65. return std::unique_ptr<T>(new T(std::move(value)));
  66. }
  67. template<class T>
  68. inline typename detail::up_if_object<T>::type
  69. make_unique_noinit()
  70. {
  71. return std::unique_ptr<T>(new T);
  72. }
  73. template<class T>
  74. inline typename detail::up_if_array<T>::type
  75. make_unique(std::size_t size)
  76. {
  77. return std::unique_ptr<T>(new typename
  78. detail::up_element<T>::type[size]());
  79. }
  80. template<class T>
  81. inline typename detail::up_if_array<T>::type
  82. make_unique_noinit(std::size_t size)
  83. {
  84. return std::unique_ptr<T>(new typename
  85. detail::up_element<T>::type[size]);
  86. }
  87. } /* boost */
  88. #endif