You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a small header-only library, providing a unique-ownership smart pointer`observable_unique_ptr` that can be observed with non-owning pointers `observer_ptr`. It is a mixture of `std::unique_ptr` and `std::shared_ptr`: it borrows the unique-ownership semantic of `std::unique_ptr` (movable, non-copiable), but allows creating `observer_ptr` to monitor the lifetime of the pointed object (like `std::weak_ptr` for `std::shared_ptr`).
14
+
This is a small header-only library, providing the unique-ownership smart pointers`observable_unique_ptr`and `observable_sealed_ptr`that can be observed with non-owning pointers `observer_ptr`. This is a mixture of `std::unique_ptr` and `std::shared_ptr`: it borrows the unique-ownership semantic of `std::unique_ptr` (movable, non-copiable), but allows creating `observer_ptr` to monitor the lifetime of the pointed object (like `std::weak_ptr` for `std::shared_ptr`).
15
15
16
-
This is useful for cases where the shared-ownership of `std::shared_ptr` is not desirable, e.g., when lifetime must be carefully controlled and not be allowed to extend, yet non-owning/weak/observer references to the object may exist after the object has been deleted.
16
+
The only difference between `observable_unique_ptr` and `observable_sealed_ptr` is that the former can release ownership, while the latter cannot. Disallowing release of ownership enables allocation optimizations. Therefore, the recommendation is to use `observable_sealed_ptr` unless release of ownership is required.
17
17
18
-
Note: Because of the unique ownership model, observer pointers cannot extend the lifetime of the pointed object, hence `observable_unique_ptr`/`observer_ptr` provides less thread-safety compared to `std::shared_ptr`/`std::weak_ptr`. This is also true of `std::unique_ptr`, and is a fundamental limitation of unique ownership. If this is an issue, you will need either to add your own explicit locking logic, or use `std::shared_ptr`/`std::weak_ptr`.
18
+
These pointers are useful for cases where the shared-ownership of `std::shared_ptr` is not desirable, e.g., when lifetime must be carefully controlled and not be allowed to extend, yet non-owning/weak/observer references to the object may exist after the object has been deleted.
19
+
20
+
Note: Because of the unique ownership model, observer pointers cannot extend the lifetime of the pointed object, hence this library provides less thread-safety compared to `std::shared_ptr`/`std::weak_ptr`. This is also true of `std::unique_ptr`, and is a fundamental limitation of unique ownership. If this is an issue, you will need either to add your own explicit locking logic, or use `std::shared_ptr`/`std::weak_ptr`.
19
21
20
22
21
23
## Usage
@@ -39,7 +41,7 @@ int main() {
39
41
40
42
{
41
43
// Unique pointer that owns the object
42
-
auto owner_ptr = oup::make_observable_unique<std::string>("hello");
44
+
auto owner_ptr = oup::make_observable_sealed<std::string>("hello");
43
45
44
46
// Make the observer pointer point to the object
45
47
obs_ptr = owner_ptr;
@@ -70,10 +72,10 @@ int main() {
70
72
71
73
## Limitations
72
74
73
-
The follownig limitations are features that were not implemented simply because of lack of motivation.
75
+
The following limitations are features that were not implemented simply because of lack of motivation.
74
76
75
-
-`observable_unique_ptr` does not support pointers to arrays, but `std::unique_ptr` and `std::shared_ptr` both do.
76
-
-`observable_unique_ptr` does not support custom allocators, but `std::shared_ptr` does.
77
+
-this library does not support pointers to arrays, but `std::unique_ptr` and `std::shared_ptr` both do.
78
+
-this library does not support custom allocators, but `std::shared_ptr` does.
- (1) If `expired()` returns true, the pointer is garanteed to remain `nullptr` forever, with no ace condition. If `expired()` returns false, the pointer could still expire on the next instant, which can lead to race conditions.
115
+
- (1) If `expired()` returns true, the pointer is guaranteed to remain `nullptr` forever, with no ace condition. If `expired()` returns false, the pointer could still expire on the next instant, which can lead to race conditions.
111
116
- (2) By construction, only one thread can own the pointer, therefore deletion is thread-safe.
112
117
- (3) Yes if using `std::atomic<std::shared_ptr<T>>` and `std::atomic<std::weak_ptr<T>>`.
0 commit comments