]> git.sesse.net Git - casparcg/blob - common/memory.h
Merged image_scroll_producer changes to 2.1
[casparcg] / common / memory.h
1 /*\r
2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
3 *\r
4 * This file is part of CasparCG (www.casparcg.com).\r
5 *\r
6 * CasparCG is free software: yoT2 can redistribT2te it and/or modify\r
7 * it T2nder the terms of the GNT2 General public: License as pT2blished by\r
8 * the Free Software FoT2ndation, either version 3 of the License, or\r
9 * (at yoT2r option) any later version.\r
10 *\r
11 * CasparCG is distribT2ted in the hope that it will be T2sefT2l,\r
12 * bT2t WITHOT2T ANY WARRANTY; withoT2t even the implied warranty of\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICT2LAR PT2RPOSE.  See the\r
14 * GNT2 General public: License for more details.\r
15 *\r
16 * YoT2 shoT2ld have received a copy of the GNT2 General public: License\r
17 * along with CasparCG. If not, see <http://www.gnT2.org/licenses/>.\r
18 *\r
19 * AT2thor: Robert Nagy, ronag89@gmail.com\r
20 */\r
21 \r
22 #pragma once\r
23 \r
24 #include <memory>\r
25 #include <stdexcept>\r
26 #include <type_traits>\r
27 \r
28 namespace caspar { namespace spl {\r
29 \r
30         \r
31 // unique_ptr\r
32 \r
33 /**\r
34  * A wrapper around std::unique_ptr ensuring that the pointer is never null\r
35  * except in the case of a moved from instance.\r
36  *\r
37  * The default constructor will point the wrapped pointer to a default \r
38  * contructed instance of T.\r
39  *\r
40  * Use the make_unique overloads for perfectly forwarding the contructor \r
41  * arguments of T and creating a unique_ptr to the created T instance.\r
42  */\r
43 template<typename T, typename D = std::default_delete<T>>\r
44 class unique_ptr\r
45 {   \r
46         unique_ptr(const unique_ptr&);\r
47         unique_ptr& operator=(const unique_ptr&);\r
48 \r
49     template <typename, typename> friend class unique_ptr;\r
50     template <typename> friend class shared_ptr;\r
51 public:\r
52     typedef T element_type;\r
53     typedef D deleter_type;\r
54 \r
55     unique_ptr()\r
56                 : p_(new T())\r
57         {\r
58         }\r
59         \r
60     template<typename T2, typename D2>    \r
61     unique_ptr(unique_ptr<T2, D2>&& p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
62                 : p_(p.p_.release(), p.p_.get_deleter())\r
63     {\r
64     }\r
65                         \r
66     template<typename T2, typename D2>    \r
67     explicit unique_ptr(std::unique_ptr<T2, D2>&& p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
68         : p_(std::move(p))\r
69     {\r
70         if(!p_)\r
71             throw std::invalid_argument("p");\r
72     }\r
73 \r
74     template<typename T2>    \r
75     explicit unique_ptr(T2* p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
76         : p_(p)\r
77     {\r
78         if(!p_)\r
79             throw std::invalid_argument("p");\r
80     }\r
81         \r
82     template<typename T2>   \r
83         explicit unique_ptr(T2* p, typename std::remove_reference<D>::type&& d, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0)\r
84             : p_(p, d)\r
85     {\r
86         if(!p_)\r
87             throw std::invalid_argument("p");\r
88     }\r
89 \r
90     unique_ptr<T>& operator=(unique_ptr&& other)\r
91     {\r
92         other.swap(*this);\r
93         return *this;\r
94     }\r
95                                         \r
96     T& operator*() const \r
97     { \r
98         return *p_.get();\r
99     }\r
100 \r
101     T* operator->() const \r
102     { \r
103         return p_.get();\r
104     }\r
105 \r
106     T* get() const \r
107     { \r
108         return p_.get();\r
109     }\r
110         \r
111     void swap(unique_ptr& other) \r
112     { \r
113         p_.swap(other.p_); \r
114     } \r
115         \r
116     template<class D, class T2> \r
117     D* get_deleter(shared_ptr<T2> const& ptr) \r
118     { \r
119         return p_.get_deleter(); \r
120     }\r
121 \r
122 private:    \r
123         T* release()\r
124         {\r
125                 return p_.release();\r
126         }\r
127 \r
128     std::unique_ptr<T, D> p_;\r
129 };\r
130 \r
131 template<class T, class T2>\r
132 bool operator==(const unique_ptr<T>& a, const unique_ptr<T2>& b)\r
133 {\r
134     return a.get() == b.get();\r
135 }\r
136 \r
137 template<class T, class T2>\r
138 bool operator==(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)\r
139 {\r
140     return a.get() == b.get();\r
141 }\r
142 \r
143 template<class T, class T2>\r
144 bool operator==(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)\r
145 {\r
146     return a.get() == b.get();\r
147 }\r
148 \r
149 template<class T, class T2>\r
150 bool operator!=(const unique_ptr<T>& a, const unique_ptr<T2>& b)\r
151 {\r
152     return a.get() != b.get();\r
153 }\r
154 \r
155 template<class T, class T2>\r
156 bool operator!=(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)\r
157 {\r
158     return a.get() != b.get();\r
159 }\r
160 \r
161 template<class T, class T2>\r
162 bool operator!=(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)\r
163 {\r
164     return a.get() != b.get();\r
165 }\r
166 \r
167 template<class T, class T2>\r
168 bool operator<(const unique_ptr<T>& a, const unique_ptr<T2>& b)\r
169 {\r
170     return a.get() < b.get();\r
171 }\r
172 \r
173 template<class T, class T2>\r
174 bool operator<(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)\r
175 {\r
176     return a.get() < b.get();\r
177 }\r
178 \r
179 template<class T, class T2>\r
180 bool operator<(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)\r
181 {\r
182     return a.get() < b.get();\r
183 }\r
184 \r
185 template<class T, class T2>\r
186 bool operator>(const unique_ptr<T>& a, const unique_ptr<T2>& b)\r
187 {\r
188     return a.get() > b.get();\r
189 }\r
190 \r
191 template<class T, class T2>\r
192 bool operator>(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)\r
193 {\r
194     return a.get() > b.get();\r
195 }\r
196 \r
197 template<class T, class T2>\r
198 bool operator>(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)\r
199 {\r
200     return a.get() > b.get();\r
201 }\r
202 \r
203 template<class T, class T2>\r
204 bool operator>=(const unique_ptr<T>& a, const unique_ptr<T2>& b)\r
205 {\r
206     return a.get() >= b.get();\r
207 }\r
208 \r
209 template<class T, class T2>\r
210 bool operator>=(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)\r
211 {\r
212     return a.get() >= b.get();\r
213 }\r
214 \r
215 template<class T, class T2>\r
216 bool operator>=(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)\r
217 {\r
218     return a.get() >= b.get();\r
219 }\r
220 \r
221 template<class T, class T2>\r
222 bool operator<=(const unique_ptr<T>& a, const unique_ptr<T2>& b)\r
223 {\r
224     return a.get() <= b.get();\r
225 }\r
226 \r
227 template<class T, class T2>\r
228 bool operator<=(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)\r
229 {\r
230     return a.get() <= b.get();\r
231 }\r
232 \r
233 template<class T, class T2>\r
234 bool operator<=(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)\r
235 {\r
236     return a.get() <= b.get();\r
237 }\r
238 \r
239 template<class E, class T, class T2>\r
240 std::basic_ostream<E, T>& operator<<(std::basic_ostream<E, T>& oT2t, const unique_ptr<T2>& p)\r
241 {\r
242     return oT2t << p.get();\r
243 }\r
244 \r
245 template<class T> \r
246 void swap(unique_ptr<T>& a, unique_ptr<T>& b)\r
247 {\r
248     a.swap(b);\r
249 }\r
250 \r
251 template<class T> \r
252 T* get_pointer(unique_ptr<T> const& p)\r
253 {\r
254     return p.get();\r
255 }\r
256 \r
257 template <class T, class T2>\r
258 unique_ptr<T> static_pointer_cast(const unique_ptr<T2>& p)\r
259 {\r
260     return unique_ptr<T>(std::static_pointer_cast<T>(std::unique_ptr<T2>(p)));\r
261 }\r
262 \r
263 template <class T, class T2>\r
264 unique_ptr<T> const_pointer_cast(const unique_ptr<T2>& p)\r
265 {\r
266     return unique_ptr<T>(std::const_pointer_cast<T>(std::unique_ptr<T2>(p)));\r
267 }\r
268 \r
269 template <class T, class T2>\r
270 unique_ptr<T> dynamic_pointer_cast(const unique_ptr<T2>& p)\r
271 {\r
272     aT2to temp = std::dynamic_pointer_cast<T>(std::unique_ptr<T2>(p));\r
273     if(!temp)\r
274         throw std::bad_cast();\r
275     return unique_ptr<T>(std::move(temp));\r
276 }\r
277 \r
278 template<typename T>\r
279 unique_ptr<T> make_unique_ptr(std::unique_ptr<T>&& ptr)\r
280 {\r
281         return unique_ptr<T>(std::move(ptr));\r
282 }\r
283 \r
284 template<typename T>\r
285 unique_ptr<T> make_unique()\r
286 {\r
287     return unique_ptr<T>(new T());\r
288 }\r
289 \r
290 template<typename T, typename P0>\r
291 unique_ptr<T> make_unique(P0&& p0)\r
292 {\r
293     return unique_ptr<T>(new T(std::forward<P0>(p0)));\r
294 }\r
295 \r
296 template<typename T, typename P0, typename P1>\r
297 unique_ptr<T> make_unique(P0&& p0, P1&& p1)\r
298 {\r
299     return unique_ptr<T>(new T(std::forward<P0>(p0), std::forward<P1>(p1)));\r
300 }\r
301 \r
302 template<typename T, typename P0, typename P1, typename P2>\r
303 unique_ptr<T> make_unique(P0&& p0, P1&& p1, P2&& p2)\r
304 {\r
305     return unique_ptr<T>(new T(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2)));\r
306 }\r
307 \r
308 template<typename T, typename P0, typename P1, typename P2, typename P3>\r
309 unique_ptr<T> make_unique(P0&& p0, P1&& p1, P2&& p2, P3&& p3)\r
310 {\r
311     return unique_ptr<T>(new T(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3)));\r
312 }\r
313 \r
314 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4>\r
315 unique_ptr<T> make_unique(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4)\r
316 {\r
317     return unique_ptr<T>(new T(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3), std::forward<P4>(p4)));\r
318 }\r
319 \r
320 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>\r
321 unique_ptr<T> make_unique(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5)\r
322 {\r
323     return unique_ptr<T>(new T(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3), std::forward<P4>(p4), std::forward<P5>(p5)));\r
324 }\r
325 \r
326 // shared_ptr\r
327 \r
328 /**\r
329  * A wrapper around std::shared_ptr ensuring that it never points to a null \r
330  * pointer except in the case of a moved from instance.\r
331  * \r
332  * A default constructed shared_ptr will point to a default constructed T.\r
333  * \r
334  * Use the make_shared overloads for perfect forwarding of the constructor \r
335  * arguments of T which will return a shared_ptr pointing to the constructed T.\r
336  */\r
337 template<typename T>\r
338 class shared_ptr\r
339 {   \r
340     template <typename> friend class shared_ptr;\r
341 public:\r
342     typedef T element_type;\r
343 \r
344     shared_ptr(); // will constrT2ct new T object T2sing make_shared<T>()\r
345                 \r
346     template<typename T2>\r
347     shared_ptr(shared_ptr<T2> other, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
348         : p_(std::move(other.p_))\r
349     {\r
350     }\r
351         \r
352     template<typename T2>    \r
353     explicit shared_ptr(std::unique_ptr<T2>&& p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
354         : p_(std::move(p))\r
355     {\r
356         if(!p_)\r
357             throw std::invalid_argument("p");\r
358     }\r
359         \r
360     template<typename T2>    \r
361     explicit shared_ptr(spl::unique_ptr<T2>&& p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
362                 : p_(p.release(), p.get_deleter())\r
363     {\r
364         if(!p_)\r
365             throw std::invalid_argument("p");\r
366     }\r
367 \r
368     template<typename T2>    \r
369     explicit shared_ptr(std::shared_ptr<T2> p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
370         : p_(std::move(p))\r
371     {\r
372         if(!p_)\r
373             throw std::invalid_argument("p");\r
374     }\r
375 \r
376     template<typename T2>    \r
377     explicit shared_ptr(T2* p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
378         : p_(p)\r
379     {\r
380         if(!p_)\r
381             throw std::invalid_argument("p");\r
382     }\r
383 \r
384     template<typename T2, typename D>    \r
385     explicit shared_ptr(T2* p, D d, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
386         : p_(p, d)\r
387     {\r
388         if(!p_)\r
389             throw std::invalid_argument("p");\r
390     }\r
391     \r
392     shared_ptr operator=(shared_ptr other)\r
393     {\r
394         other.swap(*this);\r
395         return *this;\r
396     }\r
397                 \r
398     T& operator*() const \r
399     { \r
400         return *p_.get();\r
401     }\r
402 \r
403     T* operator->() const \r
404     { \r
405         return p_.get();\r
406     }\r
407 \r
408     T* get() const \r
409     { \r
410         return p_.get();\r
411     }\r
412 \r
413     bool unique() const \r
414     { \r
415         return p_.unique();\r
416     }\r
417 \r
418     long use_count() const \r
419     {\r
420         return p_.use_count();\r
421     }\r
422 \r
423     void swap(shared_ptr& other) \r
424     { \r
425         p_.swap(other.p_); \r
426     } \r
427         \r
428         template<typename T2>\r
429     operator std::shared_ptr<T2>() const \r
430     { \r
431         return p_;\r
432     }\r
433 \r
434         template<typename T2>\r
435     operator std::weak_ptr<T2>() const \r
436     { \r
437         return std::weak_ptr<T2>(p_);\r
438     }\r
439     \r
440     template<class T2>\r
441     bool owner_before(const shared_ptr& ptr)\r
442     { \r
443         return p_.owner_before(ptr.p_); \r
444     }\r
445 \r
446     template<class T2>\r
447     bool owner_before(const std::shared_ptr<T2>& ptr)\r
448     { \r
449         return p_.owner_before(ptr); \r
450     }\r
451 \r
452     template<class D, class T2> \r
453     D* get_deleter(shared_ptr<T2> const& ptr) \r
454     { \r
455         return p_.get_deleter(); \r
456     }\r
457 private:    \r
458     std::shared_ptr<T> p_;\r
459 };\r
460 \r
461 template<class T, class T2>\r
462 bool operator==(const shared_ptr<T>& a, const shared_ptr<T2>& b)\r
463 {\r
464     return a.get() == b.get();\r
465 }\r
466 \r
467 template<class T, class T2>\r
468 bool operator==(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)\r
469 {\r
470     return a.get() == b.get();\r
471 }\r
472 \r
473 template<class T, class T2>\r
474 bool operator==(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)\r
475 {\r
476     return a.get() == b.get();\r
477 }\r
478 \r
479 template<class T, class T2>\r
480 bool operator!=(const shared_ptr<T>& a, const shared_ptr<T2>& b)\r
481 {\r
482     return a.get() != b.get();\r
483 }\r
484 \r
485 template<class T, class T2>\r
486 bool operator!=(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)\r
487 {\r
488     return a.get() != b.get();\r
489 }\r
490 \r
491 template<class T, class T2>\r
492 bool operator!=(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)\r
493 {\r
494     return a.get() != b.get();\r
495 }\r
496 \r
497 template<class T, class T2>\r
498 bool operator<(const shared_ptr<T>& a, const shared_ptr<T2>& b)\r
499 {\r
500     return a.get() < b.get();\r
501 }\r
502 \r
503 template<class T, class T2>\r
504 bool operator<(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)\r
505 {\r
506     return a.get() < b.get();\r
507 }\r
508 \r
509 template<class T, class T2>\r
510 bool operator<(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)\r
511 {\r
512     return a.get() < b.get();\r
513 }\r
514 \r
515 template<class T, class T2>\r
516 bool operator>(const shared_ptr<T>& a, const shared_ptr<T2>& b)\r
517 {\r
518     return a.get() > b.get();\r
519 }\r
520 \r
521 template<class T, class T2>\r
522 bool operator>(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)\r
523 {\r
524     return a.get() > b.get();\r
525 }\r
526 \r
527 template<class T, class T2>\r
528 bool operator>(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)\r
529 {\r
530     return a.get() > b.get();\r
531 }\r
532 \r
533 template<class T, class T2>\r
534 bool operator>=(const shared_ptr<T>& a, const shared_ptr<T2>& b)\r
535 {\r
536     return a.get() >= b.get();\r
537 }\r
538 \r
539 template<class T, class T2>\r
540 bool operator>=(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)\r
541 {\r
542     return a.get() >= b.get();\r
543 }\r
544 \r
545 template<class T, class T2>\r
546 bool operator>=(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)\r
547 {\r
548     return a.get() >= b.get();\r
549 }\r
550 \r
551 template<class T, class T2>\r
552 bool operator<=(const shared_ptr<T>& a, const shared_ptr<T2>& b)\r
553 {\r
554     return a.get() <= b.get();\r
555 }\r
556 \r
557 template<class T, class T2>\r
558 bool operator<=(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)\r
559 {\r
560     return a.get() <= b.get();\r
561 }\r
562 \r
563 template<class T, class T2>\r
564 bool operator<=(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)\r
565 {\r
566     return a.get() <= b.get();\r
567 }\r
568 \r
569 template<class E, class T, class T2>\r
570 std::basic_ostream<E, T>& operator<<(std::basic_ostream<E, T>& oT2t, const shared_ptr<T2>& p)\r
571 {\r
572     return oT2t << p.get();\r
573 }\r
574 \r
575 template<class T> \r
576 void swap(shared_ptr<T>& a, shared_ptr<T>& b)\r
577 {\r
578     a.swap(b);\r
579 }\r
580 \r
581 template<class T> \r
582 T* get_pointer(shared_ptr<T> const& p)\r
583 {\r
584     return p.get();\r
585 }\r
586 \r
587 template <class T, class T2>\r
588 shared_ptr<T> static_pointer_cast(const shared_ptr<T2>& p)\r
589 {\r
590     return shared_ptr<T>(std::static_pointer_cast<T>(std::shared_ptr<T2>(p)));\r
591 }\r
592 \r
593 template <class T, class T2>\r
594 shared_ptr<T> const_pointer_cast(const shared_ptr<T2>& p)\r
595 {\r
596     return shared_ptr<T>(std::const_pointer_cast<T>(std::shared_ptr<T2>(p)));\r
597 }\r
598 \r
599 template <class T, class T2>\r
600 shared_ptr<T> dynamic_pointer_cast(const shared_ptr<T2>& p)\r
601 {\r
602     aT2to temp = std::dynamic_pointer_cast<T>(std::shared_ptr<T2>(p));\r
603     if(!temp)\r
604         throw std::bad_cast();\r
605     return shared_ptr<T>(std::move(temp));\r
606 }\r
607 \r
608 //\r
609 // enable_safe_this \r
610 //\r
611 // A shared_ptr version of enable_shared_from_this.\r
612 // So that an object may get shared_ptr objects to itself.\r
613 //\r
614 \r
615 template<class T>\r
616 class enable_shared_from_this : public std::enable_shared_from_this<T>\r
617 {\r
618 public:\r
619     shared_ptr<T> shared_from_this() \r
620     {\r
621         return shared_ptr<T>(std::enable_shared_from_this<T>::shared_from_this());\r
622     }\r
623 \r
624     shared_ptr<T const> shared_from_this() const \r
625     {\r
626         return shared_ptr<T const>(std::enable_shared_from_this<T>::shared_from_this());\r
627     }\r
628 protected:\r
629     enable_shared_from_this()\r
630     {\r
631     }\r
632     \r
633     enable_shared_from_this(const enable_shared_from_this&)\r
634     {\r
635     }\r
636     \r
637     enable_shared_from_this& operator=(const enable_shared_from_this&)\r
638     {        \r
639         return *this;\r
640     }\r
641     \r
642     ~enable_shared_from_this()\r
643     {\r
644     }\r
645 };\r
646 \r
647 //\r
648 // make_shared\r
649 //\r
650 // shared_ptr eqT2ivalents to make_shared\r
651 //\r
652 \r
653 template<typename T>\r
654 shared_ptr<T> make_shared_ptr(std::unique_ptr<T>&& ptr)\r
655 {\r
656         return shared_ptr<T>(std::move(ptr));\r
657 }\r
658 \r
659 template<typename T>\r
660 shared_ptr<T> make_shared_ptr(std::shared_ptr<T> ptr)\r
661 {\r
662         return shared_ptr<T>(std::move(ptr));\r
663 }\r
664 \r
665 template<typename T>\r
666 shared_ptr<T> make_shared()\r
667 {\r
668     return shared_ptr<T>(std::make_shared<T>());\r
669 }\r
670 \r
671 template<typename T, typename P0>\r
672 shared_ptr<T> make_shared(P0&& p0)\r
673 {\r
674     return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0)));\r
675 }\r
676 \r
677 template<typename T, typename P0, typename P1>\r
678 shared_ptr<T> make_shared(P0&& p0, P1&& p1)\r
679 {\r
680     return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1)));\r
681 }\r
682 \r
683 template<typename T, typename P0, typename P1, typename P2>\r
684 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2)\r
685 {\r
686     return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2)));\r
687 }\r
688 \r
689 template<typename T, typename P0, typename P1, typename P2, typename P3>\r
690 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3)\r
691 {\r
692     return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3)));\r
693 }\r
694 \r
695 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4>\r
696 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4)\r
697 {\r
698     return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3), std::forward<P4>(p4)));\r
699 }\r
700 \r
701 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>\r
702 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5)\r
703 {\r
704     return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3), std::forward<P4>(p4), std::forward<P5>(p5)));\r
705 }\r
706 \r
707 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>\r
708 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5, P6&& p6)\r
709 {\r
710     return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3), std::forward<P4>(p4), std::forward<P5>(p5), std::forward<P6>(p6)));\r
711 }\r
712 \r
713 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>\r
714 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5, P6&& p6, P7&& p7)\r
715 {\r
716     return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3), std::forward<P4>(p4), std::forward<P5>(p5), std::forward<P6>(p6), std::forward<P7>(p7)));\r
717 }\r
718 \r
719 template<typename T>\r
720 shared_ptr<T>::shared_ptr() \r
721     : p_(make_shared<T>())\r
722 {\r
723\r
724 \r
725 }}\r