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