blob: ef106dbb55ab5efb021d8ad56ddf6ad8f21a19b2 [file] [log] [blame]
Brian Silverman1f5d3982018-08-04 23:37:52 -07001//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2006-2014. Distributed under the Boost
4// Software License, Version 1.0. (See accompanying file
5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7// See http://www.boost.org/libs/move for documentation.
8//
9//////////////////////////////////////////////////////////////////////////////
10
11#ifndef BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED
12#define BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED
13
14#ifndef BOOST_CONFIG_HPP
15# include <boost/config.hpp>
16#endif
17#
18#if defined(BOOST_HAS_PRAGMA_ONCE)
19# pragma once
20#endif
21
22#include <boost/move/detail/config_begin.hpp>
23#include <boost/move/detail/workaround.hpp>
24#include <boost/move/utility_core.hpp>
25#include <boost/move/unique_ptr.hpp>
26#include <cstddef> //for std::size_t
27#include <boost/move/detail/unique_ptr_meta_utils.hpp>
28#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
29# include <boost/move/detail/fwd_macros.hpp>
30#endif
31
32//!\file
33//! Defines "make_unique" functions, which are factories to create instances
34//! of unique_ptr depending on the passed arguments.
35//!
36//! This header can be a bit heavyweight in C++03 compilers due to the use of the
37//! preprocessor library, that's why it's a a separate header from <tt>unique_ptr.hpp</tt>
38
39#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
40
41namespace std { //no namespace versioning in clang+libc++
42
43struct nothrow_t;
44
45} //namespace std {
46
47namespace boost{
48namespace move_upmu {
49
50//Compile time switch between
51//single element, unknown bound array
52//and known bound array
53template<class T>
54struct unique_ptr_if
55{
56 typedef ::boost::movelib::unique_ptr<T> t_is_not_array;
57};
58
59template<class T>
60struct unique_ptr_if<T[]>
61{
62 typedef ::boost::movelib::unique_ptr<T[]> t_is_array_of_unknown_bound;
63};
64
65template<class T, std::size_t N>
66struct unique_ptr_if<T[N]>
67{
68 typedef void t_is_array_of_known_bound;
69};
70
71template <int Dummy = 0>
72struct nothrow_holder
73{
74 static std::nothrow_t *pnothrow;
75};
76
77template <int Dummy>
78std::nothrow_t *nothrow_holder<Dummy>::pnothrow =
79 reinterpret_cast<std::nothrow_t *>(0x1234); //Avoid reference to null errors in sanitizers
80
81} //namespace move_upmu {
82} //namespace boost{
83
84#endif //!defined(BOOST_MOVE_DOXYGEN_INVOKED)
85
86namespace boost{
87namespace movelib {
88
89#if defined(BOOST_MOVE_DOXYGEN_INVOKED) || !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
90
91//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
92//!
93//! <b>Returns</b>: <tt>unique_ptr<T>(new T(std::forward<Args>(args)...))</tt>.
94template<class T, class... Args>
95inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
96 typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
97 make_unique(BOOST_FWD_REF(Args)... args)
98{ return unique_ptr<T>(new T(::boost::forward<Args>(args)...)); }
99
100//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
101//!
102//! <b>Returns</b>: <tt>unique_ptr<T>(new T(std::nothrow)(std::forward<Args>(args)...))</tt>.
103template<class T, class... Args>
104inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
105 typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
106 make_unique_nothrow(BOOST_FWD_REF(Args)... args)
107{ return unique_ptr<T>(new (*boost::move_upmu::nothrow_holder<>::pnothrow)T(::boost::forward<Args>(args)...)); }
108
109#else
110 #define BOOST_MOVE_MAKE_UNIQUE_CODE(N)\
111 template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
112 typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array\
113 make_unique( BOOST_MOVE_UREF##N)\
114 { return unique_ptr<T>( new T( BOOST_MOVE_FWD##N ) ); }\
115 \
116 template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
117 typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array\
118 make_unique_nothrow( BOOST_MOVE_UREF##N)\
119 { return unique_ptr<T>( new (*boost::move_upmu::nothrow_holder<>::pnothrow)T ( BOOST_MOVE_FWD##N ) ); }\
120 //
121 BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_MAKE_UNIQUE_CODE)
122 #undef BOOST_MOVE_MAKE_UNIQUE_CODE
123
124#endif
125
126//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
127//!
128//! <b>Returns</b>: <tt>unique_ptr<T>(new T)</tt> (default initialization)
129template<class T>
130inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
131 typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
132 make_unique_definit()
133{
134 return unique_ptr<T>(new T);
135}
136
137//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
138//!
139//! <b>Returns</b>: <tt>unique_ptr<T>(new T(std::nothrow)</tt> (default initialization)
140template<class T>
141inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
142 typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
143 make_unique_nothrow_definit()
144{
145 return unique_ptr<T>(new (*boost::move_upmu::nothrow_holder<>::pnothrow)T);
146}
147
148//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of
149//! unknown bound.
150//!
151//! <b>Returns</b>: <tt>unique_ptr<T>(new remove_extent_t<T>[n]())</tt> (value initialization)
152template<class T>
153inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
154 typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
155 make_unique(std::size_t n)
156{
157 typedef typename ::boost::move_upmu::remove_extent<T>::type U;
158 return unique_ptr<T>(new U[n]());
159}
160
161//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of
162//! unknown bound.
163//!
164//! <b>Returns</b>: <tt>unique_ptr<T>(new (std::nothrow)remove_extent_t<T>[n]())</tt> (value initialization)
165template<class T>
166inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
167 typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
168 make_unique_nothrow(std::size_t n)
169{
170 typedef typename ::boost::move_upmu::remove_extent<T>::type U;
171 return unique_ptr<T>(new (*boost::move_upmu::nothrow_holder<>::pnothrow)U[n]());
172}
173
174//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of
175//! unknown bound.
176//!
177//! <b>Returns</b>: <tt>unique_ptr<T>(new remove_extent_t<T>[n])</tt> (default initialization)
178template<class T>
179inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
180 typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
181 make_unique_definit(std::size_t n)
182{
183 typedef typename ::boost::move_upmu::remove_extent<T>::type U;
184 return unique_ptr<T>(new U[n]);
185}
186
187//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of
188//! unknown bound.
189//!
190//! <b>Returns</b>: <tt>unique_ptr<T>(new (std::nothrow)remove_extent_t<T>[n])</tt> (default initialization)
191template<class T>
192inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
193 typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
194 make_unique_nothrow_definit(std::size_t n)
195{
196 typedef typename ::boost::move_upmu::remove_extent<T>::type U;
197 return unique_ptr<T>(new (*boost::move_upmu::nothrow_holder<>::pnothrow) U[n]);
198}
199
200#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
201
202//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
203//! an array of known bound.
204template<class T, class... Args>
205inline BOOST_MOVE_DOC1ST(unspecified,
206 typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
207 make_unique(BOOST_FWD_REF(Args) ...) = delete;
208
209//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
210//! an array of known bound.
211template<class T, class... Args>
212inline BOOST_MOVE_DOC1ST(unspecified,
213 typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
214 make_unique_definit(BOOST_FWD_REF(Args) ...) = delete;
215
216//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
217//! an array of known bound.
218template<class T, class... Args>
219inline BOOST_MOVE_DOC1ST(unspecified,
220 typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
221 make_unique_nothrow(BOOST_FWD_REF(Args) ...) = delete;
222
223//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
224//! an array of known bound.
225template<class T, class... Args>
226inline BOOST_MOVE_DOC1ST(unspecified,
227 typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
228 make_unique_nothrow_definit(BOOST_FWD_REF(Args) ...) = delete;
229
230#endif
231
232} //namespace movelib {
233
234} //namespace boost{
235
236#include <boost/move/detail/config_end.hpp>
237
238#endif //#ifndef BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED