std2_make_unique.hpp 1.65 KB
Newer Older
zhaoyunfei's avatar
zhaoyunfei committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
/** ==========================================================================
 * 2013 This is PUBLIC DOMAIN to use at your own risk and comes
 * with no warranties. This code is yours to share, use and modify with no
 * strings attached and no restrictions or obligations.
 *
 * For more information see g3log/LICENSE or refer refer to http://unlicense.org
 *
 * make_unique will be in C++14, this implementation is copied as I understood
 * Stephan T. Lavavej's description of it.
 *
 * PUBLIC DOMAIN and NOT under copywrite protection.
 *
 *
 * Example: usage
 * auto an_int = make_unique<int>(123);
 * auto a_string = make_unique<string>(5, 'x');
 * auto an_int_array = make_unique<int[]>(11, 22, 33);
 * ********************************************* */

#pragma once

#include <memory>
#include <type_traits>

namespace std2 {
   namespace impl_fut_stl {

      template<typename T, typename ... Args>
      std::unique_ptr<T> make_unique_helper(std::false_type, Args &&... args) {
         return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
      }

      template<typename T, typename ... Args>
      std::unique_ptr<T> make_unique_helper(std::true_type, Args &&... args) {
         static_assert(std::extent<T>::value == 0, "make_unique<T[N]>() is forbidden, please use make_unique<T[]>(),");
         typedef typename std::remove_extent<T>::type U;
         return std::unique_ptr<T>(new U[sizeof...(Args)] {std::forward<Args>(args)...});
      }
   }

   template<typename T, typename ... Args>
   std::unique_ptr<T> make_unique(Args &&... args) {
      return impl_fut_stl::make_unique_helper<T>(
                std::is_array<T>(), std::forward<Args>(args)...);
   }
}