opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
copy_on_upd_ptr.h
Go to the documentation of this file.
1#pragma once
2
3#include <functional>
4#include <memory>
5#include <type_traits>
6#include <utility>
7
8namespace osc
9{
10 // `CopyOnUpdPtr` is a smart pointer that retains shared ownership of an object through
11 // a pointer. Several `CopyOnUpdPtr` objects may view the same object, but it can only
12 // be mutated via `upd()`, results in the following happening:
13 //
14 // - if there is one owner, provides mutable access to the object
15 // - if there are multiple owners, copies the object and provides single-owner mutable access to the copy
16 //
17 // The object is destroyed and its memory deallocated when either of the following happens:
18 //
19 // - the last remaining `CopyOnUpdPtr` owning the object is destroyed
20 // - the last remaining `CopyOnUpdPtr` owning the object is assigned another pointer via `operator=` or `reset()`
21 template<typename T>
23 private:
24 template<typename U, typename... Args>
26
27 explicit CopyOnUpdPtr(std::shared_ptr<T> ptr) :
28 ptr_{std::move(ptr)}
29 {}
30 public:
31 using pointer = T*;
32 using element_type = std::remove_extent_t<T>;
33
35 {
36 return ptr_.get();
37 }
38
40 {
41 if (ptr_.use_count() > 1) {
42 ptr_ = std::make_shared<T>(*ptr_);
43 }
44 return ptr_.get();
45 }
46
48 {
49 return *ptr_;
50 }
51
53 {
54 return get();
55 }
56
57 friend void swap(CopyOnUpdPtr& a, CopyOnUpdPtr& b) noexcept
58 {
59 swap(a.ptr_, b.ptr_);
60 }
61
62 template<typename U>
63 friend bool operator==(const CopyOnUpdPtr& lhs, const CopyOnUpdPtr<U>& rhs)
64 {
65 return lhs.ptr_ == rhs.ptr_;
66 }
67
68 template<typename U>
69 friend auto operator<=>(const CopyOnUpdPtr& lhs, const CopyOnUpdPtr<U>& rhs)
70 {
71 return lhs.ptr_ <=> rhs.ptr_;
72 }
73
74 private:
75 friend struct std::hash<CopyOnUpdPtr>;
76
77 std::shared_ptr<T> ptr_;
78 };
79
80 template<typename T, typename... Args>
82 {
83 return CopyOnUpdPtr<T>(std::make_shared<T>(std::forward<Args>(args)...));
84 }
85}
86
87template<typename T>
88struct std::hash<osc::CopyOnUpdPtr<T>> final {
89 size_t operator()(const osc::CopyOnUpdPtr<T>& cow) const noexcept
90 {
91 return std::hash<std::shared_ptr<T>>{}(cow.ptr_);
92 }
93};
Definition copy_on_upd_ptr.h:22
friend void swap(CopyOnUpdPtr &a, CopyOnUpdPtr &b) noexcept
Definition copy_on_upd_ptr.h:57
friend bool operator==(const CopyOnUpdPtr &lhs, const CopyOnUpdPtr< U > &rhs)
Definition copy_on_upd_ptr.h:63
element_type * upd()
Definition copy_on_upd_ptr.h:39
const T & operator*() const noexcept
Definition copy_on_upd_ptr.h:47
friend CopyOnUpdPtr< U > make_cow(Args &&...)
const T * operator->() const noexcept
Definition copy_on_upd_ptr.h:52
T * pointer
Definition copy_on_upd_ptr.h:31
friend auto operator<=>(const CopyOnUpdPtr &lhs, const CopyOnUpdPtr< U > &rhs)
Definition copy_on_upd_ptr.h:69
std::remove_extent_t< T > element_type
Definition copy_on_upd_ptr.h:32
const element_type * get() const noexcept
Definition copy_on_upd_ptr.h:34
Definition custom_decoration_generator.h:5
CopyOnUpdPtr< T > make_cow(Args &&... args)
Definition copy_on_upd_ptr.h:81
constexpr U to(T &&value)
Definition conversion.h:56
size_t operator()(const osc::CopyOnUpdPtr< T > &cow) const noexcept
Definition copy_on_upd_ptr.h:89