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
65 template<typename TYPE, typename DERIVED, typename DELETER>
66 class autoPtr : public printable,
67 public comparable<autoPtr<TYPE, DERIVED, DELETER>>,
68 public hashable<autoPtr<TYPE, DERIVED, DELETER>> {
69 template<typename, typename, typename> friend class autoPtr;
70 protected:
73
80 explicit autoPtr(TYPE* p);
81
87 void addStrongRef() const;
88
94 void addWeakRef() const;
95
102 void removeStrongRef() const;
103
110 void removeWeakRef() const;
111
120
127
134
142
143 public:
144
151
158
164 bool exist() const;
165
172
179
185
193
201
208
215
224
225 // Mutable accessors
232
239
248
262
270
276
283
291
299
305
308
311
314
317 };
318
330 bool operator==(const autoPtr<T, DER, DEL>& ptr, const std::nullptr_t& null);
331
343 bool operator!=(const autoPtr<T, DER, DEL>& ptr, const std::nullptr_t& null);
344
356 bool operator==(const std::nullptr_t& null, const autoPtr<T, DER, DEL>& ptr);
357
369 bool operator!=(const std::nullptr_t& null, const autoPtr<T, DER, DEL>& ptr);
370
378 template <typename, typename, typename>
379 friend class autoPtr;
380
381 protected:
384
389 refCountBase();
390
396 virtual const void* getPtr() const noexcept = 0;
397
403 virtual void* getPtr() noexcept = 0;
404
412
417 virtual void destroyPtr() noexcept = 0;
418
423 };
424
442 template <typename, typename, typename>
443 friend class autoPtr;
444
445 TYPE* ptr;
447
453 explicit refCount(TYPE* p = nullptr);
454
459 const void* getPtr() const noexcept override;
460
466 void* getPtr() noexcept override;
467
474 void* releasePtr() noexcept override;
475
481 void destroyPtr() noexcept override;
482
487 ~refCount() override;
488 };
489}
490
491namespace std {
503 template<typename TYPE, typename DERIVED, typename DELETER>
504 void swap(original::autoPtr<TYPE, DERIVED, DELETER>& lhs, // NOLINT
506}
507
508template<typename TYPE, typename DERIVED, typename DELETER>
511
512template<typename TYPE, typename DERIVED, typename DELETER>
514{
515 if (const refCountBase* current = *this->ref_count) {
516 current->strong_refs += 1;
517 }
518}
519
520template<typename TYPE, typename DERIVED, typename DELETER>
522{
523 if (const refCountBase* current = *this->ref_count) {
524 current->weak_refs += 1;
525 }
526}
527
528template<typename TYPE, typename DERIVED, typename DELETER>
530{
531 if (const refCountBase* current = *this->ref_count) {
532 current->strong_refs -= 1;
533 }
534}
535
536template<typename TYPE, typename DERIVED, typename DELETER>
538{
539 if (const refCountBase* current = *this->ref_count) {
540 current->weak_refs -= 1;
541 }
542}
543
544template <typename TYPE, typename DERIVED, typename DELETER>
546{
547 refCountBase* current = *this->ref_count;
548 if (!current) return nullptr;
549 return static_cast<TYPE*>(current->releasePtr());
550}
551
552template<typename TYPE, typename DERIVED, typename DELETER>
554 const refCountBase* current = *this->ref_count;
555 if (!current) return;
556 this->ref_count = nullptr;
557 delete current;
558}
559
560template<typename TYPE, typename DERIVED, typename DELETER>
562 refCountBase* current = *this->ref_count;
563 if (!current) {
564 return;
565 }
566
567 const u_integer strong_refs = *current->strong_refs;
568 const u_integer weak_refs = *current->weak_refs;
569
570 if (strong_refs == 0) {
571 current->destroyPtr();
572 }
573
574 if (strong_refs == 0 && weak_refs == 0) {
575 this->ref_count = nullptr;
576 delete current;
577 }
578}
579
580template <typename TYPE, typename DERIVED, typename DELETER>
585
586template<typename TYPE, typename DERIVED, typename DELETER>
588 const refCountBase* current = *this->ref_count;
589 if (!current) return 0;
590 return *current->strong_refs;
591}
592
593template<typename TYPE, typename DERIVED, typename DELETER>
595 const refCountBase* current = *this->ref_count;
596 if (!current) return 0;
597 return *current->weak_refs;
598}
599
600template<typename TYPE, typename DERIVED, typename DELETER>
602 const refCountBase* current = *this->ref_count;
603 if (!current) return false;
604 return *current->strong_refs > 0 || *current->weak_refs > 0;
605}
606
607template<typename TYPE, typename DERIVED, typename DELETER>
609 const refCountBase* current = *this->ref_count;
610 if (!current) return true;
611 return *current->strong_refs == 0;
612}
613
614template<typename TYPE, typename DERIVED, typename DELETER>
616 refCountBase* current = *this->ref_count;
617 if (!current) return false;
618 if (*current->strong_refs == 0) return false;
619 const void* p = current->getPtr();
620 return p != nullptr || this->alias_ptr != nullptr;
621}
622
623template <typename TYPE, typename DERIVED, typename DELETER>
625 return !this->operator bool();
626}
627
628template<typename TYPE, typename DERIVED, typename DELETER>
630 if (!this->exist()){
631 throw nullPointerError();
632 }
633 if (this->alias_ptr) {
634 return this->alias_ptr;
635 }
636 refCountBase* current = *this->ref_count;
637 return static_cast<TYPE*>(current->getPtr());
638}
639
640template<typename TYPE, typename DERIVED, typename DELETER>
642 if (!this->exist()){
643 throw nullPointerError();
644 }
645 if (this->alias_ptr) {
646 return this->alias_ptr;
647 }
648 refCountBase* current = *this->ref_count;
649 return static_cast<TYPE*>(current->getPtr());
650}
651
652template<typename TYPE, typename DERIVED, typename DELETER>
654 const auto ptr = this->get();
655 if (!ptr)
656 throw nullPointerError();
657 return *ptr;
658}
659
660template<typename TYPE, typename DERIVED, typename DELETER>
661const TYPE*
663 const auto ptr = this->get();
664 if (!ptr)
665 throw nullPointerError();
666 return ptr;
667}
668
669template<typename TYPE, typename DERIVED, typename DELETER>
671 const auto ptr = this->get();
672 if (!ptr)
673 throw nullPointerError();
674 return ptr[index];
675}
676
677template<typename TYPE, typename DERIVED, typename DELETER>
679 auto ptr = this->get();
680 if (!ptr)
681 throw nullPointerError();
682 return *ptr;
683}
684
685template<typename TYPE, typename DERIVED, typename DELETER>
686TYPE*
688 auto ptr = this->get();
689 if (!ptr)
690 throw nullPointerError();
691 return ptr;
692}
693
694template<typename TYPE, typename DERIVED, typename DELETER>
696 auto ptr = this->get();
697 if (!ptr)
698 throw nullPointerError();
699 return ptr[index];
700}
701
702template<typename TYPE, typename DERIVED, typename DELETER>
704 if (this == &other)
705 return;
706
707 refCountBase* a = this->ref_count.exchange(nullptr);
708 refCountBase* b = other.ref_count.exchange(a);
709 std::swap(this->alias_ptr, other.alias_ptr);
710 this->ref_count = b;
711}
712
713template<typename TYPE, typename DERIVED, typename DELETER>
717
718template<typename TYPE, typename DERIVED, typename DELETER>
720 return "autoPtr";
721}
722
723template<typename TYPE, typename DERIVED, typename DELETER>
725 std::stringstream ss;
726 ss << this->className() << "(";
727 ss << formatString(this->get());
728 ss << ")";
729 if (enter)
730 ss << "\n";
731 return ss.str();
732}
733
734template<typename TYPE, typename DERIVED, typename DELETER>
738
739template<typename TYPE, typename DERIVED, typename DELETER>
741 return *this == other;
742}
743
744template<typename TYPE, typename DERIVED, typename DELETER>
748
749template<typename T, typename DER, typename DEL>
750bool original::operator==(const autoPtr<T, DER, DEL>& ptr, const std::nullptr_t&) {
751 return !ptr.operator bool();
752}
753
754template<typename T, typename DER, typename DEL>
755bool original::operator!=(const autoPtr<T, DER, DEL>& ptr, const std::nullptr_t&) {
756 return ptr.operator bool();
757}
758
759template<typename T, typename DER, typename DEL>
760bool original::operator==(const std::nullptr_t&, const autoPtr<T, DER, DEL>& ptr) {
761 return !ptr.operator bool();
762}
763
764template<typename T, typename DER, typename DEL>
765bool original::operator!=(const std::nullptr_t&, const autoPtr<T, DER, DEL>& ptr) {
766 return ptr.operator bool();
767}
768
770
771template<typename TYPE, typename DELETER>
773 : ptr(p) {}
774
775template <typename TYPE, typename DELETER>
776const void* original::refCount<TYPE, DELETER>::getPtr() const noexcept
777{
778 return this->ptr;
779}
780
781template <typename TYPE, typename DELETER>
783{
784 if constexpr (std::is_const_v<TYPE>) {
785 return const_cast<std::remove_const_t<TYPE>*>(this->ptr);
786 } else {
787 return this->ptr;
788 }
789}
790
791template <typename TYPE, typename DELETER>
793{
794 if constexpr (std::is_const_v<TYPE>) {
795 auto p = const_cast<std::remove_const_t<TYPE>*>(this->ptr);
796 this->ptr = nullptr;
797 return p;
798 } else {
799 auto p = this->ptr;
800 this->ptr = nullptr;
801 return p;
802 }
803}
804
805template<typename TYPE, typename DELETER>
807 TYPE* tmp = this->ptr;
808 this->ptr = nullptr;
809 this->deleter(tmp);
810}
811
812template<typename TYPE, typename DELETER>
814 this->destroyPtr();
815}
816
817template <typename TYPE, typename DERIVED, typename DELETER>
820{
821 lhs.swap(rhs);
822}
823
824#endif //AUTOPTR_H
Base smart pointer with reference counting.
Definition autoPtr.h:68
void addWeakRef() const
Increment weak reference count.
Definition autoPtr.h:521
static refCount< TYPE, DELETER > * newRefCount(TYPE *p=nullptr)
Create new reference counter.
Definition autoPtr.h:581
integer compareTo(const autoPtr &other) const override
Compare reference counters.
Definition autoPtr.h:714
void destroyRefCnt() noexcept
Destroy reference counter.
Definition autoPtr.h:553
virtual const TYPE & operator[](u_integer index) const
Const array access operator.
Definition autoPtr.h:670
u_integer strongRefs() const
Get strong reference count.
Definition autoPtr.h:587
~autoPtr() override
Destructor triggers reference cleanup.
Definition autoPtr.h:745
bool exist() const
Check active ownership.
Definition autoPtr.h:601
void removeWeakRef() const
Decrement weak reference count.
Definition autoPtr.h:537
void addStrongRef() const
Increment strong reference count.
Definition autoPtr.h:513
TYPE * alias_ptr
Aliased pointer for type casting scenarios.
Definition autoPtr.h:72
bool equals(const autoPtr &other) const noexcept override
Equality comparison.
Definition autoPtr.h:740
TYPE * releasePtr() noexcept
Release ownership of the managed pointer.
Definition autoPtr.h:545
bool operator!() const
Logical NOT operator.
Definition autoPtr.h:624
std::string className() const override
Get class name string.
Definition autoPtr.h:719
atomic< refCountBase * > ref_count
Reference counter object.
Definition autoPtr.h:71
void removeStrongRef() const
Decrement strong reference count.
Definition autoPtr.h:529
void swap(autoPtr &other) noexcept
Swaps the reference counters between two autoPtr instances.
Definition autoPtr.h:703
u_integer toHash() const noexcept override
Compute hash value for the pointer.
Definition autoPtr.h:735
bool expired() const
Check resource validity.
Definition autoPtr.h:608
void clean() noexcept
Cleanup resources when expired.
Definition autoPtr.h:561
u_integer weakRefs() const
Get weak reference count.
Definition autoPtr.h:594
autoPtr(TYPE *p)
Construct from raw pointer.
Definition autoPtr.h:509
virtual const TYPE & operator*() const
Const dereference operator.
Definition autoPtr.h:653
std::string toString(bool enter) const override
String representation formatter.
Definition autoPtr.h:724
const TYPE * get() const
Get managed pointer const version.
Definition autoPtr.h:629
virtual const TYPE * operator->() const
Const member access operator.
Definition autoPtr.h:662
Base class for comparable objects.
Definition comparable.h:35
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:220
Exception for null pointer dereference attempts.
Definition error.h:245
A placeholder type representing the absence of a value.
Definition types.h:33
Unique ownership smart pointer with move semantics.
Definition ownerPtr.h:37
Base class providing polymorphic string conversion capabilities.
Definition printable.h:39
Base class for reference counting metadata.
Definition autoPtr.h:377
atomic< u_integer > strong_refs
Strong reference counter.
Definition autoPtr.h:382
virtual const void * getPtr() const noexcept=0
Get managed pointer (const version)
refCountBase()
Construct refCountBase object.
Definition autoPtr.h:769
atomic< u_integer > weak_refs
Weak reference counter.
Definition autoPtr.h:383
Reference counting metadata container.
Definition autoPtr.h:441
Interface for objects that can be compared.
Platform-independent type definitions and compiler/platform detection.
Custom exception classes and callback validation utilities.
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:755
bool operator==(const autoPtr< T, DER, DEL > &ptr, const std::nullptr_t &null)
Equality comparison with nullptr.
Definition autoPtr.h:750
auto makeAtomic()
Creates a default-constructed atomic object.
Definition atomic.h:867
Standard namespace extensions for original::alternative.
Definition allocator.h:351
void swap(original::objPoolAllocator< TYPE > &lhs, original::objPoolAllocator< TYPE > &rhs) noexcept
Specialization of std::swap for objPoolAllocator.
Definition allocator.h:635
Interface for polymorphic string formatting and output.