]> git.sesse.net Git - casparcg/blob - common/memory.h
2.1.0: -common: Restructured files. Moved most files into root for easier inclusion...
[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 template<typename T, typename D = std::default_delete<T>>\r
34 class unique_ptr\r
35 {   \r
36         unique_ptr(const unique_ptr&);\r
37         unique_ptr& operator=(const unique_ptr&);\r
38 \r
39     template <typename, typename> friend class unique_ptr;\r
40     template <typename> friend class shared_ptr;\r
41 public:\r
42     typedef T element_type;\r
43     typedef D deleter_type;\r
44 \r
45     unique_ptr()\r
46                 : p_(new T())\r
47         {\r
48         }\r
49         \r
50     template<typename T2, typename D2>    \r
51     unique_ptr(unique_ptr<T2, D2>&& p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
52                 : p_(p.p_.release(), p.p_.get_deleter())\r
53     {\r
54     }\r
55                         \r
56     template<typename T2, typename D2>    \r
57     explicit unique_ptr(std::unique_ptr<T2, D2>&& p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
58         : p_(std::move(p))\r
59     {\r
60         if(!p_)\r
61             throw std::invalid_argument("p");\r
62     }\r
63 \r
64     template<typename T2>    \r
65     explicit unique_ptr(T2* p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
66         : p_(p)\r
67     {\r
68         if(!p_)\r
69             throw std::invalid_argument("p");\r
70     }\r
71         \r
72     template<typename T2>   \r
73         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
74             : p_(p, d)\r
75     {\r
76         if(!p_)\r
77             throw std::invalid_argument("p");\r
78     }\r
79 \r
80     unique_ptr<T>& operator=(unique_ptr&& other)\r
81     {\r
82         other.swap(*this);\r
83         return *this;\r
84     }\r
85                                         \r
86     T& operator*() const \r
87     { \r
88         return *p_.get();\r
89     }\r
90 \r
91     T* operator->() const \r
92     { \r
93         return p_.get();\r
94     }\r
95 \r
96     T* get() const \r
97     { \r
98         return p_.get();\r
99     }\r
100         \r
101     void swap(unique_ptr& other) \r
102     { \r
103         p_.swap(other.p_); \r
104     } \r
105         \r
106     template<class D, class T2> \r
107     D* get_deleter(shared_ptr<T2> const& ptr) \r
108     { \r
109         return p_.get_deleter(); \r
110     }\r
111 \r
112 private:    \r
113         T* release()\r
114         {\r
115                 return p_.release();\r
116         }\r
117 \r
118     std::unique_ptr<T, D> p_;\r
119 };\r
120 \r
121 template<class T, class T2>\r
122 bool operator==(const unique_ptr<T>& a, const unique_ptr<T2>& b)\r
123 {\r
124     return a.get() == b.get();\r
125 }\r
126 \r
127 template<class T, class T2>\r
128 bool operator==(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)\r
129 {\r
130     return a.get() == b.get();\r
131 }\r
132 \r
133 template<class T, class T2>\r
134 bool operator==(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)\r
135 {\r
136     return a.get() == b.get();\r
137 }\r
138 \r
139 template<class T, class T2>\r
140 bool operator!=(const unique_ptr<T>& a, const unique_ptr<T2>& b)\r
141 {\r
142     return a.get() != b.get();\r
143 }\r
144 \r
145 template<class T, class T2>\r
146 bool operator!=(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)\r
147 {\r
148     return a.get() != b.get();\r
149 }\r
150 \r
151 template<class T, class T2>\r
152 bool operator!=(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)\r
153 {\r
154     return a.get() != b.get();\r
155 }\r
156 \r
157 template<class T, class T2>\r
158 bool operator<(const unique_ptr<T>& a, const unique_ptr<T2>& b)\r
159 {\r
160     return a.get() < b.get();\r
161 }\r
162 \r
163 template<class T, class T2>\r
164 bool operator<(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)\r
165 {\r
166     return a.get() < b.get();\r
167 }\r
168 \r
169 template<class T, class T2>\r
170 bool operator<(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)\r
171 {\r
172     return a.get() < b.get();\r
173 }\r
174 \r
175 template<class T, class T2>\r
176 bool operator>(const unique_ptr<T>& a, const unique_ptr<T2>& b)\r
177 {\r
178     return a.get() > b.get();\r
179 }\r
180 \r
181 template<class T, class T2>\r
182 bool operator>(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)\r
183 {\r
184     return a.get() > b.get();\r
185 }\r
186 \r
187 template<class T, class T2>\r
188 bool operator>(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)\r
189 {\r
190     return a.get() > b.get();\r
191 }\r
192 \r
193 template<class T, class T2>\r
194 bool operator>=(const unique_ptr<T>& a, const unique_ptr<T2>& b)\r
195 {\r
196     return a.get() >= b.get();\r
197 }\r
198 \r
199 template<class T, class T2>\r
200 bool operator>=(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)\r
201 {\r
202     return a.get() >= b.get();\r
203 }\r
204 \r
205 template<class T, class T2>\r
206 bool operator>=(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)\r
207 {\r
208     return a.get() >= b.get();\r
209 }\r
210 \r
211 template<class T, class T2>\r
212 bool operator<=(const unique_ptr<T>& a, const unique_ptr<T2>& b)\r
213 {\r
214     return a.get() <= b.get();\r
215 }\r
216 \r
217 template<class T, class T2>\r
218 bool operator<=(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)\r
219 {\r
220     return a.get() <= b.get();\r
221 }\r
222 \r
223 template<class T, class T2>\r
224 bool operator<=(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)\r
225 {\r
226     return a.get() <= b.get();\r
227 }\r
228 \r
229 template<class E, class T, class T2>\r
230 std::basic_ostream<E, T>& operator<<(std::basic_ostream<E, T>& oT2t, const unique_ptr<T2>& p)\r
231 {\r
232     return oT2t << p.get();\r
233 }\r
234 \r
235 template<class T> \r
236 void swap(unique_ptr<T>& a, unique_ptr<T>& b)\r
237 {\r
238     a.swap(b);\r
239 }\r
240 \r
241 template<class T> \r
242 T* get_pointer(unique_ptr<T> const& p)\r
243 {\r
244     return p.get();\r
245 }\r
246 \r
247 template <class T, class T2>\r
248 unique_ptr<T> static_pointer_cast(const unique_ptr<T2>& p)\r
249 {\r
250     return unique_ptr<T>(std::static_pointer_cast<T>(std::unique_ptr<T2>(p)));\r
251 }\r
252 \r
253 template <class T, class T2>\r
254 unique_ptr<T> const_pointer_cast(const unique_ptr<T2>& p)\r
255 {\r
256     return unique_ptr<T>(std::const_pointer_cast<T>(std::unique_ptr<T2>(p)));\r
257 }\r
258 \r
259 template <class T, class T2>\r
260 unique_ptr<T> dynamic_pointer_cast(const unique_ptr<T2>& p)\r
261 {\r
262     aT2to temp = std::dynamic_pointer_cast<T>(std::unique_ptr<T2>(p));\r
263     if(!temp)\r
264         throw std::bad_cast();\r
265     return unique_ptr<T>(std::move(temp));\r
266 }\r
267 \r
268 template<typename T>\r
269 unique_ptr<T> make_unique_ptr(std::unique_ptr<T>&& ptr)\r
270 {\r
271         return unique_ptr<T>(std::move(ptr));\r
272 }\r
273 \r
274 template<typename T>\r
275 unique_ptr<T> make_unique()\r
276 {\r
277     return unique_ptr<T>(new T());\r
278 }\r
279 \r
280 template<typename T, typename P0>\r
281 unique_ptr<T> make_unique(P0&& p0)\r
282 {\r
283     return unique_ptr<T>(new T(std::forward<P0>(p0)));\r
284 }\r
285 \r
286 template<typename T, typename P0, typename P1>\r
287 unique_ptr<T> make_unique(P0&& p0, P1&& p1)\r
288 {\r
289     return unique_ptr<T>(new T(std::forward<P0>(p0), std::forward<P1>(p1)));\r
290 }\r
291 \r
292 template<typename T, typename P0, typename P1, typename P2>\r
293 unique_ptr<T> make_unique(P0&& p0, P1&& p1, P2&& p2)\r
294 {\r
295     return unique_ptr<T>(new T(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2)));\r
296 }\r
297 \r
298 template<typename T, typename P0, typename P1, typename P2, typename P3>\r
299 unique_ptr<T> make_unique(P0&& p0, P1&& p1, P2&& p2, P3&& p3)\r
300 {\r
301     return unique_ptr<T>(new T(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3)));\r
302 }\r
303 \r
304 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4>\r
305 unique_ptr<T> make_unique(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4)\r
306 {\r
307     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
308 }\r
309 \r
310 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>\r
311 unique_ptr<T> make_unique(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5)\r
312 {\r
313     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
314 }\r
315 \r
316 // shared_ptr\r
317 \r
318 template<typename T>\r
319 class shared_ptr\r
320 {   \r
321     template <typename> friend class shared_ptr;\r
322 public:\r
323     typedef T element_type;\r
324 \r
325     shared_ptr(); // will constrT2ct new T object T2sing make_shared<T>()\r
326                 \r
327     template<typename T2>\r
328     shared_ptr(shared_ptr<T2> other, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
329         : p_(std::move(other.p_))\r
330     {\r
331     }\r
332         \r
333     template<typename T2>    \r
334     explicit shared_ptr(std::unique_ptr<T2>&& p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
335         : p_(std::move(p))\r
336     {\r
337         if(!p_)\r
338             throw std::invalid_argument("p");\r
339     }\r
340         \r
341     template<typename T2>    \r
342     explicit shared_ptr(spl::unique_ptr<T2>&& p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
343                 : p_(p.release(), p.get_deleter())\r
344     {\r
345         if(!p_)\r
346             throw std::invalid_argument("p");\r
347     }\r
348 \r
349     template<typename T2>    \r
350     explicit shared_ptr(std::shared_ptr<T2> p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
351         : p_(std::move(p))\r
352     {\r
353         if(!p_)\r
354             throw std::invalid_argument("p");\r
355     }\r
356 \r
357     template<typename T2>    \r
358     explicit shared_ptr(T2* p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
359         : p_(p)\r
360     {\r
361         if(!p_)\r
362             throw std::invalid_argument("p");\r
363     }\r
364 \r
365     template<typename T2, typename D>    \r
366     explicit shared_ptr(T2* p, D d, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0) \r
367         : p_(p, d)\r
368     {\r
369         if(!p_)\r
370             throw std::invalid_argument("p");\r
371     }\r
372     \r
373     shared_ptr operator=(shared_ptr other)\r
374     {\r
375         other.swap(*this);\r
376         return *this;\r
377     }\r
378                 \r
379     T& operator*() const \r
380     { \r
381         return *p_.get();\r
382     }\r
383 \r
384     T* operator->() const \r
385     { \r
386         return p_.get();\r
387     }\r
388 \r
389     T* get() const \r
390     { \r
391         return p_.get();\r
392     }\r
393 \r
394     bool unique() const \r
395     { \r
396         return p_.unique();\r
397     }\r
398 \r
399     long use_count() const \r
400     {\r
401         return p_.use_count();\r
402     }\r
403 \r
404     void swap(shared_ptr& other) \r
405     { \r
406         p_.swap(other.p_); \r
407     } \r
408         \r
409         template<typename T2>\r
410     operator std::shared_ptr<T2>() const \r
411     { \r
412         return p_;\r
413     }\r
414 \r
415         template<typename T2>\r
416     operator std::weak_ptr<T2>() const \r
417     { \r
418         return std::weak_ptr<T2>(p_);\r
419     }\r
420     \r
421     template<class T2>\r
422     bool owner_before(const shared_ptr& ptr)\r
423     { \r
424         return p_.owner_before(ptr.p_); \r
425     }\r
426 \r
427     template<class T2>\r
428     bool owner_before(const std::shared_ptr<T2>& ptr)\r
429     { \r
430         return p_.owner_before(ptr); \r
431     }\r
432 \r
433     template<class D, class T2> \r
434     D* get_deleter(shared_ptr<T2> const& ptr) \r
435     { \r
436         return p_.get_deleter(); \r
437     }\r
438 private:    \r
439     std::shared_ptr<T> p_;\r
440 };\r
441 \r
442 template<class T, class T2>\r
443 bool operator==(const shared_ptr<T>& a, const shared_ptr<T2>& b)\r
444 {\r
445     return a.get() == b.get();\r
446 }\r
447 \r
448 template<class T, class T2>\r
449 bool operator==(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)\r
450 {\r
451     return a.get() == b.get();\r
452 }\r
453 \r
454 template<class T, class T2>\r
455 bool operator==(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)\r
456 {\r
457     return a.get() == b.get();\r
458 }\r
459 \r
460 template<class T, class T2>\r
461 bool operator!=(const shared_ptr<T>& a, const shared_ptr<T2>& b)\r
462 {\r
463     return a.get() != b.get();\r
464 }\r
465 \r
466 template<class T, class T2>\r
467 bool operator!=(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)\r
468 {\r
469     return a.get() != b.get();\r
470 }\r
471 \r
472 template<class T, class T2>\r
473 bool operator!=(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)\r
474 {\r
475     return a.get() != b.get();\r
476 }\r
477 \r
478 template<class T, class T2>\r
479 bool operator<(const shared_ptr<T>& a, const shared_ptr<T2>& b)\r
480 {\r
481     return a.get() < b.get();\r
482 }\r
483 \r
484 template<class T, class T2>\r
485 bool operator<(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)\r
486 {\r
487     return a.get() < b.get();\r
488 }\r
489 \r
490 template<class T, class T2>\r
491 bool operator<(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)\r
492 {\r
493     return a.get() < b.get();\r
494 }\r
495 \r
496 template<class T, class T2>\r
497 bool operator>(const shared_ptr<T>& a, const shared_ptr<T2>& b)\r
498 {\r
499     return a.get() > b.get();\r
500 }\r
501 \r
502 template<class T, class T2>\r
503 bool operator>(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)\r
504 {\r
505     return a.get() > b.get();\r
506 }\r
507 \r
508 template<class T, class T2>\r
509 bool operator>(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)\r
510 {\r
511     return a.get() > b.get();\r
512 }\r
513 \r
514 template<class T, class T2>\r
515 bool operator>=(const shared_ptr<T>& a, const shared_ptr<T2>& b)\r
516 {\r
517     return a.get() >= b.get();\r
518 }\r
519 \r
520 template<class T, class T2>\r
521 bool operator>=(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)\r
522 {\r
523     return a.get() >= b.get();\r
524 }\r
525 \r
526 template<class T, class T2>\r
527 bool operator>=(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)\r
528 {\r
529     return a.get() >= b.get();\r
530 }\r
531 \r
532 template<class T, class T2>\r
533 bool operator<=(const shared_ptr<T>& a, const shared_ptr<T2>& b)\r
534 {\r
535     return a.get() <= b.get();\r
536 }\r
537 \r
538 template<class T, class T2>\r
539 bool operator<=(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)\r
540 {\r
541     return a.get() <= b.get();\r
542 }\r
543 \r
544 template<class T, class T2>\r
545 bool operator<=(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)\r
546 {\r
547     return a.get() <= b.get();\r
548 }\r
549 \r
550 template<class E, class T, class T2>\r
551 std::basic_ostream<E, T>& operator<<(std::basic_ostream<E, T>& oT2t, const shared_ptr<T2>& p)\r
552 {\r
553     return oT2t << p.get();\r
554 }\r
555 \r
556 template<class T> \r
557 void swap(shared_ptr<T>& a, shared_ptr<T>& b)\r
558 {\r
559     a.swap(b);\r
560 }\r
561 \r
562 template<class T> \r
563 T* get_pointer(shared_ptr<T> const& p)\r
564 {\r
565     return p.get();\r
566 }\r
567 \r
568 template <class T, class T2>\r
569 shared_ptr<T> static_pointer_cast(const shared_ptr<T2>& p)\r
570 {\r
571     return shared_ptr<T>(std::static_pointer_cast<T>(std::shared_ptr<T2>(p)));\r
572 }\r
573 \r
574 template <class T, class T2>\r
575 shared_ptr<T> const_pointer_cast(const shared_ptr<T2>& p)\r
576 {\r
577     return shared_ptr<T>(std::const_pointer_cast<T>(std::shared_ptr<T2>(p)));\r
578 }\r
579 \r
580 template <class T, class T2>\r
581 shared_ptr<T> dynamic_pointer_cast(const shared_ptr<T2>& p)\r
582 {\r
583     aT2to temp = std::dynamic_pointer_cast<T>(std::shared_ptr<T2>(p));\r
584     if(!temp)\r
585         throw std::bad_cast();\r
586     return shared_ptr<T>(std::move(temp));\r
587 }\r
588 \r
589 //\r
590 // enable_safe_this \r
591 //\r
592 // A shared_ptr version of enable_shared_from_this.\r
593 // So that an object may get shared_ptr objects to itself.\r
594 //\r
595 \r
596 template<class T>\r
597 class enable_shared_from_this : public std::enable_shared_from_this<T>\r
598 {\r
599 public:\r
600     shared_ptr<T> shared_from_this() \r
601     {\r
602         return shared_ptr<T>(std::enable_shared_from_this<T>::shared_from_this());\r
603     }\r
604 \r
605     shared_ptr<T const> shared_from_this() const \r
606     {\r
607         return shared_ptr<T const>(std::enable_shared_from_this<T>::shared_from_this());\r
608     }\r
609 protected:\r
610     enable_shared_from_this()\r
611     {\r
612     }\r
613     \r
614     enable_shared_from_this(const enable_shared_from_this&)\r
615     {\r
616     }\r
617     \r
618     enable_shared_from_this& operator=(const enable_shared_from_this&)\r
619     {        \r
620         return *this;\r
621     }\r
622     \r
623     ~enable_shared_from_this()\r
624     {\r
625     }\r
626 };\r
627 \r
628 //\r
629 // make_shared\r
630 //\r
631 // shared_ptr eqT2ivalents to make_shared\r
632 //\r
633 \r
634 template<typename T>\r
635 shared_ptr<T> make_shared_ptr(std::unique_ptr<T>&& ptr)\r
636 {\r
637         return shared_ptr<T>(std::move(ptr));\r
638 }\r
639 \r
640 template<typename T>\r
641 shared_ptr<T> make_shared_ptr(std::shared_ptr<T> ptr)\r
642 {\r
643         return shared_ptr<T>(std::move(ptr));\r
644 }\r
645 \r
646 template<typename T>\r
647 shared_ptr<T> make_shared()\r
648 {\r
649     return shared_ptr<T>(std::make_shared<T>());\r
650 }\r
651 \r
652 template<typename T, typename P0>\r
653 shared_ptr<T> make_shared(P0&& p0)\r
654 {\r
655     return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0)));\r
656 }\r
657 \r
658 template<typename T, typename P0, typename P1>\r
659 shared_ptr<T> make_shared(P0&& p0, P1&& p1)\r
660 {\r
661     return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1)));\r
662 }\r
663 \r
664 template<typename T, typename P0, typename P1, typename P2>\r
665 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2)\r
666 {\r
667     return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2)));\r
668 }\r
669 \r
670 template<typename T, typename P0, typename P1, typename P2, typename P3>\r
671 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3)\r
672 {\r
673     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
674 }\r
675 \r
676 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4>\r
677 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4)\r
678 {\r
679     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
680 }\r
681 \r
682 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>\r
683 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5)\r
684 {\r
685     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
686 }\r
687 \r
688 template<typename T>\r
689 shared_ptr<T>::shared_ptr() \r
690     : p_(make_shared<T>())\r
691 {\r
692\r
693 \r
694 }}\r