#pragma once #include #include "Test.hpp" namespace smart_pointer { // `exception` class definition class exception : std::exception { using base_class = std::exception; using base_class::base_class; }; // `SmartPointer` class declaration template class SmartPointer { // don't remove this macro ENABLE_CLASS_TESTS; public: using value_type = T; explicit SmartPointer(value_type *new_core = nullptr) : Core(new_core) {} // copy constructor SmartPointer(const SmartPointer &other_core) : Core(other_core) {} // move constructor SmartPointer(SmartPointer &&other_core) : Core(other_core) {} // copy assigment SmartPointer &operator=(const SmartPointer &other_core) { core = other_core; return *core; } // move assigment SmartPointer &operator=(SmartPointer &&other_core) { core = other_core; return *core; } // SmartPointer &operator=(value_type *other_core) { core = other_core; return *core; } ~SmartPointer(); // return reference to the object of class/type T // if SmartPointer contains nullptr throw `SmartPointer::exception` value_type &operator*() { if (core == nullptr) { throw; } return *core; } const value_type &operator*() const { if (core == nullptr) { throw; } return *core; } // return pointer to the object of class/type T value_type *operator->() const { return core; } value_type *get() const { return *core; } // if pointer == nullptr => return false operator bool() const { return core == nullptr; } // if pointers points to the same address or both null => true template bool operator==(const SmartPointer &rhs) const { return (core == rhs) || ((core == nullptr) && (rhs == nullptr)); } // if pointers points to the same address or both null => false template bool operator!=(const SmartPointer &rhs) const { return (core != rhs) || ((core != nullptr) && (rhs != nullptr)); } // if smart pointer contains non-nullptr => return count owners // if smart pointer contains nullptr => return 0 std::size_t count_owners() const { return core->count_owners(); } private: class Core { public: explicit Core(value_type *new_value) { if (new_value == nullptr) { count_owners_ = 0; } else { value = *new_value; ++count_owners_; } } size_t count_owners() const { return count_owners_; } private: size_t count_owners_; value_type value; }; Core *core; }; } // namespace smart_pointer