ORIGINAL
Loading...
Searching...
No Matches
autoPtr.h
Go to the documentation of this file.
1#ifndef AUTOPTR_H
2#define AUTOPTR_H
3
4#include "atomic.h"
5#include "config.h"
6#include "printable.h"
7#include "comparable.h"
8#include "hash.h"
9#include "error.h"
10
30namespace original {
31 // Forward declaration for refCountBase
32 class refCountBase;
33
34 // Forward declaration for refCount
35 template<typename TYPE, typename DELETER>
36 class refCount;
37
54 template<typename TYPE, typename DERIVED, typename DELETER>
55 class autoPtr : public printable,
56 public comparable<autoPtr<TYPE, DERIVED, DELETER>>,
57 public hashable<autoPtr<TYPE, DERIVED, DELETER>> {
58 template<typename, typename, typename> friend class autoPtr;
59 protected:
60 atomic<refCountBase*> ref_count;
61 TYPE* alias_ptr;
62
68 explicit autoPtr(TYPE* p);
69
74 void addStrongRef() const;
75
80 void addWeakRef() const;
81
86 void removeStrongRef() const;
87
92 void removeWeakRef() const;
93
100 TYPE* releasePtr() noexcept;
101
106 void destroyRefCnt() noexcept;
107
112 void clean() noexcept;
113
119 static refCount<TYPE, DELETER>* newRefCount(TYPE* p = nullptr);
120
121 public:
122
128
134
139 bool exist() const;
140
145 bool expired() const;
146
151 explicit operator bool() const;
152
157 bool operator!() const;
158
164 const TYPE* get() const;
165
171 TYPE* get();
172
178 virtual const TYPE& operator*() const;
179
185 virtual const TYPE* operator->() const;
186
193 virtual const TYPE& operator[](u_integer index) const;
194
195 // Mutable accessors
201 virtual TYPE& operator*();
202
208 virtual TYPE* operator->();
209
216 virtual TYPE& operator[](u_integer index);
217
227 void swap(autoPtr& other) noexcept;
228
234 integer compareTo(const autoPtr& other) const override;
235
240 std::string className() const override;
241
247 std::string toString(bool enter) const override;
248
254 [[nodiscard]] u_integer toHash() const noexcept override;
255
262 bool equals(const autoPtr& other) const noexcept override;
263
267 ~autoPtr() override;
268
269 template<typename T, typename DER, typename DEL>
270 friend bool operator==(const autoPtr<T, DER, DEL>& ptr, const std::nullptr_t& null);
271
272 template<typename T, typename DER, typename DEL>
273 friend bool operator!=(const autoPtr<T, DER, DEL>& ptr, const std::nullptr_t& null);
274
275 template<typename T, typename DER, typename DEL>
276 friend bool operator==(const std::nullptr_t& null, const autoPtr<T, DER, DEL>& ptr);
277
278 template<typename T, typename DER, typename DEL>
279 friend bool operator!=(const std::nullptr_t& null, const autoPtr<T, DER, DEL>& ptr);
280 };
281
292 template<typename T, typename DER, typename DEL>
293 bool operator==(const autoPtr<T, DER, DEL>& ptr, const std::nullptr_t& null);
294
305 template<typename T, typename DER, typename DEL>
306 bool operator!=(const autoPtr<T, DER, DEL>& ptr, const std::nullptr_t& null);
307
318 template<typename T, typename DER, typename DEL>
319 bool operator==(const std::nullptr_t& null, const autoPtr<T, DER, DEL>& ptr);
320
331 template<typename T, typename DER, typename DEL>
332 bool operator!=(const std::nullptr_t& null, const autoPtr<T, DER, DEL>& ptr);
333
340 template <typename, typename, typename>
341 friend class autoPtr;
342
343 protected:
344 mutable atomic<u_integer> strong_refs;
345 mutable atomic<u_integer> weak_refs;
346
350 refCountBase();
351
356 virtual const void* getPtr() const noexcept = 0;
357
362 virtual void* getPtr() noexcept = 0;
363
369 virtual void* releasePtr() noexcept = 0;
370
374 virtual void destroyPtr() noexcept = 0;
375
376 virtual ~refCountBase() = default;
377 };
378
389 template<typename TYPE, typename DELETER>
390 class refCount final : public refCountBase {
391 template <typename, typename, typename>
392 friend class autoPtr;
393
394 TYPE* ptr;
395 DELETER deleter;
396
401 explicit refCount(TYPE* p = nullptr);
402
403 const void* getPtr() const noexcept override;
404
405 void* getPtr() noexcept override;
406
407 void* releasePtr() noexcept override;
408
412 void destroyPtr() noexcept override;
413
417 ~refCount() override;
418 };
419}
420
421template<typename TYPE, typename DERIVED, typename DELETER>
424
425template<typename TYPE, typename DERIVED, typename DELETER>
427{
428 if (const refCountBase* current = *this->ref_count) {
429 current->strong_refs += 1;
430 }
431}
432
433template<typename TYPE, typename DERIVED, typename DELETER>
435{
436 if (const refCountBase* current = *this->ref_count) {
437 current->weak_refs += 1;
438 }
439}
440
441template<typename TYPE, typename DERIVED, typename DELETER>
443{
444 if (const refCountBase* current = *this->ref_count) {
445 current->strong_refs -= 1;
446 }
447}
448
449template<typename TYPE, typename DERIVED, typename DELETER>
451{
452 if (const refCountBase* current = *this->ref_count) {
453 current->weak_refs -= 1;
454 }
455}
456
457template <typename TYPE, typename DERIVED, typename DELETER>
459{
460 refCountBase* current = *this->ref_count;
461 if (!current) return nullptr;
462 return static_cast<TYPE*>(current->releasePtr());
463}
464
465template<typename TYPE, typename DERIVED, typename DELETER>
467 const refCountBase* current = *this->ref_count;
468 if (!current) return;
469 this->ref_count = nullptr;
470 delete current;
471}
472
473template<typename TYPE, typename DERIVED, typename DELETER>
475 refCountBase* current = *this->ref_count;
476 if (!current) {
477 return;
478 }
479
480 const u_integer strong_refs = *current->strong_refs;
481 const u_integer weak_refs = *current->weak_refs;
482
483 if (strong_refs == 0) {
484 current->destroyPtr();
485 }
486
487 if (strong_refs == 0 && weak_refs == 0) {
488 this->ref_count = nullptr;
489 delete current;
490 }
491}
492
493template <typename TYPE, typename DERIVED, typename DELETER>
498
499template<typename TYPE, typename DERIVED, typename DELETER>
501 const refCountBase* current = *this->ref_count;
502 if (!current) return 0;
503 return *current->strong_refs;
504}
505
506template<typename TYPE, typename DERIVED, typename DELETER>
508 const refCountBase* current = *this->ref_count;
509 if (!current) return 0;
510 return *current->weak_refs;
511}
512
513template<typename TYPE, typename DERIVED, typename DELETER>
515 const refCountBase* current = *this->ref_count;
516 if (!current) return false;
517 return *current->strong_refs > 0 || *current->weak_refs > 0;
518}
519
520template<typename TYPE, typename DERIVED, typename DELETER>
522 const refCountBase* current = *this->ref_count;
523 if (!current) return true;
524 return *current->strong_refs == 0;
525}
526
527template<typename TYPE, typename DERIVED, typename DELETER>
529 refCountBase* current = *this->ref_count;
530 if (!current) return false;
531 if (*current->strong_refs == 0) return false;
532 const void* p = current->getPtr();
533 return p != nullptr || this->alias_ptr != nullptr;
534}
535
536template <typename TYPE, typename DERIVED, typename DELETER>
538 return !this->operator bool();
539}
540
541template<typename TYPE, typename DERIVED, typename DELETER>
543 if (!this->exist()){
544 throw nullPointerError();
545 }
546 if (this->alias_ptr) {
547 return this->alias_ptr;
548 }
549 refCountBase* current = *this->ref_count;
550 return static_cast<TYPE*>(current->getPtr());
551}
552
553template<typename TYPE, typename DERIVED, typename DELETER>
555 if (!this->exist()){
556 throw nullPointerError();
557 }
558 if (this->alias_ptr) {
559 return this->alias_ptr;
560 }
561 refCountBase* current = *this->ref_count;
562 return static_cast<TYPE*>(current->getPtr());
563}
564
565template<typename TYPE, typename DERIVED, typename DELETER>
567 const auto ptr = this->get();
568 if (!ptr)
569 throw nullPointerError();
570 return *ptr;
571}
572
573template<typename TYPE, typename DERIVED, typename DELETER>
574const TYPE*
576 const auto ptr = this->get();
577 if (!ptr)
578 throw nullPointerError();
579 return ptr;
580}
581
582template<typename TYPE, typename DERIVED, typename DELETER>
584 const auto ptr = this->get();
585 if (!ptr)
586 throw nullPointerError();
587 return ptr[index];
588}
589
590template<typename TYPE, typename DERIVED, typename DELETER>
592 auto ptr = this->get();
593 if (!ptr)
594 throw nullPointerError();
595 return *ptr;
596}
597
598template<typename TYPE, typename DERIVED, typename DELETER>
599TYPE*
601 auto ptr = this->get();
602 if (!ptr)
603 throw nullPointerError();
604 return ptr;
605}
606
607template<typename TYPE, typename DERIVED, typename DELETER>
609 auto ptr = this->get();
610 if (!ptr)
611 throw nullPointerError();
612 return ptr[index];
613}
614
615template<typename TYPE, typename DERIVED, typename DELETER>
617 std::swap(this->alias_ptr, other.alias_ptr);
618
619 refCountBase* a = this->ref_count.exchange(nullptr);
620 refCountBase* b = other.ref_count.exchange(a);
621 this->ref_count = b;
622}
623
624template<typename TYPE, typename DERIVED, typename DELETER>
626 return this->get() - other.get();
627}
628
629template<typename TYPE, typename DERIVED, typename DELETER>
631 return "autoPtr";
632}
633
634template<typename TYPE, typename DERIVED, typename DELETER>
635std::string original::autoPtr<TYPE, DERIVED, DELETER>::toString(const bool enter) const {
636 std::stringstream ss;
637 ss << this->className() << "(";
638 ss << formatString(this->get());
639 ss << ")";
640 if (enter)
641 ss << "\n";
642 return ss.str();
643}
644
645template<typename TYPE, typename DERIVED, typename DELETER>
649
650template<typename TYPE, typename DERIVED, typename DELETER>
652 return *this == other;
653}
654
655template<typename TYPE, typename DERIVED, typename DELETER>
659
660template<typename T, typename DER, typename DEL>
661bool original::operator==(const autoPtr<T, DER, DEL>& ptr, const std::nullptr_t&) {
662 return !ptr.operator bool();
663}
664
665template<typename T, typename DER, typename DEL>
666bool original::operator!=(const autoPtr<T, DER, DEL>& ptr, const std::nullptr_t&) {
667 return ptr.operator bool();
668}
669
670template<typename T, typename DER, typename DEL>
671bool original::operator==(const std::nullptr_t&, const autoPtr<T, DER, DEL>& ptr) {
672 return !ptr.operator bool();
673}
674
675template<typename T, typename DER, typename DEL>
676bool original::operator!=(const std::nullptr_t&, const autoPtr<T, DER, DEL>& ptr) {
677 return ptr.operator bool();
678}
679
680inline original::refCountBase::refCountBase() : strong_refs(makeAtomic<u_integer>(0)), weak_refs(makeAtomic<u_integer>(0)) {}
681
682template<typename TYPE, typename DELETER>
684 : ptr(p) {}
685
686template <typename TYPE, typename DELETER>
687const void* original::refCount<TYPE, DELETER>::getPtr() const noexcept
688{
689 return this->ptr;
690}
691
692template <typename TYPE, typename DELETER>
694{
695 if constexpr (std::is_const_v<TYPE>) {
696 return const_cast<std::remove_const_t<TYPE>*>(this->ptr);
697 } else {
698 return this->ptr;
699 }
700}
701
702template <typename TYPE, typename DELETER>
704{
705 if constexpr (std::is_const_v<TYPE>) {
706 auto p = const_cast<std::remove_const_t<TYPE>*>(this->ptr);
707 this->ptr = nullptr;
708 return p;
709 } else {
710 auto p = this->ptr;
711 this->ptr = nullptr;
712 return p;
713 }
714}
715
716template<typename TYPE, typename DELETER>
718 TYPE* tmp = this->ptr;
719 this->ptr = nullptr;
720 this->deleter(tmp);
721}
722
723template<typename TYPE, typename DELETER>
725 this->destroyPtr();
726}
727
728#endif //AUTOPTR_H
Base smart pointer with reference counting.
Definition autoPtr.h:57
void addWeakRef() const
Increment weak reference count.
Definition autoPtr.h:434
static refCount< TYPE, DELETER > * newRefCount(TYPE *p=nullptr)
Create new reference counter.
Definition autoPtr.h:494
integer compareTo(const autoPtr &other) const override
Compare reference counters.
Definition autoPtr.h:625
void destroyRefCnt() noexcept
Destroy reference counter.
Definition autoPtr.h:466
virtual const TYPE & operator[](u_integer index) const
Const array access operator.
Definition autoPtr.h:583
u_integer strongRefs() const
Get strong reference count.
Definition autoPtr.h:500
~autoPtr() override
Destructor triggers reference cleanup.
Definition autoPtr.h:656
bool exist() const
Check active ownership.
Definition autoPtr.h:514
void removeWeakRef() const
Decrement weak reference count.
Definition autoPtr.h:450
void addStrongRef() const
Increment strong reference count.
Definition autoPtr.h:426
TYPE * alias_ptr
Aliased pointer for type casting scenarios.
Definition autoPtr.h:61
bool equals(const autoPtr &other) const noexcept override
Equality comparison.
Definition autoPtr.h:651
TYPE * releasePtr() noexcept
Release ownership of the managed pointer.
Definition autoPtr.h:458
bool operator!() const
Logical NOT operator.
Definition autoPtr.h:537
std::string className() const override
Get class name string.
Definition autoPtr.h:630
atomic< refCountBase * > ref_count
Reference counter object.
Definition autoPtr.h:60
void removeStrongRef() const
Decrement strong reference count.
Definition autoPtr.h:442
void swap(autoPtr &other) noexcept
Swaps the reference counters between two autoPtr instances.
Definition autoPtr.h:616
u_integer toHash() const noexcept override
Compute hash value for the pointer.
Definition autoPtr.h:646
bool expired() const
Check resource validity.
Definition autoPtr.h:521
void clean() noexcept
Cleanup resources when expired.
Definition autoPtr.h:474
u_integer weakRefs() const
Get weak reference count.
Definition autoPtr.h:507
autoPtr(TYPE *p)
Construct from raw pointer.
Definition autoPtr.h:422
virtual const TYPE & operator*() const
Const dereference operator.
Definition autoPtr.h:566
std::string toString(bool enter) const override
String representation formatter.
Definition autoPtr.h:635
const TYPE * get() const
Get managed pointer const version.
Definition autoPtr.h:542
virtual const TYPE * operator->() const
Const member access operator.
Definition autoPtr.h:575
Base class for comparable objects.
Definition comparable.h:32
Default deletion policy for single objects.
Definition deleter.h:109
static u_integer hashFunc(const T &t) noexcept
Default hash function fallback.
Forward declaration of hashable interface template.
Definition hash.h:206
Exception for null pointer dereference attempts.
Definition error.h:171
Base class providing polymorphic string conversion capabilities.
Definition printable.h:39
Base class for reference counting metadata.
Definition autoPtr.h:339
atomic< u_integer > strong_refs
Strong reference counter.
Definition autoPtr.h:344
virtual const void * getPtr() const noexcept=0
Get managed pointer (const version)
refCountBase()
Construct refCountBase object.
Definition autoPtr.h:680
atomic< u_integer > weak_refs
Weak reference counter.
Definition autoPtr.h:345
virtual void destroyPtr() noexcept=0
Destroy managed pointer using deleter.
virtual void * releasePtr() noexcept=0
Release ownership of the managed pointer.
Reference counting metadata container.
Definition autoPtr.h:390
Interface for objects that can be compared.
Platform-independent type definitions and compiler/platform detection.
Custom exception classes and callback validation utilities.
std::uint32_t u_integer
32-bit unsigned integer type for sizes and indexes
Definition config.h:263
std::int64_t integer
64-bit signed integer type for arithmetic operations
Definition config.h:254
Provides a generic hashing utility and interface for hashable types.
Main namespace for the project Original.
Definition algorithms.h:21
bool operator!=(const autoPtr< T, DER, DEL > &ptr, const std::nullptr_t &null)
Inequality comparison with nullptr.
Definition autoPtr.h:666
bool operator==(const autoPtr< T, DER, DEL > &ptr, const std::nullptr_t &null)
Equality comparison with nullptr.
Definition autoPtr.h:661
Interface for polymorphic string formatting and output.