ALib C++ Framework
by
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
owner.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_lang of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under #"mainpage_license".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace lang {
9
10/// Ensures that an object of template type \p{TOwnable} is acquired and properly released when
11/// unwinding the stack (\https{RAII idiom,https://en.cppreference.com/w/cpp/language/raii}).
12/// This class is meant to be allocated only on the stack and not on the heap.
13/// Therefore, the new operators as well as copy and move constructors and assignment operators
14/// are declared private.
15///
16/// With debug-builds, the constructor expects caller source information parameters
17/// of type \b CallerInfo.
18/// Use the macro #"ALIB_CALLER_PRUNED" to prune those with release-builds.
19///
20/// In the rather unusual case that it is a run-time decision whether this object should
21/// carry an object to acquire or not, the template parameter \p{TOptional} may be set to \c true.
22/// With that, pointers are accepted with construction and method #"Set" becomes available.
23///
24/// \see
25/// - Several sibling types exist.
26/// They are described and listed in chapter #"alib_threads_locks_auto_owner" of the
27/// Programmer's Manual of module \alib_threads.
28/// - Besides generic preprocessor macro #"ALIB_OWN", several application-specific alias macros
29/// exist.
30/// For example, macros
31/// - #"ALIB_LOCK",
32/// - #"ALIB_LOCK_WITH",
33/// - #"ALIB_DCS", or
34/// - #"ALIB_DCS_WITH"
35///
36/// provide a convenient and "speaking" way to use this class.
37/// - Chapter #"alib_manual_appendix_callerinfo" of the General Programmer's Manual.
38///
39/// @tparam TOwnable The type to own.
40/// Requirements are to have methods \b %Acquire and \b %Release available.
41/// @tparam TOptional If \c true, then checks is performed, whether the given #".owned" is
42/// \e nulled and thus not acquired and released.
43/// If \c false such checks are omitted.
44template <typename TOwnable, bool TOptional= false>
45class Owner
46{
48
49 public:
50 /// The pointer type of the owned object.
51 using OwnablePointer= std::remove_reference_t<TOwnable>*;
52
53 protected:
54 OwnablePointer owned; ///< The resource to acquire and release.
55 #if ALIB_DEBUG
56 CallerInfo dbgCI; ///< Caller information. Available only with debug-builds.
57 #endif
58
59 #if !DOXYGEN
60 // choosing the right release method, with or without caller parameters.
61 #if ALIB_DEBUG
62 template<typename TRequires= TOwnable>
63 requires ( ALIB_HAS_METHOD(TRequires, Release, dbgCI))
64 void callRelease() { owned->Release(dbgCI); }
65 #endif
66
67 template<typename TRequires= TOwnable>
68 requires ( ALIB_HAS_METHOD(TRequires, Release, ))
69 void callRelease() { owned->Release(); }
70 #endif
71 public:
72
73 #if ALIB_DEBUG
74 /// Constructor. Invokes Acquire() on the ownable.
75 /// @param ownable The ownable to acquire.
76 /// @param ci Caller information.
77 Owner( TOwnable& ownable, const CallerInfo& ci)
78 : owned(&ownable)
79 , dbgCI(ci) { ownable.Acquire( ci ); }
80
81 /// Constructor taking a pointer to the ownable. This constructor is only available if
82 /// the template parameter \p{TOptional} is \c true.
83 /// @param ownable The ownable to acquire.
84 /// @param ci Caller information.
85 Owner( OwnablePointer ownable, const CallerInfo& ci)
86 requires TOptional
87 : owned(ownable)
88 , dbgCI(ci) { if (ownable != nullptr) ownable->Acquire( ci ); }
89 #else
90 Owner( TOwnable& ownable ) : owned(&ownable) { ownable.Acquire(); }
91 Owner( OwnablePointer ownable)
92 requires TOptional
93 : owned(ownable) { if (ownable != nullptr) ownable->Acquire(); }
94 #endif
95
96 /// Destructor. Releases the owner by invoking Release().
97 ~Owner() { if (!TOptional || owned) callRelease(); }
98
99 /// Sets the ownable after construction. This method is only available if the template
100 /// parameter \p{TOptional} is \c true. It must not be called if an object was given with
101 /// construction already, and it must not be called twice. If done, an assertion is raised.
102 /// @param ownable The ownable to acquire.
103 void Set(OwnablePointer ownable)
104 requires TOptional {
105 ALIB_ASSERT_ERROR(owned==nullptr, "LANG", "Owner already set.")
106 (owned= ownable)->Acquire( ALIB_DBG(dbgCI) );
107 }
108}; //class Owner
109
110/// Similar to class #"lang::Owner", but calls method \b TryAcquire instead of \b Acquire.
111/// The result is retrievable with method #".IsOwning".
112/// @see Chapter #"alib_threads_locks_auto_owner" of the Programmer's Manual of module
113/// \alib_threads
114/// @tparam TOwnable The type to own.
115/// Requirements are to have methods \b %TryAcquire and \b %Release available.
116/// @tparam TOptional If \c true, then checks is performed, whether the given #".owned" is
117/// \e nulled and thus not acquired and released.
118/// If \c false such checks are omitted.
119template <typename TOwnable, bool TOptional= false>
121{
123
124 public:
125 /// The pointer type of the owned object.
126 using OwnablePointer= std::remove_reference_t<TOwnable>*;
127
128 protected:
129 OwnablePointer owned; ///< The resource to acquire and release.
130 bool isOwning; ///< The result of the call to \b TryAcquire.
131 #if ALIB_DEBUG
132 CallerInfo dbgCI; ///< Caller information. Available only with debug-builds.
133 #endif
134
135 #if !DOXYGEN
136 // choosing the right release method, with or without caller parameters.
137 #if ALIB_DEBUG
138 template<typename TRequires= TOwnable>
139 requires ( ALIB_HAS_METHOD(TRequires, Release, dbgCI))
140 void callRelease() { if (!TOptional || owned) owned->Release(dbgCI); }
141 #endif
142
143 template<typename TRequires= TOwnable>
144 requires ( ALIB_HAS_METHOD(TRequires, Release, ))
145 void callRelease() { if (!TOptional || owned) owned->Release(); }
146
147 #if ALIB_DEBUG
148 template<typename TRequires= TOwnable>
149 requires ( ALIB_HAS_METHOD(TRequires, ReleaseRecursive, dbgCI))
150 void callRelease() { if (!TOptional || owned) owned->ReleaseRecursive(dbgCI); }
151 #endif
152
153 template<typename TRequires= TOwnable>
154 requires ( ALIB_HAS_METHOD(TRequires, ReleaseRecursive, ))
155 void callRelease() { if (!TOptional || owned) owned->ReleaseRecursive(); }
156
157 #endif
158 public:
159
160 #if ALIB_DEBUG
161 /// Constructor. Invokes TryAcquire() on member #".owned".
162 /// @param ownable The ownable to acquire.
163 /// @param ci Caller information.
164 OwnerTry( TOwnable& ownable, const CallerInfo& ci)
165 : owned(&ownable)
166 , dbgCI(ci) { isOwning= ownable.TryAcquire(ci); }
167
168 /// Constructor taking a pointer to the ownable. This constructor is only available if
169 /// the template parameter \p{TOptional} is \c true.
170 /// @param ownable The ownable to acquire.
171 /// @param ci Caller information.
172 OwnerTry( OwnablePointer ownable, const CallerInfo& ci)
173 requires TOptional
174 : owned(ownable)
175 , dbgCI(ci) { isOwning = !ownable || ownable->TryAcquire( ci ); }
176#else
177 OwnerTry( TOwnable& ownable )
178 : owned(&ownable) { isOwning= ownable.TryAcquire(); }
179 OwnerTry( OwnablePointer ownable)
180 requires TOptional
181 : owned(ownable) { isOwning = !ownable || ownable->TryAcquire(); }
182 #endif
183
184
185 /// Destructor. Invokes Release() on member #".owned".
186 ~OwnerTry() { if ((!TOptional || owned) && isOwning) callRelease(); }
187
188 /// Sets the ownable after construction. This method is only available if the template
189 /// parameter \p{TOptional} is \c true. It must not be called if an object was given with
190 /// construction already, and it must not be called twice. If done, an assertion is raised.
191 /// @param ownable The ownable to acquire.
192 /// @return \c true if the try to acquire the owner was successful, \c false if not.
193 bool Set(OwnablePointer ownable)
194 requires TOptional {
195 ALIB_ASSERT_ERROR(owned==nullptr, "LANG", "Owner already set.")
196 return isOwning= (owned= ownable)->TryAcquire( ALIB_DBG(dbgCI) );
197 }
198
199 /// @return \c true if the try to acquire the #".owned" with construction of this type was
200 /// successful. Furthermore, \c true is returned in the case that the template
201 /// parameter \p{TOptional} is \c true and no ownable was given with construction.
202 /// Otherwise, \c false is returned.
203 bool IsOwning() const noexcept { return isOwning; }
204}; //class OwnerTry
205
206/// Similar to class #"lang::Owner", but calls method \b TryAcquireTimed instead of \b Acquire.
207/// The result is retrievable with method #".IsOwning".
208/// @see Chapter #"alib_threads_locks_auto_owner" of the Programmer's Manual of module
209/// \alib_threads
210/// @tparam TOwnable The type to own.
211/// Requirements are to have methods \b %TryAcquireTimed and \b %Release
212/// available.
213/// @tparam TOptional If \c true, then checks is performed, whether the given #".owned" is
214/// \e nulled and thus not acquired and released.
215/// If \c false such checks are omitted.
216template <typename TOwnable, bool TOptional= false>
218{
220
221 public:
222 /// The pointer type of the owned object.
223 using OwnablePointer= std::remove_reference_t<TOwnable>*;
224
225 protected:
226 OwnablePointer owned; ///< The resource to acquire and release.
227 bool isOwning; ///< The result of the call to \b TryAcquire.
228 #if ALIB_DEBUG
229 CallerInfo dbgCI; ///< Caller information. Available only with debug-builds.
230 #endif
231
232 #if !DOXYGEN
233 // choosing the right release method, with or without caller parameters.
234 #if ALIB_DEBUG
235 template<typename TRequires= TOwnable>
236 requires ( ALIB_HAS_METHOD(TRequires, Release, dbgCI))
237 void callRelease() { owned->Release(dbgCI); }
238 #endif
239
240 template<typename TRequires= TOwnable>
241 requires ( ALIB_HAS_METHOD(TRequires, Release, ))
242 void callRelease() { owned->Release(); }
243
244 // choosing the right release method, with or without caller parameters.
245 #if ALIB_DEBUG
246 template<typename TRequires= TOwnable>
247 requires ( ALIB_HAS_METHOD(TRequires, ReleaseRecursive, dbgCI))
248 void callRelease() { owned->ReleaseRecursive(dbgCI); }
249 #endif
250
251 template<typename TRequires= TOwnable>
252 requires ( ALIB_HAS_METHOD(TRequires, ReleaseRecursive, ))
253 void callRelease() { owned->ReleaseRecursive(); }
254
255 #endif
256 public:
257
258 #if ALIB_DEBUG
259 /// Constructor. Invokes TryAcquire() on member #".owned".
260 /// @param ownable The ownable to acquire.
261 /// @param time The duration to wait for, or point in time to wait until.
262 /// @param ci Caller information.
263 /// @tparam TTimeValue The type of the parameter \p{time} accepted with construction and passed
264 /// to the method <b>TOwnable::TryAcquireTimed</b>.<br>
265 /// Usually this is type #"Ticks" or its inherited type #"^Ticks::Duration".
266 template<typename TTimeValue>
267 OwnerTimed( TOwnable& ownable, const TTimeValue& time, const CallerInfo& ci)
268 : owned(&ownable)
269 , dbgCI(ci) { isOwning= ownable.TryAcquireTimed( time, ci); }
270
271 /// Constructor taking a pointer to the ownable. This constructor is only available if
272 /// the template parameter \p{TOptional} is \c true.
273 /// @param ownable The ownable to acquire.
274 /// @param time The duration to wait for, or point in time to wait until.
275 /// @param ci Caller information.
276 /// @tparam TTimeValue The type of the parameter \p{time} accepted with construction and passed
277 /// to the method <b>TOwnable::TryAcquireTimed</b>.<br>
278 /// Usually this is type #"Ticks" or its inherited type #"^Ticks::Duration".
279 template<typename TTimeValue>
280 requires TOptional
281 OwnerTimed( OwnablePointer ownable, const TTimeValue& time, const CallerInfo& ci)
282 : owned(ownable)
283 , dbgCI(ci) { isOwning = !ownable || ownable->TryAcquireTimed( time, ci ); }
284 #else
285 template<typename TTimeValue>
286 OwnerTimed( TOwnable& ownable, const TTimeValue& time )
287 : owned(&ownable) { isOwning= ownable.TryAcquireTimed( time ); }
288
289 template<typename TTimeValue>
290 requires TOptional
291 OwnerTimed( OwnablePointer ownable, const TTimeValue& time)
292 : owned(ownable) { isOwning = !ownable || ownable->TryAcquireTimed(time); }
293 #endif
294
295
296 /// Destructor. Invokes Release() on member #".owned".
297 ~OwnerTimed() { if ((!TOptional || owned) && isOwning) callRelease(); }
298
299 /// Sets the ownable after construction. This method is only available if the template
300 /// parameter \p{TOptional} is \c true. It must not be called if an object was given with
301 /// construction already, and it must not be called twice. If done, an assertion is raised.
302 /// @param ownable The ownable to acquire.
303 /// @param time The duration to wait for, or point in time to wait until.
304 /// @tparam TTimeValue The type of the parameter \p{time} accepted with construction and passed
305 /// to the method <b>TOwnable::TryAcquireTimed</b>.<br>
306 /// Usually this is type #"Ticks" or its inherited type #"^Ticks::Duration".
307 /// @return \c true if the try to acquire the owner was successful, \c false if not.
308 template<typename TTimeValue>
309 requires TOptional
310 bool Set(OwnablePointer ownable, const TTimeValue& time) {
311 ALIB_ASSERT_ERROR(owned==nullptr, "LANG", "Owner already set.")
312 return isOwning= (owned= ownable)->TryAcquireTimed( time ALIB_DBG(, dbgCI) );
313 }
314
315 /// @return \c true if the try to acquire the #owned with construction of this type was
316 /// successful. Furthermore, \c true is returned in the case that the template
317 /// parameter \p{TOptional} is \c true and no ownable was given with construction.
318 /// Otherwise, \c false is returned.
319 bool IsOwning() const noexcept { return isOwning; }
320}; //class OwnerTimed
321
322
323/// Similar to class #"lang::Owner", but calls methods \b AcquireRecursive and
324/// \b ReleaseRecursive.
325/// @see Chapter #"alib_threads_locks_auto_owner" of the Programmer's Manual of module
326/// \alib_threads
327/// @tparam TOwnable The type to own.
328/// Requirements are to have methods \b %AcquireRecursive and \b %ReleaseRecursive
329/// available.
330/// @tparam TOptional If \c true, then checks is performed, whether the given #owned is
331/// \e nulled and thus not acquired and released.
332/// If \c false such checks are omitted.
333template <typename TOwnable, bool TOptional= false>
335{
337
338 public:
339 /// The pointer type of the owned object.
340 using OwnablePointer= std::remove_reference_t<TOwnable>*;
341
342 protected:
343 OwnablePointer owned; ///< The resource to acquire and release.
344 #if ALIB_DEBUG
345 CallerInfo dbgCI; ///< Caller information. Available only with debug-builds.
346 #endif
347
348 #if !DOXYGEN
349 // choosing the right release method, with or without caller parameters.
350 #if ALIB_DEBUG
351 template<typename TRequires= TOwnable>
352 requires ( ALIB_HAS_METHOD(TRequires, ReleaseRecursive,dbgCI))
353 void callRelease() { owned->ReleaseRecursive(dbgCI); }
354 #endif
355
356 template<typename TRequires= TOwnable>
357 requires ( ALIB_HAS_METHOD(TRequires, ReleaseRecursive, ))
358 void callRelease() { owned->ReleaseRecursive(); }
359 #endif
360 public:
361
362 #if ALIB_DEBUG
363 /// Constructor. Invokes AcquireRecursive() on member #owned.
364 /// @param ownable The ownable to acquire.
365 /// @param ci Caller information.
366 OwnerRecursive( TOwnable& ownable, const CallerInfo& ci)
367 : owned(&ownable)
368 , dbgCI(ci) { ownable.AcquireRecursive(ci); }
369
370 /// Constructor taking a pointer to the ownable. This constructor is only available if
371 /// the template parameter \p{TOptional} is \c true.
372 /// @param ownable The ownable to acquire.
373 /// @param ci Caller information.
375 requires TOptional
376 : owned(ownable)
377 , dbgCI(ci) { if (ownable != nullptr) ownable->AcquireRecursive( ci ); }
378 #else
379 OwnerRecursive( TOwnable& ownable ) : owned(&ownable) { ownable.AcquireRecursive(); }
380
382 requires TOptional
383 : owned(ownable) { if (ownable != nullptr) ownable->AcquireRecursive(); }
384 #endif
385
386 /// Destructor. Invokes ReleaseRecursive() on member #owned.
387 ~OwnerRecursive() { if (!TOptional || owned) callRelease(); }
388
389 /// Sets the ownable after construction. This method is only available if the template
390 /// parameter \p{TOptional} is \c true. It must not be called if an object was given with
391 /// construction already, and it must not be called twice. If done, an assertion is raised.
392 /// @param ownable The ownable to acquire.
393 void Set(OwnablePointer ownable)
394 requires TOptional {
395 ALIB_ASSERT_ERROR(owned==nullptr, "LANG", "Owner already set.")
396 (owned= ownable)->AcquireRecursive( ALIB_DBG(dbgCI) );
397 }
398}; //class OwnerRecursive
399
400/// Similar to class #"lang::Owner", but calls methods \b AcquireShared and
401/// \b ReleaseShared.
402/// @see Chapter #"alib_threads_locks_auto_owner" of the Programmer's Manual of module
403/// \alib_threads
404/// @tparam TOwnable The type to own.
405/// Requirements are to have methods \b %AcquireShared and \b %ReleaseShared
406/// available.
407/// @tparam TOptional If \c true, then checks is performed, whether the given #owned is
408/// \e nulled and thus not acquired and released.
409/// If \c false such checks are omitted.
410template <typename TOwnable, bool TOptional= false>
412{
414
415 public:
416 /// The pointer type of the owned object.
417 using OwnablePointer= std::remove_reference_t<TOwnable>*;
418
419 protected:
420 OwnablePointer owned; ///< The resource to acquire and release.
421 #if ALIB_DEBUG
422 CallerInfo dbgCI; ///< Caller information. Available only with debug-builds.
423 #endif
424
425 #if !DOXYGEN
426 // choosing the right release method, with or without caller parameters.
427 #if ALIB_DEBUG
428 template<typename TRequires= TOwnable>
429 requires ( ALIB_HAS_METHOD(TRequires, ReleaseShared, dbgCI))
430 void callRelease() const { owned->ReleaseShared(dbgCI); }
431 #endif
432
433 template<typename TRequires= TOwnable>
434 requires ( ALIB_HAS_METHOD(TRequires, ReleaseShared, ))
435 void callRelease() const { owned->ReleaseShared(); }
436 #endif
437 public:
438
439 #if ALIB_DEBUG
440 /// Constructor. Invokes AcquireShared() on member #owned.
441 /// @param ownable The ownable to acquire.
442 /// @param ci Caller information.
443 OwnerShared( TOwnable& ownable, const CallerInfo& ci)
444 : owned(&ownable)
445 , dbgCI(ci) { ownable.AcquireShared(ci); }
446
447 /// Constructor taking a pointer to the ownable. This constructor is only available if
448 /// the template parameter \p{TOptional} is \c true.
449 /// @param ownable The ownable to acquire.
450 /// @param ci Caller information.
452 requires TOptional
453 : owned(ownable)
454 , dbgCI(ci) { if (ownable != nullptr) ownable->AcquireShared( ci ); }
455 #else
456 OwnerShared( TOwnable& ownable ) : owned(&ownable) { ownable.AcquireShared(); }
457 OwnerShared( OwnablePointer ownable )
458 requires TOptional
459 : owned(ownable) { if (ownable != nullptr) ownable->AcquireShared(); }
460 #endif
461
462
463 /// Destructor. Invokes ReleaseShared() on member #owned.
464 ~OwnerShared() { if (!TOptional || owned) callRelease(); }
465
466 /// Sets the ownable after construction. This method is only available if the template
467 /// parameter \p{TOptional} is \c true. It must not be called if an object was given with
468 /// construction already, and it must not be called twice. If done, an assertion is raised.
469 /// @param ownable The ownable to acquire.
470 void Set(OwnablePointer ownable)
471 requires TOptional {
472 ALIB_ASSERT_ERROR(owned==nullptr, "LANG", "Owner already set.")
473 (owned= ownable)->AcquireShared( ALIB_DBG(dbgCI) );
474 }
475}; //class OwnerShared
476
477/// Similar to class #"lang::Owner", but calls method \b TryAcquireShared instead of \b Acquire
478/// and \b ReleaseShared instead of \b Release.
479/// The result is retrievable with the method #IsOwning().
480/// @see Chapter #"alib_threads_locks_auto_owner" of the Programmer's Manual of module
481/// \alib_threads
482/// @tparam TOwnable The type to own.
483/// Requirements are to have methods \b %TryAcquireShared and \b %ReleaseShared
484/// available.
485/// @tparam TOptional If \c true, then checks is performed, whether the given #owned is
486/// \e nulled and thus not acquired and released.
487/// If \c false such checks are omitted.
488template <typename TOwnable, bool TOptional= false>
490{
492
493 public:
494 /// The pointer type of the owned object.
495 using OwnablePointer= std::remove_reference_t<TOwnable>*;
496
497 protected:
498 OwnablePointer owned; ///< The resource to acquire and release.
499 bool isOwning; ///< The result of the call to \b TryAcquire.
500 #if ALIB_DEBUG
501 CallerInfo dbgCI; ///< Caller information. Available only with debug-builds.
502 #endif
503
504 #if !DOXYGEN
505 // choosing the right release method, with or without caller parameters.
506 #if ALIB_DEBUG
507 template<typename TRequires= TOwnable>
508 requires ( ALIB_HAS_METHOD(TRequires, ReleaseShared, dbgCI))
509 void callRelease() { owned->ReleaseShared(dbgCI); }
510 #endif
511
512 template<typename TRequires= TOwnable>
513 requires ( ALIB_HAS_METHOD(TRequires, ReleaseShared, ))
514 void callRelease() { owned->ReleaseShared(); }
515 #endif
516 public:
517
518 #if ALIB_DEBUG
519 /// Constructor. Invokes TryAcquire() on member #owned.
520 /// @param ownable The ownable to acquire.
521 /// @param ci Caller information.
522 OwnerTryShared( TOwnable& ownable, const CallerInfo& ci)
523 : owned(&ownable)
524 , dbgCI(ci) { isOwning= ownable.TryAcquireShared(ci); }
525
526 /// Constructor taking a pointer to the ownable. This constructor is only available if
527 /// the template parameter \p{TOptional} is \c true.
528 /// @param ownable The ownable to acquire.
529 /// @param ci Caller information.
531 requires TOptional
532 : owned(ownable)
533 , dbgCI(ci) { isOwning = !ownable || ownable->TryAcquireShared( ci ); }
534 #else
535 OwnerTryShared( TOwnable& ownable )
536 : owned(&ownable) { isOwning= ownable.TryAcquireShared(); }
537
539 requires TOptional
540 : owned(ownable) { isOwning = !ownable || ownable->TryAcquireShared(); }
541 #endif
542
543
544 /// Destructor. Invokes Release() on member #owned.
545 ~OwnerTryShared() { if ((!TOptional || owned) && isOwning) callRelease(); }
546
547 /// @return \c true if the try to acquire the #owned with construction of this type was
548 /// successful. Furthermore, \c true is returned in the case that the template
549 /// parameter \p{TOptional} is \c true and no ownable was given with construction.
550 /// Otherwise, \c false is returned.
551 bool IsOwning() const noexcept { return isOwning; }
552
553 /// Sets the ownable after construction. This method is only available if the template
554 /// parameter \p{TOptional} is \c true. It must not be called if an object was given with
555 /// construction already, and it must not be called twice. If done, an assertion is raised.
556 /// @param ownable The ownable to acquire.
557 /// @return \c true if the try to acquire the owner was successful, \c false if not.
558 bool Set(OwnablePointer ownable)
559 requires TOptional {
560 ALIB_ASSERT_ERROR(owned==nullptr, "LANG", "Owner already set.")
561 return isOwning= (owned= ownable)->TryAcquireShared( ALIB_DBG(dbgCI) );
562 }
563
564}; //class OwnerTryShared
565
566
567/// Similar to class #"lang::Owner", but calls method \b TryAcquireSharedTimed instead
568/// of \b Acquire and \b ReleaseShared instead of \b Shared.
569/// The result is retrievable with the method #IsOwning().
570/// @see Chapter #"alib_threads_locks_auto_owner" of the Programmer's Manual of module
571/// \alib_threads
572/// @tparam TOwnable The type to own.
573/// Requirements are to have methods \b %TryAcquireSharedTimed and
574/// \b %ReleaseShared available.
575/// @tparam TOptional If \c true, then checks is performed, whether the given #owned is
576/// \e nulled and thus not acquired and released.
577/// If \c false such checks are omitted.
578template <typename TOwnable, bool TOptional= false>
580{
582
583 public:
584 /// The pointer type of the owned object.
585 using OwnablePointer= std::remove_reference_t<TOwnable>*;
586
587 protected:
588 OwnablePointer owned; ///< The resource to acquire and release.
589 bool isOwning; ///< The result of the call to \b TryAcquire.
590 #if ALIB_DEBUG
591 CallerInfo dbgCI; ///< Caller information. Available only with debug-builds.
592 #endif
593
594 #if !DOXYGEN
595 // choosing the right release method, with or without caller parameters.
596 #if ALIB_DEBUG
597 template<typename TRequires= TOwnable>
598 requires ( ALIB_HAS_METHOD(TRequires, ReleaseShared, dbgCI))
599 void callRelease() { owned->ReleaseShared(dbgCI); }
600 #endif
601
602 template<typename TRequires= TOwnable>
603 requires ( ALIB_HAS_METHOD(TRequires, ReleaseShared, ))
604 void callRelease() { owned->ReleaseShared(); }
605 #endif
606 public:
607
608 #if ALIB_DEBUG
609 /// Constructor. Invokes TryAcquire() on member #owned.
610 /// @tparam TTimeValue The type of the parameter \p{time} accepted with construction and passed
611 /// to the method <b>TOwnable::TryAcquireTimed</b>.<br>
612 /// Usually this is type #"Ticks" or its inherited type #"^Ticks::Duration".
613 /// @param time The duration to wait for, or point in time to wait until.
614 /// @param ownable The ownable to acquire.
615 /// @param ci Caller information.
616 template<typename TTimeValue>
617 OwnerSharedTimed( TOwnable& ownable, const TTimeValue& time, const CallerInfo& ci)
618 : owned(&ownable)
619 , dbgCI(ci) { isOwning= ownable.TryAcquireSharedTimed( time, ci); }
620
621 /// Constructor taking a pointer to the ownable. This constructor is only available if
622 /// the template parameter \p{TOptional} is \c true.
623 /// @tparam TTimeValue The type of the parameter \p{time} accepted with construction and passed
624 /// to method <b>TOwnable::TryAcquireTimed</b>.<br>
625 /// Usually this is type #"Ticks" or its inherited type #"^Ticks::Duration".
626 /// @param time The duration to wait for, or point in time to wait until.
627 /// @param ownable The ownable to acquire.
628 /// @param ci Caller information.
629 template<typename TTimeValue>
630 requires TOptional
631 OwnerSharedTimed( OwnablePointer ownable, const TTimeValue& time, const CallerInfo& ci)
632 : owned(ownable)
633 , dbgCI(ci) { isOwning= !ownable || ownable->TryAcquireSharedTimed( time, ci); }
634 #else
635 template<typename TTimeValue>
636 OwnerSharedTimed( TOwnable& ownable, const TTimeValue& time )
637 : owned(&ownable) { isOwning= ownable.TryAcquireSharedTimed( time ); }
638
639 template<typename TTimeValue>
640 requires TOptional
641 OwnerSharedTimed( OwnablePointer ownable, const TTimeValue& time)
642 : owned(ownable) { isOwning= !ownable || ownable->TryAcquireSharedTimed( time); }
643 #endif
644
645
646 /// Destructor. Invokes Release() on member #owned.
647 ~OwnerSharedTimed() { if ((!TOptional || owned) && isOwning) callRelease(); }
648
649 /// @return \c true if the try to acquire the #owned with construction of this type was
650 /// successful. Furthermore, \c true is returned in the case that the template
651 /// parameter \p{TOptional} is \c true and no ownable was given with construction.
652 /// Otherwise, \c false is returned.
653 bool IsOwning() const noexcept { return isOwning; }
654
655 /// Sets the ownable after construction. This method is only available if the template
656 /// parameter \p{TOptional} is \c true. It must not be called if an object was given with
657 /// construction already, and it must not be called twice. If done, an assertion is raised.
658 /// @param ownable The ownable to acquire.
659 /// @param time The duration to wait for, or point in time to wait until.
660 /// @tparam TTimeValue The type of the parameter \p{time} accepted with construction and passed
661 /// to the method <b>TOwnable::TryAcquireTimed</b>.<br>
662 /// Usually this is type #"Ticks" or its inherited type #"^Ticks::Duration".
663 /// @return \c true if the try to acquire the owner was successful, \c false if not.
664 template<typename TTimeValue>
665 bool Set(OwnablePointer ownable, const TTimeValue& time)
666 requires TOptional {
667 ALIB_ASSERT_ERROR(owned==nullptr, "LANG", "Owner already set.")
668 return isOwning= (owned= ownable)->TryAcquireSharedTimed( time ALIB_DBG(, dbgCI) );
669 }
670
671}; //class OwnerSharedTimed
672
673} // namespace alib[::lang]
674
675} // namespace [alib]
#define ALIB_HAS_METHOD(T, Method,...)
Definition alib.inl:1083
#define ALIB_STACK_ALLOCATED_TYPE(T)
Definition alib.inl:1070
#define ALIB_EXPORT
Definition alib.inl:562
#define ALIB_DBG(...)
Definition alib.inl:931
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1144
void Set(OwnablePointer ownable)
Definition owner.inl:393
std::remove_reference_t< TOwnable > * OwnablePointer
The pointer type of the owned object.
Definition owner.inl:340
OwnerRecursive(OwnablePointer ownable, const CallerInfo &ci)
Definition owner.inl:374
OwnerRecursive(TOwnable &ownable, const CallerInfo &ci)
Definition owner.inl:366
OwnablePointer owned
The resource to acquire and release.
Definition owner.inl:343
CallerInfo dbgCI
Caller information. Available only with debug-builds.
Definition owner.inl:345
~OwnerRecursive()
Destructor. Invokes ReleaseRecursive() on member owned.
Definition owner.inl:387
std::remove_reference_t< TOwnable > * OwnablePointer
The pointer type of the owned object.
Definition owner.inl:585
OwnerSharedTimed(OwnablePointer ownable, const TTimeValue &time, const CallerInfo &ci)
Definition owner.inl:631
~OwnerSharedTimed()
Destructor. Invokes Release() on member owned.
Definition owner.inl:647
CallerInfo dbgCI
Caller information. Available only with debug-builds.
Definition owner.inl:591
bool Set(OwnablePointer ownable, const TTimeValue &time)
Definition owner.inl:665
OwnerSharedTimed(TOwnable &ownable, const TTimeValue &time, const CallerInfo &ci)
Definition owner.inl:617
bool isOwning
The result of the call to TryAcquire.
Definition owner.inl:589
bool IsOwning() const noexcept
Definition owner.inl:653
OwnablePointer owned
The resource to acquire and release.
Definition owner.inl:588
OwnerShared(TOwnable &ownable, const CallerInfo &ci)
Definition owner.inl:443
OwnablePointer owned
The resource to acquire and release.
Definition owner.inl:420
std::remove_reference_t< TOwnable > * OwnablePointer
The pointer type of the owned object.
Definition owner.inl:417
~OwnerShared()
Destructor. Invokes ReleaseShared() on member owned.
Definition owner.inl:464
OwnerShared(OwnablePointer ownable, const CallerInfo &ci)
Definition owner.inl:451
void Set(OwnablePointer ownable)
Definition owner.inl:470
CallerInfo dbgCI
Caller information. Available only with debug-builds.
Definition owner.inl:422
std::remove_reference_t< TOwnable > * OwnablePointer
The pointer type of the owned object.
Definition owner.inl:223
bool IsOwning() const noexcept
Definition owner.inl:319
~OwnerTimed()
Destructor. Invokes Release() on member #".owned".
Definition owner.inl:297
OwnerTimed(OwnablePointer ownable, const TTimeValue &time, const CallerInfo &ci)
Definition owner.inl:281
OwnerTimed(TOwnable &ownable, const TTimeValue &time, const CallerInfo &ci)
Definition owner.inl:267
bool Set(OwnablePointer ownable, const TTimeValue &time)
Definition owner.inl:310
OwnablePointer owned
The resource to acquire and release.
Definition owner.inl:226
CallerInfo dbgCI
Caller information. Available only with debug-builds.
Definition owner.inl:229
bool isOwning
The result of the call to TryAcquire.
Definition owner.inl:227
bool IsOwning() const noexcept
Definition owner.inl:551
CallerInfo dbgCI
Caller information. Available only with debug-builds.
Definition owner.inl:501
bool isOwning
The result of the call to TryAcquire.
Definition owner.inl:499
std::remove_reference_t< TOwnable > * OwnablePointer
The pointer type of the owned object.
Definition owner.inl:495
OwnablePointer owned
The resource to acquire and release.
Definition owner.inl:498
bool Set(OwnablePointer ownable)
Definition owner.inl:558
OwnerTryShared(TOwnable &ownable, const CallerInfo &ci)
Definition owner.inl:522
OwnerTryShared(OwnablePointer ownable, const CallerInfo &ci)
Definition owner.inl:530
~OwnerTryShared()
Destructor. Invokes Release() on member owned.
Definition owner.inl:545
OwnablePointer owned
The resource to acquire and release.
Definition owner.inl:129
bool Set(OwnablePointer ownable)
Definition owner.inl:193
OwnerTry(OwnablePointer ownable, const CallerInfo &ci)
Definition owner.inl:172
~OwnerTry()
Destructor. Invokes Release() on member #".owned".
Definition owner.inl:186
CallerInfo dbgCI
Caller information. Available only with debug-builds.
Definition owner.inl:132
std::remove_reference_t< TOwnable > * OwnablePointer
The pointer type of the owned object.
Definition owner.inl:126
bool IsOwning() const noexcept
Definition owner.inl:203
OwnerTry(TOwnable &ownable, const CallerInfo &ci)
Definition owner.inl:164
bool isOwning
The result of the call to TryAcquire.
Definition owner.inl:130
OwnablePointer owned
The resource to acquire and release.
Definition owner.inl:54
std::remove_reference_t< TOwnable > * OwnablePointer
The pointer type of the owned object.
Definition owner.inl:51
~Owner()
Destructor. Releases the owner by invoking Release().
Definition owner.inl:97
Owner(TOwnable &ownable, const CallerInfo &ci)
Definition owner.inl:77
Owner(OwnablePointer ownable, const CallerInfo &ci)
Definition owner.inl:85
CallerInfo dbgCI
Caller information. Available only with debug-builds.
Definition owner.inl:56
void Set(OwnablePointer ownable)
Definition owner.inl:103