Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef SHARED_PTR_GUARD
- #define SHARED_PTR_GUARD
- #include <algorithm>
- #include <iostream>
- namespace ptrs::shared {
- template <typename T>
- struct shared_ptr {
- private:
- T *ptr_on_object = nullptr;
- int *use_count = nullptr;
- void delete_data() {
- if (use_count == nullptr) {
- return;
- }
- if (*use_count == 1) {
- delete use_count;
- delete ptr_on_object;
- } else {
- --*use_count;
- }
- }
- public:
- // invariant: if user give ptr == nullptr, then counter=nullptr, else
- // counter=1
- shared_ptr() = default;
- explicit shared_ptr(T *cur_ptr)
- : ptr_on_object(std::exchange(cur_ptr, nullptr)),
- use_count(new int{1}) {
- }
- explicit shared_ptr(std::nullptr_t) {
- }
- shared_ptr(const shared_ptr &other)
- : ptr_on_object(other.ptr_on_object),
- // cppcheck-suppress copyCtorPointerCopying
- use_count(other.use_count) {
- if (use_count != nullptr) {
- ++*use_count;
- }
- }
- shared_ptr(shared_ptr &&other)
- : ptr_on_object(std::exchange(other.ptr_on_object, nullptr)),
- use_count(std::exchange(other.use_count, nullptr)) {
- }
- shared_ptr &operator=(const shared_ptr &other) {
- if (other.ptr_on_object == ptr_on_object) {
- return *this;
- }
- delete_data();
- ptr_on_object = other.ptr_on_object;
- use_count = other.use_count;
- if (use_count != nullptr) {
- ++*use_count;
- }
- return *this;
- }
- shared_ptr &operator=(shared_ptr &&other) {
- if (other.ptr_on_object == ptr_on_object) {
- return *this;
- }
- delete_data();
- ptr_on_object = std::exchange(other.ptr_on_object, nullptr);
- use_count = std::exchange(other.use_count, nullptr);
- return *this;
- }
- ~shared_ptr() {
- delete_data();
- }
- [[nodiscard]] T *get() const {
- return ptr_on_object;
- }
- explicit operator bool() const {
- return ptr_on_object != nullptr;
- }
- friend void swap(shared_ptr<T> &a, shared_ptr<T> &b) {
- std::swap(a.ptr_on_object, b.ptr_on_object);
- std::swap(a.use_count, b.use_count);
- }
- [[nodiscard]] T *release() {
- if (use_count != nullptr) {
- --*use_count;
- }
- use_count = nullptr;
- return std::exchange(ptr_on_object, nullptr);
- }
- void reset() {
- delete_data();
- use_count = nullptr;
- ptr_on_object = nullptr;
- }
- void reset(T *other) {
- delete_data();
- if (other != nullptr) {
- use_count = new int{1};
- } else {
- use_count = nullptr;
- }
- ptr_on_object = std::exchange(other, nullptr);
- }
- [[nodiscard]] T &operator*() const {
- return *get();
- }
- [[nodiscard]] T *operator->() const {
- return get();
- }
- [[nodiscard]] bool operator==(const shared_ptr &other) const {
- return ptr_on_object == other.ptr_on_object;
- }
- [[nodiscard]] bool operator!=(const shared_ptr &other) const {
- return ptr_on_object != other.ptr_on_object;
- }
- };
- } // namespace ptrs::shared
- #endif
Advertisement
Add Comment
Please, Sign In to add comment