9 #ifndef slimsig_tracked_connect_h
10 #define slimsig_tracked_connect_h
13 #include <initializer_list>
15 #include <type_traits>
18 template <
class T,
class Observer,
class BaseAllocator = std::allocator<T>>
20 using allocator_traits = std::allocator_traits<BaseAllocator>;
21 using base = BaseAllocator;
23 using parent_rebind_traits_t =
typename allocator_traits::template rebind_traits<U>;
25 using parent_rebind_t =
typename parent_rebind_traits_t<U>::allocator_type;
27 using typename allocator_traits::value_type;
29 using typename allocator_traits::const_pointer;
30 using typename allocator_traits::void_pointer;
31 using typename allocator_traits::const_void_pointer;
32 using typename allocator_traits::difference_type;
33 using typename allocator_traits::size_type;
34 using typename allocator_traits::propagate_on_container_copy_assignment;
35 using typename allocator_traits::propagate_on_container_move_assignment;
36 using typename allocator_traits::propagate_on_container_swap;
38 template <
class U,
class O = Observer>
41 using base::deallocate;
42 using base::construct;
47 allocator_traits::destroy(*
this, p);
52 template <
class T,
class Observer,
class Deleter = std::default_delete<T>>
55 template <class U, class OtherObserver = Observer, class OtherDeleter = Deleter, std::enable_if<std::is_convertible<U*, T*>::
value,
bool> =
true>
57 trackable_delete(Observer observer = Observer{}, Deleter deleter = Deleter{}) : m_observer(std::move(observer)), m_deleter(std::move(deleter)){};
83 template <
class T,
class Observer,
class Deleter = std::default_delete<T>>
84 using trackable_ptr = std::unique_ptr<T, trackable_delete<T, Observer, Deleter>>;
86 template <
class T,
class Observer,
class Deleter = std::default_delete<T>,
class TrackableDeleter = trackable_delete<T, Observer, Deleter>,
class... Args>
87 std::shared_ptr<T>
make_trackable(TrackableDeleter deleter, Args&&... args) {
88 return std::shared_ptr<T> ( deleter, T{std::forward<Args>(args)...} );
90 template <
class T,
class Observer,
class Deleter = std::default_delete<T>,
class TrackableDeleter = trackable_delete<T, Observer, Deleter>,
class... Args>
92 return std::shared_ptr<T> ( TrackableDeleter { observer }, T{std::forward<Args>(args)...} );
94 template <
class T,
class Observer,
class Deleter = std::default_delete<T>,
class TrackableDeleter = trackable_delete<T, Observer, Deleter>,
class... Args>
95 std::shared_ptr<T>
make_trackable(Observer observer, Deleter deleter, Args&&... args) {
96 return std::shared_ptr<T> ( TrackableDeleter { observer, deleter }, T{std::forward<Args>(args)...} );
98 template <
class T,
class Observer,
class Allocator = std::allocator<T>,
class TrackableAllocator = trackable_allocator<T, Observer, Allocator>,
class... Args>
100 return std::allocate_shared<T>(allocator, std::forward<Args>(args)...);
102 template <
class T,
class Observer,
class Allocator = std::allocator<T>,
class TrackableAllocator = trackable_allocator<T, Observer, Allocator>,
class... Args>
104 return std::allocate_shared<T>(TrackableAllocator {observer}, std::forward<Args>(args)...);
106 template <
class T,
class Observer,
class Allocator = std::allocator<T>,
class TrackableAllocator = trackable_allocator<T, Observer, Allocator>,
class... Args>
108 return std::allocate_shared<T>(TrackableAllocator {observer, allocator}, std::forward<Args>(args)...);
116 trackable_lock(std::vector<std::weak_ptr<T>> trackable_objects) : m_tracking(std::move(trackable_objects)) {};
117 trackable_lock(std::initializer_list<std::weak_ptr<T>> trackable_list) : m_tracking{std::move(trackable_list)} {}
122 m_locked.reserve(m_tracking.size());
126 std::vector<std::weak_ptr<T>> m_tracking;
127 std::vector<std::shared_ptr<T>> m_locked;