make_unique.h
Go to the documentation of this file.
1 // This is free and unencumbered software released into the public domain.
2 
3 // Anyone is free to copy, modify, publish, use, compile, sell, or
4 // distribute this software, either in source code form or as a compiled
5 // binary, for any purpose, commercial or non-commercial, and by any
6 // means.
7 
8 // In jurisdictions that recognize copyright laws, the author or authors
9 // of this software dedicate any and all copyright interest in the
10 // software to the public domain. We make this dedication for the benefit
11 // of the public at large and to the detriment of our heirs and
12 // successors. We intend this dedication to be an overt act of
13 // relinquishment in perpetuity of all present and future rights to this
14 // software under copyright law.
15 
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 // OTHER DEALINGS IN THE SOFTWARE.
23 
24 // Implementation of C++14's make_unique for C++11 compilers.
25 //
26 // This has been tested with:
27 // - MSVC 11.0 (Visual Studio 2012)
28 // - gcc 4.6.3
29 // - Xcode 4.4 (with clang "4.0")
30 //
31 // It is based off an implementation proposed by Stephan T. Lavavej for
32 // inclusion in the C++14 standard:
33 // http://isocpp.org/files/papers/N3656.txt
34 // Where appropriate, it borrows the use of MSVC's _VARIADIC_EXPAND_0X macro
35 // machinery to compensate for lack of variadic templates.
36 //
37 // This file injects make_unique into the std namespace, which I acknowledge is
38 // technically forbidden ([C++11: 17.6.4.2.2.1/1]), but is necessary in order
39 // to have syntax compatibility with C++14.
40 //
41 // I perform compiler version checking for MSVC, gcc, and clang to ensure that
42 // we don't add make_unique if it is already there (instead, we include
43 // <memory> to get the compiler-provided one). You can override the compiler
44 // version checking by defining the symbol COMPILER_SUPPORTS_MAKE_UNIQUE.
45 //
46 //
47 // ===============================================================================
48 // This file is released into the public domain. See LICENCE for more information.
49 // ===============================================================================
50 
51 #pragma once
52 
53 // If user hasn't specified COMPILER_SUPPORTS_MAKE_UNIQUE then try to figure out
54 // based on compiler version if std::make_unique is provided.
55 #if !defined(COMPILER_SUPPORTS_MAKE_UNIQUE)
56 #if defined(_MSC_VER)
57 // std::make_unique was added in MSVC 12.0
58 #if _MSC_VER >= 1800 // MSVC 12.0 (Visual Studio 2013)
59 #define COMPILER_SUPPORTS_MAKE_UNIQUE
60 #endif
61 #elif defined(__clang__)
62 // std::make_unique was added in clang 3.4, but not until Xcode 6.
63 // Annoyingly, Apple makes the clang version defines match the version
64 // of Xcode, not the version of clang.
65 #define CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
66 #if defined(__APPLE__) && CLANG_VERSION >= 60000
67 #define COMPILER_SUPPORTS_MAKE_UNIQUE
68 #elif !defined(__APPLE__) && CLANG_VERSION >= 30400
69 #define COMPILER_SUPPORTS_MAKE_UNIQUE
70 #endif
71 #elif defined(__GNUC__)
72 // std::make_unique was added in gcc 4.9, for standards versions greater
73 // than -std=c++11.
74 #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
75 #if GCC_VERSION >= 40900 && __cplusplus > 201103L
76 #define COMPILER_SUPPORTS_MAKE_UNIQUE
77 #endif
78 #endif
79 #endif
80 
81 #if defined(COMPILER_SUPPORTS_MAKE_UNIQUE)
82 
83 // If the compiler supports std::make_unique, then pull in <memory> to get it.
84 #include <memory>
85 
86 #else
87 
88 // Otherwise, the compiler doesn't provide it, so implement it ourselves.
89 
90 #include <cstddef>
91 #include <memory>
92 #include <type_traits>
93 #include <utility>
94 
95 namespace std
96 {
97 template <class _Ty>
98 struct _Unique_if
99 {
100  typedef unique_ptr<_Ty> _Single_object;
101 };
102 
103 template <class _Ty>
104 struct _Unique_if<_Ty[]>
105 {
106  typedef unique_ptr<_Ty[]> _Unknown_bound;
107 };
108 
109 template <class _Ty, size_t N>
110 struct _Unique_if<_Ty[N]>
111 {
112  typedef void _Known_bound;
113 };
114 
115 //
116 // template< class T, class... Args >
117 // unique_ptr<T> make_unique( Args&&... args);
118 //
119 
120 #if defined(_MSC_VER) && (_MSC_VER < 1800)
121 
122 // Macro machinery because MSVC 11.0 doesn't support variadic templates.
123 // The _VARIADIC_EXPAND_0X stuff is defined in <xstddef>
124 #define _MAKE_UNIQUE(TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
125  template <class _Ty COMMA LIST(_CLASS_TYPE)> \
126  inline typename _Unique_if<_Ty>::_Single_object make_unique(LIST(_TYPE_REFREF_ARG)) \
127  { \
128  return unique_ptr<_Ty>(new _Ty(LIST(_FORWARD_ARG))); \
129  }
130 
131 _VARIADIC_EXPAND_0X(_MAKE_UNIQUE, , , , )
132 #undef _MAKE_UNIQUE
133 
134 #else // not MSVC 11.0 or earlier
135 
136 template <class _Ty, class... Args>
138 {
139  return unique_ptr<_Ty>(new _Ty(std::forward<Args>(args)...));
140 }
141 
142 #endif
143 
144 // template< class T >
145 // unique_ptr<T> make_unique( std::size_t size );
146 
147 template <class _Ty>
149 {
150  typedef typename remove_extent<_Ty>::type U;
151  return unique_ptr<_Ty>(new U[n]());
152 }
153 
154 // template< class T, class... Args >
155 // /* unspecified */ make_unique( Args&&... args ) = delete;
156 
157 // MSVC 11.0 doesn't support deleted functions, so the best we can do
158 // is simply not define the function.
159 #if !(defined(_MSC_VER) && (_MSC_VER < 1800))
160 
161 template <class T, class... Args>
162 typename _Unique_if<T>::_Known_bound make_unique(Args&&...) = delete;
163 
164 #endif
165 
166 } // namespace std
167 
168 #endif // !COMPILER_SUPPORTS_MAKE_UNIQUE
unique_ptr< _Ty[]> _Unknown_bound
Definition: make_unique.h:106
unique_ptr< _Ty > _Single_object
Definition: make_unique.h:100
_Unique_if< _Ty >::_Single_object make_unique(Args &&...args)
Definition: make_unique.h:137


packml_sm
Author(s): Shaun Edwards
autogenerated on Fri Jul 12 2019 03:30:55