Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RMakeUnique.hxx
Go to the documentation of this file.
1 /// \file ROOT/RMakeUnique.hxx
2 /// \ingroup Base StdExt
3 /// \author Danilo Piparo
4 /// \date 2017-09-22
5 
6 /*************************************************************************
7  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
8  * All rights reserved. *
9  * *
10  * For the licensing terms see $ROOTSYS/LICENSE. *
11  * For the list of contributors see $ROOTSYS/README/CREDITS. *
12  *************************************************************************/
13 
14 #ifndef ROOT_RMakeUnique
15 #define ROOT_RMakeUnique
16 
17 #include <memory>
18 
19 #if __cplusplus < 201402L && !defined(_MSC_VER)
20 
21 #include <type_traits>
22 #include <utility>
23 
24 namespace ROOT {
25 namespace Detail {
26 // Inspired from abseil
27 template <typename T>
28 struct RMakeUniqueResult {
29  using scalar = std::unique_ptr<T>;
30 };
31 template <typename T>
32 struct RMakeUniqueResult<T[]> {
33  using array = std::unique_ptr<T[]>;
34 };
35 template <typename T, size_t N>
36 struct RMakeUniqueResult<T[N]> {
37  using invalid = void;
38 };
39 } // namespace Detail
40 } // namespace ROOT
41 
42 namespace std {
43 
44 // template <typename T, typename... Args, typename std::enable_if<!std::is_array<T>::value, int>::type = 0>
45 template <typename T, typename... Args>
46 typename ROOT::Detail::RMakeUniqueResult<T>::scalar make_unique(Args &&... args)
47 {
48  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
49 }
50 
51 template <typename T>
52 typename ROOT::Detail::RMakeUniqueResult<T>::array make_unique(std::size_t size)
53 {
54  return std::unique_ptr<T>(new typename std::remove_extent<T>::type[size]());
55 }
56 
57 template <typename T, typename... Args>
58 typename ROOT::Detail::RMakeUniqueResult<T>::invalid make_unique(Args &&...) = delete;
59 
60 
61 } // namespace std
62 #endif
63 
64 #endif