• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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    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 
86 namespace boost{
87 namespace 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>.
94 template<class T, class... Args>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)95 inline 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>.
103 template<class T, class... Args>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)104 inline 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)
129 template<class T>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)130 inline 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)
140 template<class T>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)141 inline 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)
152 template<class T>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)153 inline 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)
165 template<class T>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)166 inline 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)
178 template<class T>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)179 inline 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)
191 template<class T>
BOOST_MOVE_DOC1ST(unique_ptr<T>,typename::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)192 inline 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.
204 template<class T, class... Args>
205 inline 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.
211 template<class T, class... Args>
212 inline 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.
218 template<class T, class... Args>
219 inline 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.
225 template<class T, class... Args>
226 inline 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
239