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