xref: /haiku/docs/user/netservices/ExclusiveBorrow.dox (revision 1e22817dfb175e3974fcf93a3d755e2346ec3265)
1*1e22817dSNiels Sascha Reedijk/*
2*1e22817dSNiels Sascha Reedijk * Copyright 2021 Haiku, Inc. All rights reserved.
3*1e22817dSNiels Sascha Reedijk * Distributed under the terms of the MIT License.
4*1e22817dSNiels Sascha Reedijk *
5*1e22817dSNiels Sascha Reedijk * Authors:
6*1e22817dSNiels Sascha Reedijk *		Niels Sascha Reedijk, niels.reedijk@gmail.com
7*1e22817dSNiels Sascha Reedijk *
8*1e22817dSNiels Sascha Reedijk * Corresponds to:
9*1e22817dSNiels Sascha Reedijk *		headers/private/netservices2/ExclusiveBorrow.h	hrev?????
10*1e22817dSNiels Sascha Reedijk */
11*1e22817dSNiels Sascha Reedijk
12*1e22817dSNiels Sascha Reedijk
13*1e22817dSNiels Sascha Reedijk#if __cplusplus >= 201703L
14*1e22817dSNiels Sascha Reedijk
15*1e22817dSNiels Sascha Reedijk
16*1e22817dSNiels Sascha Reedijk/*!
17*1e22817dSNiels Sascha Reedijk	\file ExclusiveBorrow.h
18*1e22817dSNiels Sascha Reedijk	\ingroup netservices
19*1e22817dSNiels Sascha Reedijk	\brief Provides the BExclusiveBorrow smart pointer.
20*1e22817dSNiels Sascha Reedijk*/
21*1e22817dSNiels Sascha Reedijk
22*1e22817dSNiels Sascha Reedijknamespace BPrivate {
23*1e22817dSNiels Sascha Reedijk
24*1e22817dSNiels Sascha Reedijknamespace Network {
25*1e22817dSNiels Sascha Reedijk
26*1e22817dSNiels Sascha Reedijk
27*1e22817dSNiels Sascha Reedijk/*!
28*1e22817dSNiels Sascha Reedijk	\class BBorrowError
29*1e22817dSNiels Sascha Reedijk	\ingroup netservices
30*1e22817dSNiels Sascha Reedijk	\brief Error while handling a BExclusiveBorrow or BBorrow object.
31*1e22817dSNiels Sascha Reedijk
32*1e22817dSNiels Sascha Reedijk	\since Haiku R1
33*1e22817dSNiels Sascha Reedijk*/
34*1e22817dSNiels Sascha Reedijk
35*1e22817dSNiels Sascha Reedijk
36*1e22817dSNiels Sascha Reedijk/*!
37*1e22817dSNiels Sascha Reedijk	\fn BBorrowError::BBorrowError(const char* origin)
38*1e22817dSNiels Sascha Reedijk	\brief Constructor that sets the \a origin.
39*1e22817dSNiels Sascha Reedijk
40*1e22817dSNiels Sascha Reedijk	\since Haiku R1
41*1e22817dSNiels Sascha Reedijk*/
42*1e22817dSNiels Sascha Reedijk
43*1e22817dSNiels Sascha Reedijk
44*1e22817dSNiels Sascha Reedijk/*!
45*1e22817dSNiels Sascha Reedijk	\fn virtual const char* BBorrowError::Message() const noexcept override
46*1e22817dSNiels Sascha Reedijk	\brief Get a pointer to the message describing the borrow error.
47*1e22817dSNiels Sascha Reedijk
48*1e22817dSNiels Sascha Reedijk	\since Haiku R1
49*1e22817dSNiels Sascha Reedijk*/
50*1e22817dSNiels Sascha Reedijk
51*1e22817dSNiels Sascha Reedijk
52*1e22817dSNiels Sascha Reedijk//! \cond INTERNAL
53*1e22817dSNiels Sascha Reedijk
54*1e22817dSNiels Sascha Reedijk
55*1e22817dSNiels Sascha Reedijk/*!
56*1e22817dSNiels Sascha Reedijk	\class BorrowAdmin
57*1e22817dSNiels Sascha Reedijk	\brief Internal class that provides admin block for BExclusiveBorrow and BBorrow.
58*1e22817dSNiels Sascha Reedijk
59*1e22817dSNiels Sascha Reedijk	This base class provides the admin functions to deal with the underlying objects that are
60*1e22817dSNiels Sascha Reedijk	managed by this smart pointers. It is implemented in such a way that it provides type erasure
61*1e22817dSNiels Sascha Reedijk	for the actual smart objects, to enable them to allow for a BExclusiveBorrow<Derived> to have a
62*1e22817dSNiels Sascha Reedijk	BBorrow<Base> higher up in the class inheritance.
63*1e22817dSNiels Sascha Reedijk
64*1e22817dSNiels Sascha Reedijk	\since Haiku R1
65*1e22817dSNiels Sascha Reedijk*/
66*1e22817dSNiels Sascha Reedijk
67*1e22817dSNiels Sascha Reedijk
68*1e22817dSNiels Sascha Reedijk/*!
69*1e22817dSNiels Sascha Reedijk	\fn BorrowAdmin::~BorrowAdmin()
70*1e22817dSNiels Sascha Reedijk	\brief Destructor
71*1e22817dSNiels Sascha Reedijk
72*1e22817dSNiels Sascha Reedijk	\since Haiku R1
73*1e22817dSNiels Sascha Reedijk*/
74*1e22817dSNiels Sascha Reedijk
75*1e22817dSNiels Sascha Reedijk
76*1e22817dSNiels Sascha Reedijk/*!
77*1e22817dSNiels Sascha Reedijk	\fn virtual void BorrowAdmin::Cleanup() noexcept
78*1e22817dSNiels Sascha Reedijk	\brief Hook function that triggers the cleanup of the underlying object.
79*1e22817dSNiels Sascha Reedijk
80*1e22817dSNiels Sascha Reedijk	Implemented by BorrowPointer<T>
81*1e22817dSNiels Sascha Reedijk
82*1e22817dSNiels Sascha Reedijk	\since Haiku R1
83*1e22817dSNiels Sascha Reedijk*/
84*1e22817dSNiels Sascha Reedijk
85*1e22817dSNiels Sascha Reedijk
86*1e22817dSNiels Sascha Reedijk/*!
87*1e22817dSNiels Sascha Reedijk	\fn virtual void BorrowAdmin::ReleasePointer() noexcept
88*1e22817dSNiels Sascha Reedijk	\brief Hook function to relinquish ownership of the underlying pointer.
89*1e22817dSNiels Sascha Reedijk
90*1e22817dSNiels Sascha Reedijk	When BExclusiveBorrow<T>::Release() is called, ownership of the pointer is transferred to the
91*1e22817dSNiels Sascha Reedijk	caller. This hook function allows the BorrowPointer<T> to release the object so that there will
92*1e22817dSNiels Sascha Reedijk	not be a double delete when the BExclusiveBorrow<T> is cleaned up.
93*1e22817dSNiels Sascha Reedijk
94*1e22817dSNiels Sascha Reedijk	\since Haiku R1
95*1e22817dSNiels Sascha Reedijk*/
96*1e22817dSNiels Sascha Reedijk
97*1e22817dSNiels Sascha Reedijk
98*1e22817dSNiels Sascha Reedijk/*!
99*1e22817dSNiels Sascha Reedijk	\fn BorrowAdmin::BorrowAdmin()
100*1e22817dSNiels Sascha Reedijk	\brief Constructor
101*1e22817dSNiels Sascha Reedijk
102*1e22817dSNiels Sascha Reedijk	\since Haiku R1
103*1e22817dSNiels Sascha Reedijk*/
104*1e22817dSNiels Sascha Reedijk
105*1e22817dSNiels Sascha Reedijk
106*1e22817dSNiels Sascha Reedijk/*!
107*1e22817dSNiels Sascha Reedijk	\fn void BorrowAdmin::Borrow()
108*1e22817dSNiels Sascha Reedijk	\brief Register that a BBorrow<T> object is created
109*1e22817dSNiels Sascha Reedijk
110*1e22817dSNiels Sascha Reedijk	\exception BBorrowError In case the object already is borrowed.
111*1e22817dSNiels Sascha Reedijk
112*1e22817dSNiels Sascha Reedijk	\since Haiku R1
113*1e22817dSNiels Sascha Reedijk*/
114*1e22817dSNiels Sascha Reedijk
115*1e22817dSNiels Sascha Reedijk
116*1e22817dSNiels Sascha Reedijk/*!
117*1e22817dSNiels Sascha Reedijk	\fn void BorrowAdmin::Return() noexcept
118*1e22817dSNiels Sascha Reedijk	\brief Register that the BBorrow<T> object no longer borrows the object.
119*1e22817dSNiels Sascha Reedijk
120*1e22817dSNiels Sascha Reedijk	This also cleans up the internal object if the corresponding BExclusiveBorrow<T> no longer
121*1e22817dSNiels Sascha Reedijk	exists.
122*1e22817dSNiels Sascha Reedijk
123*1e22817dSNiels Sascha Reedijk	\since Haiku R1
124*1e22817dSNiels Sascha Reedijk*/
125*1e22817dSNiels Sascha Reedijk
126*1e22817dSNiels Sascha Reedijk
127*1e22817dSNiels Sascha Reedijk/*!
128*1e22817dSNiels Sascha Reedijk	\fn void BorrowAdmin::Forfeit() noexcept
129*1e22817dSNiels Sascha Reedijk	\brief Register that the BExclusiveBorrow<T> object no longer wants to own the object.
130*1e22817dSNiels Sascha Reedijk
131*1e22817dSNiels Sascha Reedijk	This also cleans up the internal object if there is no BBorrow<T> object.
132*1e22817dSNiels Sascha Reedijk
133*1e22817dSNiels Sascha Reedijk	\since Haiku R1
134*1e22817dSNiels Sascha Reedijk*/
135*1e22817dSNiels Sascha Reedijk
136*1e22817dSNiels Sascha Reedijk
137*1e22817dSNiels Sascha Reedijk/*!
138*1e22817dSNiels Sascha Reedijk	\fn bool BorrowAdmin::IsBorrowed() noexcept
139*1e22817dSNiels Sascha Reedijk	\brief Check if the current object is borrowed.
140*1e22817dSNiels Sascha Reedijk
141*1e22817dSNiels Sascha Reedijk	\since Haiku R1
142*1e22817dSNiels Sascha Reedijk*/
143*1e22817dSNiels Sascha Reedijk
144*1e22817dSNiels Sascha Reedijk
145*1e22817dSNiels Sascha Reedijk/*!
146*1e22817dSNiels Sascha Reedijk	\fn void BorrowAdmin::Release()
147*1e22817dSNiels Sascha Reedijk	\brief Cleanup the BorrowAdmin object without cleaning up the underlying object.
148*1e22817dSNiels Sascha Reedijk
149*1e22817dSNiels Sascha Reedijk	This method is called by BExclusiveBorrow<T>::Release(), where the smart pointer is emptied and
150*1e22817dSNiels Sascha Reedijk	the ownership of the object is transferred to the caller.
151*1e22817dSNiels Sascha Reedijk
152*1e22817dSNiels Sascha Reedijk	\exception BBorrowError The ownership cannot be released if the object is borrowed.
153*1e22817dSNiels Sascha Reedijk
154*1e22817dSNiels Sascha Reedijk	\since Haiku R1
155*1e22817dSNiels Sascha Reedijk*/
156*1e22817dSNiels Sascha Reedijk
157*1e22817dSNiels Sascha Reedijk
158*1e22817dSNiels Sascha Reedijk/*!
159*1e22817dSNiels Sascha Reedijk	\class BorrowPointer
160*1e22817dSNiels Sascha Reedijk	\ingroup netservices
161*1e22817dSNiels Sascha Reedijk	\brief Type derived from BorrowAdmin, which administrates the type-specific pointer.
162*1e22817dSNiels Sascha Reedijk
163*1e22817dSNiels Sascha Reedijk	In order to accomplish type erasure in BExclusiveBorrow and BBorrow, this derived type handles
164*1e22817dSNiels Sascha Reedijk	the actual owned pointer.
165*1e22817dSNiels Sascha Reedijk
166*1e22817dSNiels Sascha Reedijk	\tparam T The type of the object that the BExclusiveBorrow<T> instance owns.
167*1e22817dSNiels Sascha Reedijk
168*1e22817dSNiels Sascha Reedijk	\since Haiku R1
169*1e22817dSNiels Sascha Reedijk*/
170*1e22817dSNiels Sascha Reedijk
171*1e22817dSNiels Sascha Reedijk
172*1e22817dSNiels Sascha Reedijk/*!
173*1e22817dSNiels Sascha Reedijk	\fn BorrowPointer<T>::BorrowPointer(T* object) noexcept
174*1e22817dSNiels Sascha Reedijk	\brief Construct a new admin block to manage the \a object.
175*1e22817dSNiels Sascha Reedijk
176*1e22817dSNiels Sascha Reedijk	\since Haiku R1
177*1e22817dSNiels Sascha Reedijk*/
178*1e22817dSNiels Sascha Reedijk
179*1e22817dSNiels Sascha Reedijk
180*1e22817dSNiels Sascha Reedijk/*!
181*1e22817dSNiels Sascha Reedijk	\fn BorrowPointer<T>::~BorrowPointer()
182*1e22817dSNiels Sascha Reedijk	\brief Destructor that deletes the owned object.
183*1e22817dSNiels Sascha Reedijk
184*1e22817dSNiels Sascha Reedijk	\since Haiku R1
185*1e22817dSNiels Sascha Reedijk*/
186*1e22817dSNiels Sascha Reedijk
187*1e22817dSNiels Sascha Reedijk
188*1e22817dSNiels Sascha Reedijk/*!
189*1e22817dSNiels Sascha Reedijk	\fn virtual void BorrowPointer<T>::Cleanup() noexcept override
190*1e22817dSNiels Sascha Reedijk	\brief Implementation of the Cleanup() hook function to delete the admin block and free
191*1e22817dSNiels Sascha Reedijk		resources.
192*1e22817dSNiels Sascha Reedijk
193*1e22817dSNiels Sascha Reedijk	\since Haiku R1
194*1e22817dSNiels Sascha Reedijk*/
195*1e22817dSNiels Sascha Reedijk
196*1e22817dSNiels Sascha Reedijk
197*1e22817dSNiels Sascha Reedijk/*!
198*1e22817dSNiels Sascha Reedijk	\fn virtual void BorrowPointer<T>::ReleasePointer() noexcept override
199*1e22817dSNiels Sascha Reedijk	\brief Implementation of the ReleasePointer() hook function to make sure that the pointer
200*1e22817dSNiels Sascha Reedijk		will not be freed when the object is destroyed.
201*1e22817dSNiels Sascha Reedijk
202*1e22817dSNiels Sascha Reedijk	\since Haiku R1
203*1e22817dSNiels Sascha Reedijk*/
204*1e22817dSNiels Sascha Reedijk
205*1e22817dSNiels Sascha Reedijk
206*1e22817dSNiels Sascha Reedijk//! \endcond
207*1e22817dSNiels Sascha Reedijk
208*1e22817dSNiels Sascha Reedijk
209*1e22817dSNiels Sascha Reedijk/*!
210*1e22817dSNiels Sascha Reedijk	\class BExclusiveBorrow
211*1e22817dSNiels Sascha Reedijk	\ingroup netservices
212*1e22817dSNiels Sascha Reedijk	\brief Smart pointer that allows shared ownership of an object with exclusive access.
213*1e22817dSNiels Sascha Reedijk
214*1e22817dSNiels Sascha Reedijk	This smart pointer was designed to support the particular pattern where a non-threadsafe or
215*1e22817dSNiels Sascha Reedijk	non-lockable needs to be shared between two threads, where only one can have access to the
216*1e22817dSNiels Sascha Reedijk	underlying object at the time.
217*1e22817dSNiels Sascha Reedijk
218*1e22817dSNiels Sascha Reedijk	When creating a new object, the underlying object can be accessed using the dereference
219*1e22817dSNiels Sascha Reedijk	operator overloads as if with any other smart pointer. This ownership can then be borrowed
220*1e22817dSNiels Sascha Reedijk	by creating a \ref BBorrow object. At that stage, the original owner can no longer access the
221*1e22817dSNiels Sascha Reedijk	underlying object, until the borrow is returned. The borrow can access the object as long as
222*1e22817dSNiels Sascha Reedijk	they retain the borrow. The borrow is returned by the borrow object going out of scope, or by
223*1e22817dSNiels Sascha Reedijk	the borrow object being assigned a \c nullptr object. At that stage, the original owner regains
224*1e22817dSNiels Sascha Reedijk	access.
225*1e22817dSNiels Sascha Reedijk
226*1e22817dSNiels Sascha Reedijk	\code
227*1e22817dSNiels Sascha Reedijk	// Create a newly owned string object.
228*1e22817dSNiels Sascha Reedijk	BExclusiveBorrow<BString> owner = make_exclusive_borrow<BString>("Initial value");
229*1e22817dSNiels Sascha Reedijk
230*1e22817dSNiels Sascha Reedijk	// Access the exclusively accessibe object and set it to a different value
231*1e22817dSNiels Sascha Reedijk	owner->SetTo("New value set by owner");
232*1e22817dSNiels Sascha Reedijk
233*1e22817dSNiels Sascha Reedijk	// Create a borrow.
234*1e22817dSNiels Sascha Reedijk	BBorrow<BString> borrow = BBorrow<BString>(owner);
235*1e22817dSNiels Sascha Reedijk
236*1e22817dSNiels Sascha Reedijk	try {
237*1e22817dSNiels Sascha Reedijk		owner->SetTo("Another value set by owner");
238*1e22817dSNiels Sascha Reedijk	} catch (const BorrowError& e) {
239*1e22817dSNiels Sascha Reedijk		// This error will be thrown because the `owner` cannot access the object while borrowed.
240*1e22817dSNiels Sascha Reedijk	}
241*1e22817dSNiels Sascha Reedijk
242*1e22817dSNiels Sascha Reedijk	try {
243*1e22817dSNiels Sascha Reedijk		BBorrow<BString> secondBorrow = BBorrow<BString>(owner);
244*1e22817dSNiels Sascha Reedijk	} catch (const BorrowError& e) {
245*1e22817dSNiels Sascha Reedijk		// This error will be thrown because there cannot be more than one borrow at a time.
246*1e22817dSNiels Sascha Reedijk	}
247*1e22817dSNiels Sascha Reedijk
248*1e22817dSNiels Sascha Reedijk	// The `borrow` has exclusive access to the underlying BString object
249*1e22817dSNiels Sascha Reedijk	borrow->SetTo("A value set by the borrower");
250*1e22817dSNiels Sascha Reedijk
251*1e22817dSNiels Sascha Reedijk	// The borrow is returned by explicitly setting it to `nullptr` or by having the object go out
252*1e22817dSNiels Sascha Reedijk	// of scope.
253*1e22817dSNiels Sascha Reedijk	borrow = nullptr;
254*1e22817dSNiels Sascha Reedijk
255*1e22817dSNiels Sascha Reedijk	// The owner can access the object again
256*1e22817dSNiels Sascha Reedijk	assert(*owner == "A value set by the borrower");
257*1e22817dSNiels Sascha Reedijk	\endcode
258*1e22817dSNiels Sascha Reedijk
259*1e22817dSNiels Sascha Reedijk	\par Object Lifetime Management
260*1e22817dSNiels Sascha Reedijk	The BExclusiveBorrow and BBorrow pair manage the lifetime of the underlying object, meaning
261*1e22817dSNiels Sascha Reedijk	the memory will be freed when the object is no longer referenced by either the owner or the
262*1e22817dSNiels Sascha Reedijk	borrower. It is possible to get the ownership of the underlying object through the
263*1e22817dSNiels Sascha Reedijk	\ref BExclusiveBorrow::Release() method. This returns a \c unique_ptr.
264*1e22817dSNiels Sascha Reedijk
265*1e22817dSNiels Sascha Reedijk	\par Creating New Objects
266*1e22817dSNiels Sascha Reedijk	When creating a BExclusiveBorrow object, you can use the \ref BExclusiveBorrow(T* object)
267*1e22817dSNiels Sascha Reedijk	constructor to create a new smart pointer that takes an \em existing underlying object. Note
268*1e22817dSNiels Sascha Reedijk	that the smart pointer will assume ownership, meaning that you should also have ownership of
269*1e22817dSNiels Sascha Reedijk	that object. If you want to create a BExclusiveBorrow object for a new object, then you can use
270*1e22817dSNiels Sascha Reedijk	the \ref make_exclusive_borrow() function to create a new object.
271*1e22817dSNiels Sascha Reedijk
272*1e22817dSNiels Sascha Reedijk	\par Move Semantics and Empty Objects
273*1e22817dSNiels Sascha Reedijk	The template class is designed around having an underlying object value, and in most cases will
274*1e22817dSNiels Sascha Reedijk	have an underlying object. However, there may be cases where a BExclusiveOwner or BBorrow
275*1e22817dSNiels Sascha Reedijk	object will not have an internal value. This either happens when it is explicitly assigned an
276*1e22817dSNiels Sascha Reedijk	empty value, or after the object has been moved. You can check whether the object has a value
277*1e22817dSNiels Sascha Reedijk	through the \ref HasValue() method. Trying to access an empty object will throw a
278*1e22817dSNiels Sascha Reedijk	\ref BBorrowError.
279*1e22817dSNiels Sascha Reedijk
280*1e22817dSNiels Sascha Reedijk	\par Checked Access
281*1e22817dSNiels Sascha Reedijk	The semantics of the exclusive ownership are enforced by this class. The rules are:
282*1e22817dSNiels Sascha Reedijk	 - There can only be one owner. The object cannot be copied, only moved.
283*1e22817dSNiels Sascha Reedijk	 - There can only be one borrower at a time. The borrow object cannot be copied, only moved.
284*1e22817dSNiels Sascha Reedijk	 - If one tries to create an additional borrow, an exception is thrown.
285*1e22817dSNiels Sascha Reedijk	 - If an object is borrowed, accessing it through the owner will throw exceptions.
286*1e22817dSNiels Sascha Reedijk
287*1e22817dSNiels Sascha Reedijk	\par Casting Pointers between Owner and Borrower
288*1e22817dSNiels Sascha Reedijk	For some design patterns, you may want to be able to cast the type of the owner to a related
289*1e22817dSNiels Sascha Reedijk	type for the borrower. For example, the Network Services kit accepts a \c BBorrow<BDataIO> type
290*1e22817dSNiels Sascha Reedijk	in order to allow the user to specify where to write the content of a network request to. The
291*1e22817dSNiels Sascha Reedijk	\ref BDataIO itself is an abstract interface to read and write data from an object. A user
292*1e22817dSNiels Sascha Reedijk	will most likely use a \ref BFile or \ref BMallocIO as underlying objects, both of which
293*1e22817dSNiels Sascha Reedijk	have \ref BDataIO as their base class.
294*1e22817dSNiels Sascha Reedijk
295*1e22817dSNiels Sascha Reedijk	\par
296*1e22817dSNiels Sascha Reedijk	Due to the specialized constructor of \ref BBorrow, it is possible to cast between compatible
297*1e22817dSNiels Sascha Reedijk	pointer types, without loosing the advantages of properly cleaning up the object when the
298*1e22817dSNiels Sascha Reedijk	borrow and the owner go out of scope. In the internals of the template, a type erasure
299*1e22817dSNiels Sascha Reedijk	technique similar to that of \c std::shared_ptr is used.
300*1e22817dSNiels Sascha Reedijk
301*1e22817dSNiels Sascha Reedijk	\code
302*1e22817dSNiels Sascha Reedijk	// Create a new BFile object, which inherits the BDataIO class.
303*1e22817dSNiels Sascha Reedijk	BExclusiveBorrow<BFile> owner = make_exclusive_borrow<BFile>("path/to/file", B_READ_WRITE);
304*1e22817dSNiels Sascha Reedijk	// The following succeeds because a BFile pointer can be assigned to a BDataIO pointer.
305*1e22817dSNiels Sascha Reedijk	BBorrow<BDataIO> borrow = BBorrow<BDataIO>(owner);
306*1e22817dSNiels Sascha Reedijk	\endcode
307*1e22817dSNiels Sascha Reedijk
308*1e22817dSNiels Sascha Reedijk	\par Multithread Safety, and Performance Cost
309*1e22817dSNiels Sascha Reedijk	This smart object uses atomics to synchronize the ownership and borrows of the object, and to
310*1e22817dSNiels Sascha Reedijk	enforce all the checks that were mentioned previously. The atomics guarantee that when you
311*1e22817dSNiels Sascha Reedijk	want to access the object in BExclusiveBorrow, that this only succeeds after any outstanding
312*1e22817dSNiels Sascha Reedijk	borrow is completed, otherwise an exception is thrown. While atomics can be used as a method of
313*1e22817dSNiels Sascha Reedijk	synchronization, this templace class is \em not designed for that and it does not have the
314*1e22817dSNiels Sascha Reedijk	tools to help doing that. If you need to synchronize object access between through threads, you
315*1e22817dSNiels Sascha Reedijk	should use semaphores or thread joins instead.
316*1e22817dSNiels Sascha Reedijk
317*1e22817dSNiels Sascha Reedijk	\tparam T The type of object for this smart pointer.
318*1e22817dSNiels Sascha Reedijk
319*1e22817dSNiels Sascha Reedijk	\since Haiku R1
320*1e22817dSNiels Sascha Reedijk*/
321*1e22817dSNiels Sascha Reedijk
322*1e22817dSNiels Sascha Reedijk/*!
323*1e22817dSNiels Sascha Reedijk	\fn BExclusiveBorrow<T>::BExclusiveBorrow() noexcept
324*1e22817dSNiels Sascha Reedijk	\brief Create a new smart pointer with no value.
325*1e22817dSNiels Sascha Reedijk
326*1e22817dSNiels Sascha Reedijk	\since Haiku R1
327*1e22817dSNiels Sascha Reedijk*/
328*1e22817dSNiels Sascha Reedijk
329*1e22817dSNiels Sascha Reedijk
330*1e22817dSNiels Sascha Reedijk/*!
331*1e22817dSNiels Sascha Reedijk	\fn BExclusiveBorrow<T>::BExclusiveBorrow(nullptr_t) noexcept
332*1e22817dSNiels Sascha Reedijk	\brief Special constructor that creates a new smart pointer with no value.
333*1e22817dSNiels Sascha Reedijk
334*1e22817dSNiels Sascha Reedijk	\since Haiku R1
335*1e22817dSNiels Sascha Reedijk*/
336*1e22817dSNiels Sascha Reedijk
337*1e22817dSNiels Sascha Reedijk
338*1e22817dSNiels Sascha Reedijk/*!
339*1e22817dSNiels Sascha Reedijk	\fn BExclusiveBorrow<T>::BExclusiveBorrow(T* object)
340*1e22817dSNiels Sascha Reedijk	\brief Create a new smart pointer that takes ownership of the \a object.
341*1e22817dSNiels Sascha Reedijk
342*1e22817dSNiels Sascha Reedijk	\param object The object to wrap inside this smart pointer.
343*1e22817dSNiels Sascha Reedijk
344*1e22817dSNiels Sascha Reedijk	\exception std::bad_alloc In case there are issues allocating memory for the internals of
345*1e22817dSNiels Sascha Reedijk		the smart pointer.
346*1e22817dSNiels Sascha Reedijk
347*1e22817dSNiels Sascha Reedijk	\since Haiku R1
348*1e22817dSNiels Sascha Reedijk*/
349*1e22817dSNiels Sascha Reedijk
350*1e22817dSNiels Sascha Reedijk
351*1e22817dSNiels Sascha Reedijk/*!
352*1e22817dSNiels Sascha Reedijk	\fn BExclusiveBorrow<T>::~BExclusiveBorrow()
353*1e22817dSNiels Sascha Reedijk	\brief Destructor.
354*1e22817dSNiels Sascha Reedijk
355*1e22817dSNiels Sascha Reedijk	If the smart pointer is not empty, the underlying object will be deleted if there no longer
356*1e22817dSNiels Sascha Reedijk	is a borrow accessing it.
357*1e22817dSNiels Sascha Reedijk
358*1e22817dSNiels Sascha Reedijk	\since Haiku R1
359*1e22817dSNiels Sascha Reedijk*/
360*1e22817dSNiels Sascha Reedijk
361*1e22817dSNiels Sascha Reedijk
362*1e22817dSNiels Sascha Reedijk/*!
363*1e22817dSNiels Sascha Reedijk	\fn BExclusiveBorrow<T>::BExclusiveBorrow(BExclusiveBorrow&& other) noexcept
364*1e22817dSNiels Sascha Reedijk	\brief Move constructor.
365*1e22817dSNiels Sascha Reedijk
366*1e22817dSNiels Sascha Reedijk	\param other The object to move from. It will be left empty after the move.
367*1e22817dSNiels Sascha Reedijk
368*1e22817dSNiels Sascha Reedijk	\since Haiku R1
369*1e22817dSNiels Sascha Reedijk*/
370*1e22817dSNiels Sascha Reedijk
371*1e22817dSNiels Sascha Reedijk
372*1e22817dSNiels Sascha Reedijk/*!
373*1e22817dSNiels Sascha Reedijk	\fn BExclusiveBorrow& BExclusiveBorrow<T>::operator=(BExclusiveBorrow&& other) noexcept
374*1e22817dSNiels Sascha Reedijk	\brief Move assignment.
375*1e22817dSNiels Sascha Reedijk
376*1e22817dSNiels Sascha Reedijk	\param other The object to move from. It will be left empty after the move.
377*1e22817dSNiels Sascha Reedijk
378*1e22817dSNiels Sascha Reedijk	\since Haiku R1
379*1e22817dSNiels Sascha Reedijk*/
380*1e22817dSNiels Sascha Reedijk
381*1e22817dSNiels Sascha Reedijk
382*1e22817dSNiels Sascha Reedijk/*!
383*1e22817dSNiels Sascha Reedijk	\fn bool BExclusiveBorrow<T>::HasValue() const noexcept
384*1e22817dSNiels Sascha Reedijk	\brief Check if the object has a value or is empty.
385*1e22817dSNiels Sascha Reedijk
386*1e22817dSNiels Sascha Reedijk	\since Haiku R1
387*1e22817dSNiels Sascha Reedijk*/
388*1e22817dSNiels Sascha Reedijk
389*1e22817dSNiels Sascha Reedijk
390*1e22817dSNiels Sascha Reedijk/*!
391*1e22817dSNiels Sascha Reedijk	\fn T& BExclusiveBorrow<T>::operator*() const
392*1e22817dSNiels Sascha Reedijk	\brief Dereferences the pointer.
393*1e22817dSNiels Sascha Reedijk
394*1e22817dSNiels Sascha Reedijk	\exception BBorrowError This exception is raised if the object is borrowed, or if it is empty.
395*1e22817dSNiels Sascha Reedijk
396*1e22817dSNiels Sascha Reedijk	\since Haiku R1
397*1e22817dSNiels Sascha Reedijk*/
398*1e22817dSNiels Sascha Reedijk
399*1e22817dSNiels Sascha Reedijk
400*1e22817dSNiels Sascha Reedijk/*!
401*1e22817dSNiels Sascha Reedijk	\fn T* BExclusiveBorrow<T>::operator->() const
402*1e22817dSNiels Sascha Reedijk	\brief Dereferences the pointer.
403*1e22817dSNiels Sascha Reedijk
404*1e22817dSNiels Sascha Reedijk	\exception BBorrowError This exception is raised if the object is borrowed, or if it is empty.
405*1e22817dSNiels Sascha Reedijk
406*1e22817dSNiels Sascha Reedijk	\since Haiku R1
407*1e22817dSNiels Sascha Reedijk*/
408*1e22817dSNiels Sascha Reedijk
409*1e22817dSNiels Sascha Reedijk
410*1e22817dSNiels Sascha Reedijk/*!
411*1e22817dSNiels Sascha Reedijk	\fn std::unique_ptr<T> BExclusiveBorrow<T>::Release()
412*1e22817dSNiels Sascha Reedijk	\brief Returns a unique_ptr of the inner object and releases the ownership.
413*1e22817dSNiels Sascha Reedijk
414*1e22817dSNiels Sascha Reedijk	\exception BBorrowError This exception is raised if the object is borrowed, or if it is empty.
415*1e22817dSNiels Sascha Reedijk
416*1e22817dSNiels Sascha Reedijk	\since Haiku R1
417*1e22817dSNiels Sascha Reedijk*/
418*1e22817dSNiels Sascha Reedijk
419*1e22817dSNiels Sascha Reedijk
420*1e22817dSNiels Sascha Reedijk/*!
421*1e22817dSNiels Sascha Reedijk	\class BBorrow
422*1e22817dSNiels Sascha Reedijk	\ingroup netservices
423*1e22817dSNiels Sascha Reedijk	\brief Smart pointer that borrows an object from a \ref BExclusiveBorrow owner.
424*1e22817dSNiels Sascha Reedijk
425*1e22817dSNiels Sascha Reedijk	The BBorrow smart pointer is the accompanyment to the \ref BExclusiveBorrow owner object. See
426*1e22817dSNiels Sascha Reedijk	the documentation on that template class on how to use the smart pointer pairs to express and
427*1e22817dSNiels Sascha Reedijk	enforce exclusive ownership between the owner and the borrower.
428*1e22817dSNiels Sascha Reedijk
429*1e22817dSNiels Sascha Reedijk	Like a BExclusiveBorrow object, a BBorrow object can either have a borrow or be empty. When it
430*1e22817dSNiels Sascha Reedijk	is empty, it means the current object is not borrowing anything at that moment. Any calls to
431*1e22817dSNiels Sascha Reedijk	access the underlying data will fail in that case.
432*1e22817dSNiels Sascha Reedijk
433*1e22817dSNiels Sascha Reedijk	\tparam T The type of object that is owned by this smart pointer.
434*1e22817dSNiels Sascha Reedijk
435*1e22817dSNiels Sascha Reedijk	\since Haiku R1
436*1e22817dSNiels Sascha Reedijk*/
437*1e22817dSNiels Sascha Reedijk
438*1e22817dSNiels Sascha Reedijk
439*1e22817dSNiels Sascha Reedijk/*!
440*1e22817dSNiels Sascha Reedijk	\fn BBorrow<T>::BBorrow() noexcept
441*1e22817dSNiels Sascha Reedijk	\brief Create a new smart pointer with no value.
442*1e22817dSNiels Sascha Reedijk
443*1e22817dSNiels Sascha Reedijk	\since Haiku R1
444*1e22817dSNiels Sascha Reedijk*/
445*1e22817dSNiels Sascha Reedijk
446*1e22817dSNiels Sascha Reedijk
447*1e22817dSNiels Sascha Reedijk/*!
448*1e22817dSNiels Sascha Reedijk	\fn BBorrow<T>::BBorrow(nullptr_t) noexcept
449*1e22817dSNiels Sascha Reedijk	\brief Special constructor that builds an empty borrow object.
450*1e22817dSNiels Sascha Reedijk
451*1e22817dSNiels Sascha Reedijk	\since Haiku R1
452*1e22817dSNiels Sascha Reedijk*/
453*1e22817dSNiels Sascha Reedijk
454*1e22817dSNiels Sascha Reedijk
455*1e22817dSNiels Sascha Reedijk/*!
456*1e22817dSNiels Sascha Reedijk	\fn BBorrow<T>::BBorrow(BExclusiveBorrow<P>& owner)
457*1e22817dSNiels Sascha Reedijk	\brief Construct a borrowed object from the \a owner.
458*1e22817dSNiels Sascha Reedijk
459*1e22817dSNiels Sascha Reedijk	\param owner The owner to borrow from.
460*1e22817dSNiels Sascha Reedijk
461*1e22817dSNiels Sascha Reedijk	\exception BBorrowError In case the \a owner already borrowed their object, or in case the
462*1e22817dSNiels Sascha Reedijk		\a owner is an empty object, as you cannot borrow something that is not there.
463*1e22817dSNiels Sascha Reedijk
464*1e22817dSNiels Sascha Reedijk	\tparam T The type of object for this BBorrow object.
465*1e22817dSNiels Sascha Reedijk	\tparam P The type of objedt for the BExclusiveBorrow object. This allows you to have different
466*1e22817dSNiels Sascha Reedijk		types between the owner and the borrower, with the requirement that a pointer to type P can
467*1e22817dSNiels Sascha Reedijk		be cast to a pointer of type T without issue.
468*1e22817dSNiels Sascha Reedijk
469*1e22817dSNiels Sascha Reedijk	\since Haiku R1
470*1e22817dSNiels Sascha Reedijk*/
471*1e22817dSNiels Sascha Reedijk
472*1e22817dSNiels Sascha Reedijk
473*1e22817dSNiels Sascha Reedijk/*!
474*1e22817dSNiels Sascha Reedijk	\fn BBorrow<T>::BBorrow(BBorrow&& other) noexcept
475*1e22817dSNiels Sascha Reedijk	\brief Move constructor.
476*1e22817dSNiels Sascha Reedijk
477*1e22817dSNiels Sascha Reedijk	\param other The object to move from. It will be left empty after the move.
478*1e22817dSNiels Sascha Reedijk
479*1e22817dSNiels Sascha Reedijk	\since Haiku R1
480*1e22817dSNiels Sascha Reedijk*/
481*1e22817dSNiels Sascha Reedijk
482*1e22817dSNiels Sascha Reedijk
483*1e22817dSNiels Sascha Reedijk/*!
484*1e22817dSNiels Sascha Reedijk	\fn BBorrow& BBorrow<T>::operator=(BBorrow&& other) noexcept
485*1e22817dSNiels Sascha Reedijk	\brief Move assignment.
486*1e22817dSNiels Sascha Reedijk
487*1e22817dSNiels Sascha Reedijk	\param other The object to move from. It will be left empty after the move.
488*1e22817dSNiels Sascha Reedijk
489*1e22817dSNiels Sascha Reedijk	\since Haiku R1
490*1e22817dSNiels Sascha Reedijk*/
491*1e22817dSNiels Sascha Reedijk
492*1e22817dSNiels Sascha Reedijk
493*1e22817dSNiels Sascha Reedijk/*!
494*1e22817dSNiels Sascha Reedijk	\fn BBorrow<T>::~BBorrow()
495*1e22817dSNiels Sascha Reedijk	\brief Destructor that returns the object to the original owner.
496*1e22817dSNiels Sascha Reedijk
497*1e22817dSNiels Sascha Reedijk	If the original owner no longer exists, the underlying object will be deleted.
498*1e22817dSNiels Sascha Reedijk
499*1e22817dSNiels Sascha Reedijk	\since Haiku R1
500*1e22817dSNiels Sascha Reedijk*/
501*1e22817dSNiels Sascha Reedijk
502*1e22817dSNiels Sascha Reedijk
503*1e22817dSNiels Sascha Reedijk/*!
504*1e22817dSNiels Sascha Reedijk	\fn bool BBorrow<T>::HasValue() const noexcept
505*1e22817dSNiels Sascha Reedijk	\brief Check if the object has a value or is empty.
506*1e22817dSNiels Sascha Reedijk
507*1e22817dSNiels Sascha Reedijk	\since Haiku R1
508*1e22817dSNiels Sascha Reedijk*/
509*1e22817dSNiels Sascha Reedijk
510*1e22817dSNiels Sascha Reedijk
511*1e22817dSNiels Sascha Reedijk/*!
512*1e22817dSNiels Sascha Reedijk	\fn T& BBorrow<T>::operator*() const
513*1e22817dSNiels Sascha Reedijk	\brief Dereference operator.
514*1e22817dSNiels Sascha Reedijk
515*1e22817dSNiels Sascha Reedijk	\exception BBorrowError When the smart pointer is empty and there is no object to access.
516*1e22817dSNiels Sascha Reedijk
517*1e22817dSNiels Sascha Reedijk	\since Haiku R1
518*1e22817dSNiels Sascha Reedijk*/
519*1e22817dSNiels Sascha Reedijk
520*1e22817dSNiels Sascha Reedijk
521*1e22817dSNiels Sascha Reedijk/*!
522*1e22817dSNiels Sascha Reedijk	\fn T* BBorrow<T>::operator->() const
523*1e22817dSNiels Sascha Reedijk	\brief Dereference operator.
524*1e22817dSNiels Sascha Reedijk
525*1e22817dSNiels Sascha Reedijk	\exception BBorrowError When the smart pointer is empty and there is no object to access.
526*1e22817dSNiels Sascha Reedijk
527*1e22817dSNiels Sascha Reedijk	\since Haiku R1
528*1e22817dSNiels Sascha Reedijk*/
529*1e22817dSNiels Sascha Reedijk
530*1e22817dSNiels Sascha Reedijk
531*1e22817dSNiels Sascha Reedijk/*!
532*1e22817dSNiels Sascha Reedijk	\fn void BBorrow<T>::Return() noexcept
533*1e22817dSNiels Sascha Reedijk	\brief Return object to the owner.
534*1e22817dSNiels Sascha Reedijk
535*1e22817dSNiels Sascha Reedijk	The current object will be set to be an empty object after this call. If the object is already
536*1e22817dSNiels Sascha Reedijk	empty, this call will not do anything. If the owner no longer exists, the object will be
537*1e22817dSNiels Sascha Reedijk	disposed off.
538*1e22817dSNiels Sascha Reedijk
539*1e22817dSNiels Sascha Reedijk	\since Haiku R1
540*1e22817dSNiels Sascha Reedijk*/
541*1e22817dSNiels Sascha Reedijk
542*1e22817dSNiels Sascha Reedijk
543*1e22817dSNiels Sascha Reedijk/*!
544*1e22817dSNiels Sascha Reedijk	\fn BExclusiveBorrow<T> make_exclusive_borrow(_Args&& ...__args)
545*1e22817dSNiels Sascha Reedijk	\ingroup netservices
546*1e22817dSNiels Sascha Reedijk	\brief Create a new object that is managed by a BExclusiveBorrow smart pointer.
547*1e22817dSNiels Sascha Reedijk
548*1e22817dSNiels Sascha Reedijk	This is a convenience template function to the likes of \c std::make_unique(). It allows you to
549*1e22817dSNiels Sascha Reedijk	directly create the \ref BExclusiveBorrow smart pointer around a newly allocated object.
550*1e22817dSNiels Sascha Reedijk
551*1e22817dSNiels Sascha Reedijk	\tparam T The type of the object that will be created.
552*1e22817dSNiels Sascha Reedijk	\tparam _Args Arguments to be passed to the constructor of T.
553*1e22817dSNiels Sascha Reedijk
554*1e22817dSNiels Sascha Reedijk	\exception std::bad_alloc In case there are issues allocating the new object.
555*1e22817dSNiels Sascha Reedijk	\exception ... Any other exception that is thrown by the constructor of the object T.
556*1e22817dSNiels Sascha Reedijk
557*1e22817dSNiels Sascha Reedijk	\since Haiku R1
558*1e22817dSNiels Sascha Reedijk*/
559*1e22817dSNiels Sascha Reedijk
560*1e22817dSNiels Sascha Reedijk
561*1e22817dSNiels Sascha Reedijk} // namespace Network
562*1e22817dSNiels Sascha Reedijk
563*1e22817dSNiels Sascha Reedijk} // namespace BPrivate
564*1e22817dSNiels Sascha Reedijk
565*1e22817dSNiels Sascha Reedijk# endif
566