Skip to content

Commit 2831085

Browse files
committed
Made control block type public, for easier use
1 parent e34295a commit 2831085

File tree

1 file changed

+65
-53
lines changed

1 file changed

+65
-53
lines changed

include/oup/observable_unique_ptr.hpp

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -29,54 +29,6 @@ template<typename T, typename Policy, typename ... Args>
2929
auto make_observable(Args&& ... args);
3030

3131
namespace details {
32-
/// Implementation-defined class holding reference counts and expired flag.
33-
/** All the details about this class are private, and only accessible to
34-
* `oup::` classes. As a user, you may only use this class to forward it
35-
* to `oup::` classes as required.
36-
*/
37-
template<typename Policy>
38-
class control_block {
39-
template<typename T, typename D, typename P>
40-
friend class oup::basic_observable_ptr;
41-
42-
template<typename T, typename P>
43-
friend class oup::basic_observer_ptr;
44-
45-
template<typename P>
46-
friend struct enable_observer_from_this_base;
47-
48-
template<typename U, typename P, typename ... Args>
49-
friend auto oup::make_observable(Args&& ... args);
50-
51-
using refcount_type = typename Policy::refcount_type;
52-
53-
enum flag_elements {
54-
flag_none = 0,
55-
flag_expired = 1
56-
};
57-
58-
refcount_type refcount = 1;
59-
int flags = flag_none;
60-
61-
control_block() noexcept = default;
62-
control_block(const control_block&) = delete;
63-
control_block(control_block&&) = delete;
64-
control_block& operator=(const control_block&) = delete;
65-
control_block& operator=(control_block&&) = delete;
66-
67-
void push_ref() noexcept { ++refcount; }
68-
69-
void pop_ref() noexcept { --refcount; }
70-
71-
bool has_no_ref() const noexcept { return refcount == 0; }
72-
73-
bool expired() const noexcept { return (flags & flag_expired) != 0; }
74-
75-
void set_not_expired() noexcept { flags = flags & ~flag_expired; }
76-
77-
void set_expired() noexcept { flags = flags | flag_expired; }
78-
};
79-
8032
// This class enables optimizing the space taken by the Deleter object
8133
// when the deleter is stateless (has no member variable). It relies
8234
// on empty base class optimization. In C++20, this could be simplified
@@ -140,14 +92,67 @@ struct sealed_policy {
14092
using control_block_policy = default_control_block_policy;
14193
};
14294

95+
namespace details {
96+
template<typename Policy>
97+
struct enable_observer_from_this_base;
98+
}
99+
100+
/// Implementation-defined class holding reference counts and expired flag.
101+
/** All the details about this class are private, and only accessible to
102+
* `oup::` classes. As a user, you may only use this class to forward it
103+
* to `oup::` classes as required.
104+
*/
105+
template<typename Policy>
106+
class basic_control_block {
107+
template<typename T, typename D, typename P>
108+
friend class oup::basic_observable_ptr;
109+
110+
template<typename T, typename P>
111+
friend class oup::basic_observer_ptr;
112+
113+
template<typename P>
114+
friend struct details::enable_observer_from_this_base;
115+
116+
template<typename U, typename P, typename ... Args>
117+
friend auto oup::make_observable(Args&& ... args);
118+
119+
using refcount_type = typename Policy::refcount_type;
120+
121+
enum flag_elements {
122+
flag_none = 0,
123+
flag_expired = 1
124+
};
125+
126+
refcount_type refcount = 1;
127+
int flags = flag_none;
128+
129+
basic_control_block() noexcept = default;
130+
basic_control_block(const basic_control_block&) = delete;
131+
basic_control_block(basic_control_block&&) = delete;
132+
basic_control_block& operator=(const basic_control_block&) = delete;
133+
basic_control_block& operator=(basic_control_block&&) = delete;
134+
135+
void push_ref() noexcept { ++refcount; }
136+
137+
void pop_ref() noexcept { --refcount; }
138+
139+
bool has_no_ref() const noexcept { return refcount == 0; }
140+
141+
bool expired() const noexcept { return (flags & flag_expired) != 0; }
142+
143+
void set_not_expired() noexcept { flags = flags & ~flag_expired; }
144+
145+
void set_expired() noexcept { flags = flags | flag_expired; }
146+
};
147+
143148
namespace details {
144149
template<typename Policy>
145150
struct enable_observer_from_this_base {
146151
/// Policy for the control block
147152
using control_block_policy = typename Policy::control_block_policy;
148153

149154
/// Type of the control block
150-
using control_block_type = details::control_block<control_block_policy>;
155+
using control_block_type = basic_control_block<control_block_policy>;
151156

152157
mutable control_block_type* this_control_block = nullptr;
153158

@@ -245,7 +250,7 @@ class basic_observable_ptr {
245250
using control_block_policy = typename Policy::control_block_policy;
246251

247252
/// Type of the control block
248-
using control_block_type = details::control_block<control_block_policy>;
253+
using control_block_type = basic_control_block<control_block_policy>;
249254

250255
/// Type of the pointed object
251256
using element_type = T;
@@ -653,7 +658,7 @@ class basic_observable_ptr {
653658
template<typename T, typename Policy, typename ... Args>
654659
auto make_observable(Args&& ... args) {
655660
using control_block_policy = typename Policy::control_block_policy;
656-
using control_block_type = details::control_block<control_block_policy>;
661+
using control_block_type = basic_control_block<control_block_policy>;
657662
using decayed_type = std::decay_t<T>;
658663

659664
if constexpr (!Policy::is_sealed) {
@@ -764,7 +769,7 @@ class basic_observer_ptr {
764769
using control_block_policy = Policy;
765770

766771
/// Type of the control block
767-
using control_block_type = details::control_block<control_block_policy>;
772+
using control_block_type = basic_control_block<control_block_policy>;
768773

769774
/// Type of the pointed object
770775
using element_type = T;
@@ -1209,7 +1214,7 @@ class basic_enable_observer_from_this : public
12091214
using control_block_policy = typename Policy::control_block_policy;
12101215

12111216
/// Type of the control block
1212-
using control_block_type = details::control_block<control_block_policy>;
1217+
using control_block_type = basic_control_block<control_block_policy>;
12131218

12141219
/// Default constructor.
12151220
/** \note This constructor is only enabled if `Policy::is_enable_observer_base_virtual` is true.
@@ -1424,6 +1429,13 @@ basic_observer_ptr<U,Policy> dynamic_pointer_cast(basic_observer_ptr<T,Policy>&&
14241429
return basic_observer_ptr<U,Policy>(std::move(ptr), dynamic_cast<U*>(ptr.get()));
14251430
}
14261431

1432+
/// Implementation-defined class holding reference counts and expired flag.
1433+
/** All the details about this class are private, and only accessible to
1434+
* `oup::` classes. As a user, you may only use this class to forward it
1435+
* to `oup::` classes as required.
1436+
*/
1437+
using control_block = basic_control_block<default_control_block_policy>;
1438+
14271439
/// Unique-ownership smart pointer, can be observed by @ref observer_ptr, ownership can be released.
14281440
/** This smart pointer mimics the interface of `std::unique_ptr`, in that
14291441
* it is movable but not copiable. The smart pointer holds exclusive

0 commit comments

Comments
 (0)