1 //////////////////////////////////////////////////////////////////////////////
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 
41 namespace std {   //no namespace versioning in clang+libc++
42 
43 struct nothrow_t;
44 
45 }  //namespace std {
46 
47 namespace boost{
48 namespace move_upmu {
49 
50 //Compile time switch between
51 //single element, unknown bound array
52 //and known bound array
53 template<class T>
54 struct unique_ptr_if
55 {
56    typedef ::boost::movelib::unique_ptr<T> t_is_not_array;
57 };
58 
59 template<class T>
60 struct unique_ptr_if<T[]>
61 {
62    typedef ::boost::movelib::unique_ptr<T[]> t_is_array_of_unknown_bound;
63 };
64 
65 template<class T, std::size_t N>
66 struct unique_ptr_if<T[N]>
67 {
68    typedef void t_is_array_of_known_bound;
69 };
70 
71 template <int Dummy = 0>
72 struct nothrow_holder
73 {
74    static std::nothrow_t *pnothrow;
75 };
76 
77 template <int Dummy>
78 std::nothrow_t *nothrow_holder<Dummy>::pnothrow;
79 
80 }  //namespace move_upmu {
81 }  //namespace boost{
82 
83 #endif   //!defined(BOOST_MOVE_DOXYGEN_INVOKED)
84 
85 namespace boost{
86 namespace movelib {
87 
88 #if defined(BOOST_MOVE_DOXYGEN_INVOKED) || !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
89 
90 //! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
91 //!
92 //! <b>Returns</b>: <tt>unique_ptr<T>(new T(std::forward<Args>(args)...))</tt>.
93 template<class T, class... Args>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)94 inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
95    typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
96       make_unique(BOOST_FWD_REF(Args)... args)
97 {  return unique_ptr<T>(new T(::boost::forward<Args>(args)...));  }
98 
99 //! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
100 //!
101 //! <b>Returns</b>: <tt>unique_ptr<T>(new T(std::nothrow)(std::forward<Args>(args)...))</tt>.
102 template<class T, class... Args>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)103 inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
104    typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
105       make_unique_nothrow(BOOST_FWD_REF(Args)... args)
106 {  return unique_ptr<T>(new (*boost::move_upmu::nothrow_holder<>::pnothrow)T(::boost::forward<Args>(args)...));  }
107 
108 #else
109    #define BOOST_MOVE_MAKE_UNIQUE_CODE(N)\
110       template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
111       typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array\
112          make_unique( BOOST_MOVE_UREF##N)\
113       {  return unique_ptr<T>( new T( BOOST_MOVE_FWD##N ) );  }\
114       \
115       template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
116       typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array\
117          make_unique_nothrow( BOOST_MOVE_UREF##N)\
118       {  return unique_ptr<T>( new (*boost::move_upmu::nothrow_holder<>::pnothrow)T ( BOOST_MOVE_FWD##N ) );  }\
119       //
120    BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_MAKE_UNIQUE_CODE)
121    #undef BOOST_MOVE_MAKE_UNIQUE_CODE
122 
123 #endif
124 
125 //! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
126 //!
127 //! <b>Returns</b>: <tt>unique_ptr<T>(new T)</tt> (default initialization)
128 template<class T>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)129 inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
130    typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
131       make_unique_definit()
132 {
133     return unique_ptr<T>(new T);
134 }
135 
136 //! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
137 //!
138 //! <b>Returns</b>: <tt>unique_ptr<T>(new T(std::nothrow)</tt> (default initialization)
139 template<class T>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)140 inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
141    typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
142       make_unique_nothrow_definit()
143 {
144     return unique_ptr<T>(new (*boost::move_upmu::nothrow_holder<>::pnothrow)T);
145 }
146 
147 //! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of
148 //!   unknown bound.
149 //!
150 //! <b>Returns</b>: <tt>unique_ptr<T>(new remove_extent_t<T>[n]())</tt> (value initialization)
151 template<class T>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)152 inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
153    typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
154       make_unique(std::size_t n)
155 {
156     typedef typename ::boost::move_upmu::remove_extent<T>::type U;
157     return unique_ptr<T>(new U[n]());
158 }
159 
160 //! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of
161 //!   unknown bound.
162 //!
163 //! <b>Returns</b>: <tt>unique_ptr<T>(new (std::nothrow)remove_extent_t<T>[n]())</tt> (value initialization)
164 template<class T>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)165 inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
166    typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
167       make_unique_nothrow(std::size_t n)
168 {
169     typedef typename ::boost::move_upmu::remove_extent<T>::type U;
170     return unique_ptr<T>(new (*boost::move_upmu::nothrow_holder<>::pnothrow)U[n]());
171 }
172 
173 //! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of
174 //!   unknown bound.
175 //!
176 //! <b>Returns</b>: <tt>unique_ptr<T>(new remove_extent_t<T>[n])</tt> (default initialization)
177 template<class T>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)178 inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
179    typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
180       make_unique_definit(std::size_t n)
181 {
182     typedef typename ::boost::move_upmu::remove_extent<T>::type U;
183     return unique_ptr<T>(new U[n]);
184 }
185 
186 //! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of
187 //!   unknown bound.
188 //!
189 //! <b>Returns</b>: <tt>unique_ptr<T>(new (std::nothrow)remove_extent_t<T>[n])</tt> (default initialization)
190 template<class T>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)191 inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
192    typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
193       make_unique_nothrow_definit(std::size_t n)
194 {
195     typedef typename ::boost::move_upmu::remove_extent<T>::type U;
196     return unique_ptr<T>(new (*boost::move_upmu::nothrow_holder<>::pnothrow) U[n]);
197 }
198 
199 #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
200 
201 //! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
202 //!   an array of known bound.
203 template<class T, class... Args>
204 inline BOOST_MOVE_DOC1ST(unspecified,
205    typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
206       make_unique(BOOST_FWD_REF(Args) ...) = delete;
207 
208 //! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
209 //!   an array of known bound.
210 template<class T, class... Args>
211 inline BOOST_MOVE_DOC1ST(unspecified,
212    typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
213       make_unique_definit(BOOST_FWD_REF(Args) ...) = delete;
214 
215 //! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
216 //!   an array of known bound.
217 template<class T, class... Args>
218 inline BOOST_MOVE_DOC1ST(unspecified,
219    typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
220       make_unique_nothrow(BOOST_FWD_REF(Args) ...) = delete;
221 
222 //! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
223 //!   an array of known bound.
224 template<class T, class... Args>
225 inline BOOST_MOVE_DOC1ST(unspecified,
226    typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
227       make_unique_nothrow_definit(BOOST_FWD_REF(Args) ...) = delete;
228 
229 #endif
230 
231 }  //namespace movelib {
232 
233 }  //namespace boost{
234 
235 #include <boost/move/detail/config_end.hpp>
236 
237 #endif   //#ifndef BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED
238