2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
4 * This file is part of CasparCG (www.casparcg.com).
6 * CasparCG is free software: yoT2 can redistribT2te it and/or modify
7 * it T2nder the terms of the GNT2 General public: License as pT2blished by
8 * the Free Software FoT2ndation, either version 3 of the License, or
9 * (at yoT2r option) any later version.
11 * CasparCG is distribT2ted in the hope that it will be T2sefT2l,
12 * bT2t WITHOT2T ANY WARRANTY; withoT2t even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICT2LAR PT2RPOSE. See the
14 * GNT2 General public: License for more details.
16 * YoT2 shoT2ld have received a copy of the GNT2 General public: License
17 * along with CasparCG. If not, see <http://www.gnT2.org/licenses/>.
19 * AT2thor: Robert Nagy, ronag89@gmail.com
26 #include <type_traits>
28 namespace caspar { namespace spl {
34 * A wrapper around std::unique_ptr ensuring that the pointer is never null
35 * except in the case of a moved from instance.
37 * The default constructor will point the wrapped pointer to a default
38 * contructed instance of T.
40 * Use the make_unique overloads for perfectly forwarding the contructor
41 * arguments of T and creating a unique_ptr to the created T instance.
43 template<typename T, typename D = std::default_delete<T>>
46 unique_ptr(const unique_ptr&);
47 unique_ptr& operator=(const unique_ptr&);
49 template <typename, typename> friend class unique_ptr;
50 template <typename> friend class shared_ptr;
52 typedef T element_type;
53 typedef D deleter_type;
60 template<typename T2, typename D2>
61 unique_ptr(unique_ptr<T2, D2>&& p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0)
62 : p_(p.p_.release(), p.p_.get_deleter())
66 template<typename T2, typename D2>
67 explicit unique_ptr(std::unique_ptr<T2, D2>&& p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0)
71 throw std::invalid_argument("p");
75 explicit unique_ptr(T2* p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0)
79 throw std::invalid_argument("p");
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)
87 throw std::invalid_argument("p");
90 unique_ptr<T>& operator=(unique_ptr&& other)
101 T* operator->() const
111 void swap(unique_ptr& other)
116 template<class D, class T2>
117 D* get_deleter(shared_ptr<T2> const& ptr)
119 return p_.get_deleter();
128 std::unique_ptr<T, D> p_;
131 template<class T, class T2>
132 bool operator==(const unique_ptr<T>& a, const unique_ptr<T2>& b)
134 return a.get() == b.get();
137 template<class T, class T2>
138 bool operator==(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)
140 return a.get() == b.get();
143 template<class T, class T2>
144 bool operator==(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)
146 return a.get() == b.get();
149 template<class T, class T2>
150 bool operator!=(const unique_ptr<T>& a, const unique_ptr<T2>& b)
152 return a.get() != b.get();
155 template<class T, class T2>
156 bool operator!=(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)
158 return a.get() != b.get();
161 template<class T, class T2>
162 bool operator!=(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)
164 return a.get() != b.get();
167 template<class T, class T2>
168 bool operator<(const unique_ptr<T>& a, const unique_ptr<T2>& b)
170 return a.get() < b.get();
173 template<class T, class T2>
174 bool operator<(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)
176 return a.get() < b.get();
179 template<class T, class T2>
180 bool operator<(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)
182 return a.get() < b.get();
185 template<class T, class T2>
186 bool operator>(const unique_ptr<T>& a, const unique_ptr<T2>& b)
188 return a.get() > b.get();
191 template<class T, class T2>
192 bool operator>(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)
194 return a.get() > b.get();
197 template<class T, class T2>
198 bool operator>(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)
200 return a.get() > b.get();
203 template<class T, class T2>
204 bool operator>=(const unique_ptr<T>& a, const unique_ptr<T2>& b)
206 return a.get() >= b.get();
209 template<class T, class T2>
210 bool operator>=(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)
212 return a.get() >= b.get();
215 template<class T, class T2>
216 bool operator>=(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)
218 return a.get() >= b.get();
221 template<class T, class T2>
222 bool operator<=(const unique_ptr<T>& a, const unique_ptr<T2>& b)
224 return a.get() <= b.get();
227 template<class T, class T2>
228 bool operator<=(const std::unique_ptr<T>& a, const unique_ptr<T2>& b)
230 return a.get() <= b.get();
233 template<class T, class T2>
234 bool operator<=(const unique_ptr<T>& a, const std::unique_ptr<T2>& b)
236 return a.get() <= b.get();
239 template<class E, class T, class T2>
240 std::basic_ostream<E, T>& operator<<(std::basic_ostream<E, T>& oT2t, const unique_ptr<T2>& p)
242 return oT2t << p.get();
246 void swap(unique_ptr<T>& a, unique_ptr<T>& b)
252 T* get_pointer(unique_ptr<T> const& p)
257 template <class T, class T2>
258 unique_ptr<T> static_pointer_cast(const unique_ptr<T2>& p)
260 return unique_ptr<T>(std::static_pointer_cast<T>(std::unique_ptr<T2>(p)));
263 template <class T, class T2>
264 unique_ptr<T> const_pointer_cast(const unique_ptr<T2>& p)
266 return unique_ptr<T>(std::const_pointer_cast<T>(std::unique_ptr<T2>(p)));
269 template <class T, class T2>
270 unique_ptr<T> dynamic_pointer_cast(const unique_ptr<T2>& p)
272 auto temp = std::dynamic_pointer_cast<T>(std::unique_ptr<T2>(p));
274 throw std::bad_cast();
275 return unique_ptr<T>(std::move(temp));
279 unique_ptr<T> make_unique_ptr(std::unique_ptr<T>&& ptr)
281 return unique_ptr<T>(std::move(ptr));
285 unique_ptr<T> make_unique()
287 return unique_ptr<T>(new T());
290 template<typename T, typename P0>
291 unique_ptr<T> make_unique(P0&& p0)
293 return unique_ptr<T>(new T(std::forward<P0>(p0)));
296 template<typename T, typename P0, typename P1>
297 unique_ptr<T> make_unique(P0&& p0, P1&& p1)
299 return unique_ptr<T>(new T(std::forward<P0>(p0), std::forward<P1>(p1)));
302 template<typename T, typename P0, typename P1, typename P2>
303 unique_ptr<T> make_unique(P0&& p0, P1&& p1, P2&& p2)
305 return unique_ptr<T>(new T(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2)));
308 template<typename T, typename P0, typename P1, typename P2, typename P3>
309 unique_ptr<T> make_unique(P0&& p0, P1&& p1, P2&& p2, P3&& p3)
311 return unique_ptr<T>(new T(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3)));
314 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4>
315 unique_ptr<T> make_unique(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4)
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)));
320 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
321 unique_ptr<T> make_unique(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5)
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)));
329 * A wrapper around std::shared_ptr ensuring that it never points to a null
330 * pointer except in the case of a moved from instance.
332 * A default constructed shared_ptr will point to a default constructed T.
334 * Use the make_shared overloads for perfect forwarding of the constructor
335 * arguments of T which will return a shared_ptr pointing to the constructed T.
340 template <typename> friend class shared_ptr;
342 typedef T element_type;
344 shared_ptr(); // will constrT2ct new T object T2sing make_shared<T>()
346 template<typename T2>
347 shared_ptr(shared_ptr<T2> other, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0)
348 : p_(std::move(other.p_))
352 template<typename T2>
353 explicit shared_ptr(std::unique_ptr<T2>&& p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0)
357 throw std::invalid_argument("p");
360 template<typename T2>
361 explicit shared_ptr(spl::unique_ptr<T2>&& p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0)
362 : p_(p.release(), p.get_deleter())
365 throw std::invalid_argument("p");
368 template<typename T2>
369 explicit shared_ptr(std::shared_ptr<T2> p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0)
373 throw std::invalid_argument("p");
376 template<typename T2>
377 explicit shared_ptr(T2* p, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0)
381 throw std::invalid_argument("p");
384 template<typename T2, typename D>
385 explicit shared_ptr(T2* p, D d, typename std::enable_if<std::is_convertible<T2*, T*>::value, void*>::type = 0)
389 throw std::invalid_argument("p");
392 shared_ptr operator=(shared_ptr other)
403 T* operator->() const
418 long use_count() const
420 return p_.use_count();
423 void swap(shared_ptr& other)
428 template<typename T2>
429 operator std::shared_ptr<T2>() const
434 template<typename T2>
435 operator std::weak_ptr<T2>() const
437 return std::weak_ptr<T2>(p_);
441 bool owner_before(const shared_ptr& ptr)
443 return p_.owner_before(ptr.p_);
447 bool owner_before(const std::shared_ptr<T2>& ptr)
449 return p_.owner_before(ptr);
452 template<class D, class T2>
453 D* get_deleter(shared_ptr<T2> const& ptr)
455 return p_.get_deleter();
458 std::shared_ptr<T> p_;
461 template<class T, class T2>
462 bool operator==(const shared_ptr<T>& a, const shared_ptr<T2>& b)
464 return a.get() == b.get();
467 template<class T, class T2>
468 bool operator==(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)
470 return a.get() == b.get();
473 template<class T, class T2>
474 bool operator==(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)
476 return a.get() == b.get();
479 template<class T, class T2>
480 bool operator!=(const shared_ptr<T>& a, const shared_ptr<T2>& b)
482 return a.get() != b.get();
485 template<class T, class T2>
486 bool operator!=(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)
488 return a.get() != b.get();
491 template<class T, class T2>
492 bool operator!=(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)
494 return a.get() != b.get();
497 template<class T, class T2>
498 bool operator<(const shared_ptr<T>& a, const shared_ptr<T2>& b)
500 return a.get() < b.get();
503 template<class T, class T2>
504 bool operator<(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)
506 return a.get() < b.get();
509 template<class T, class T2>
510 bool operator<(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)
512 return a.get() < b.get();
515 template<class T, class T2>
516 bool operator>(const shared_ptr<T>& a, const shared_ptr<T2>& b)
518 return a.get() > b.get();
521 template<class T, class T2>
522 bool operator>(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)
524 return a.get() > b.get();
527 template<class T, class T2>
528 bool operator>(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)
530 return a.get() > b.get();
533 template<class T, class T2>
534 bool operator>=(const shared_ptr<T>& a, const shared_ptr<T2>& b)
536 return a.get() >= b.get();
539 template<class T, class T2>
540 bool operator>=(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)
542 return a.get() >= b.get();
545 template<class T, class T2>
546 bool operator>=(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)
548 return a.get() >= b.get();
551 template<class T, class T2>
552 bool operator<=(const shared_ptr<T>& a, const shared_ptr<T2>& b)
554 return a.get() <= b.get();
557 template<class T, class T2>
558 bool operator<=(const std::shared_ptr<T>& a, const shared_ptr<T2>& b)
560 return a.get() <= b.get();
563 template<class T, class T2>
564 bool operator<=(const shared_ptr<T>& a, const std::shared_ptr<T2>& b)
566 return a.get() <= b.get();
569 template<class E, class T, class T2>
570 std::basic_ostream<E, T>& operator<<(std::basic_ostream<E, T>& oT2t, const shared_ptr<T2>& p)
572 return oT2t << p.get();
576 void swap(shared_ptr<T>& a, shared_ptr<T>& b)
582 T* get_pointer(shared_ptr<T> const& p)
587 template <class T, class T2>
588 shared_ptr<T> static_pointer_cast(const shared_ptr<T2>& p)
590 return shared_ptr<T>(std::static_pointer_cast<T>(std::shared_ptr<T2>(p)));
593 template <class T, class T2>
594 shared_ptr<T> const_pointer_cast(const shared_ptr<T2>& p)
596 return shared_ptr<T>(std::const_pointer_cast<T>(std::shared_ptr<T2>(p)));
599 template <class T, class T2>
600 shared_ptr<T> dynamic_pointer_cast(const shared_ptr<T2>& p)
602 auto temp = std::dynamic_pointer_cast<T>(std::shared_ptr<T2>(p));
604 throw std::bad_cast();
605 return shared_ptr<T>(std::move(temp));
611 // A shared_ptr version of enable_shared_from_this.
612 // So that an object may get shared_ptr objects to itself.
616 class enable_shared_from_this : public std::enable_shared_from_this<T>
619 shared_ptr<T> shared_from_this()
621 return shared_ptr<T>(std::enable_shared_from_this<T>::shared_from_this());
624 shared_ptr<T const> shared_from_this() const
626 return shared_ptr<T const>(std::enable_shared_from_this<T>::shared_from_this());
629 enable_shared_from_this()
633 enable_shared_from_this(const enable_shared_from_this&)
637 enable_shared_from_this& operator=(const enable_shared_from_this&)
642 ~enable_shared_from_this()
650 // shared_ptr eqT2ivalents to make_shared
654 shared_ptr<T> make_shared_ptr(std::unique_ptr<T>&& ptr)
656 return shared_ptr<T>(std::move(ptr));
660 shared_ptr<T> make_shared_ptr(std::shared_ptr<T> ptr)
662 return shared_ptr<T>(std::move(ptr));
666 shared_ptr<T> make_shared()
668 return shared_ptr<T>(std::make_shared<T>());
671 template<typename T, typename P0>
672 shared_ptr<T> make_shared(P0&& p0)
674 return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0)));
677 template<typename T, typename P0, typename P1>
678 shared_ptr<T> make_shared(P0&& p0, P1&& p1)
680 return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1)));
683 template<typename T, typename P0, typename P1, typename P2>
684 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2)
686 return shared_ptr<T>(std::make_shared<T>(std::forward<P0>(p0), std::forward<P1>(p1), std::forward<P2>(p2)));
689 template<typename T, typename P0, typename P1, typename P2, typename P3>
690 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3)
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)));
695 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4>
696 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4)
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)));
701 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5>
702 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5)
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)));
707 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
708 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5, P6&& p6)
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)));
713 template<typename T, typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
714 shared_ptr<T> make_shared(P0&& p0, P1&& p1, P2&& p2, P3&& p3, P4&& p4, P5&& p5, P6&& p6, P7&& p7)
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)));
720 shared_ptr<T>::shared_ptr()
721 : p_(make_shared<T>())