# SmartPointer Documentation `uLib::SmartPointer` is a shared ownership smart pointer implementation designed for the `uLib` ecosystem. While it shares many similarities with `std::shared_ptr`, it includes specific features for legacy compatibility, local reference wrapping, and integrated Boost serialization. ## Table of Contents 1. [Overview](#overview) 2. [Key Differences from std::shared_ptr](#key-differences-from-stdshared_ptr) 3. [Common Usage](#common-usage) 4. [Construction and Assignment](#construction-and-assignment) 5. [Wrapping References](#wrapping-references) 6. [Polymorphism and Casting](#polymorphism-and-casting) 7. [Serialization](#serialization) 8. [Thread Safety](#thread-safety) --- ## Overview A `SmartPointer` manages the lifetime of an object through reference counting. When the last `SmartPointer` owning an object is destroyed or reset, the object is automatically deleted (unless a custom deleter is provided). The implementation uses an internal `ControlBlock` to manage the reference count and an optional deleter function. ## Key Differences from std::shared_ptr | Feature | `uLib::SmartPointer` | `std::shared_ptr` | | :--- | :--- | :--- | | **Default Constructor** | Initializes to `nullptr`. | Initializes to `nullptr`. | | **Implicit Conversion** | Implicitly converts from `T*` and to `T*`. | Explicit construction from `T*`, no implicit conversion to `T*`. | | **Reference Wrapping** | Direct support for wrapping `T&` with a no-op deleter. | Requires explicit custom deleter `[](T*){}`. | | **Serialization** | Built-in Boost.Serialization support. | Requires external serialization helpers. | > [!NOTE] > The default constructor `SmartPointer()` now initializes to `nullptr`, matching standard C++ smart pointer behavior. ## Common Usage ```cpp #include "Core/SmartPointer.h" // 1. Allocation via default constructor (Allocates a new MyObject) uLib::SmartPointer ptr; // 2. Explicit null pointer uLib::SmartPointer null_ptr(nullptr); // 3. From raw pointer uLib::SmartPointer manual_ptr(new MyObject(args)); // 4. Accessing members ptr->DoSomething(); (*ptr).Value = 10; // 5. Checking validity if (ptr) { // ... } ``` ## Construction and Assignment ### Allocation and Ownership - `SmartPointer()`: Initializes to `nullptr` (Standard behavior). - `SmartPointer(nullptr)`: Initializes to null. - `SmartPointer(T* ptr)`: Takes ownership of the raw pointer (implicit conversion allowed). - `SmartPointer(T& ref)`: Wraps an existing reference with a no-op deleter (implicit conversion allowed). - `SmartPointer(T* ptr, Deleter d)`: Takes ownership and uses a custom deleter. - `SmartPointer(const SmartPointer* other)`: Creates a copy from a *pointer* to another `SmartPointer`. ### Move and Copy - Supports standard copy and move semantics. Move operations transfer ownership without incrementing the reference count. ### Pointer Access - `get()` / `Get()`: Returns the underlying raw pointer. - `operator T*()`: Implicit conversion to raw pointer (legacy support). ## Wrapping References The `SmartPointer` can wrap an existing object (e.g., on the stack) without taking ownership: ```cpp MyObject stackObj; uLib::SmartPointer spt(stackObj); // spt will NOT delete stackObj when it goes out of scope. ``` ## Polymorphism and Casting `SmartPointer` supports assignment between compatible types (base/derived). For explicit casting, use the following utilities: - `uLib::static_pointer_cast(ptr)` - `uLib::dynamic_pointer_cast(ptr)` - `uLib::const_pointer_cast(ptr)` - `uLib::reinterpret_pointer_cast(ptr)` Example: ```cpp uLib::SmartPointer derived(new Derived()); uLib::SmartPointer base = derived; // Automatic upcast auto derived2 = uLib::dynamic_pointer_cast(base); // Downcast ``` ## Serialization `SmartPointer` is fully integrated with `boost::serialization`. It tracks `ControlBlock` identity during serialization to ensure that multiple shared pointers to the same object are correctly reconstructed as a single shared instance. ```cpp #include void save(const uLib::SmartPointer& ptr, std::ostream& os) { boost::archive::text_oarchive oa(os); oa << ptr; } ``` ## Thread Safety - The reference count is managed using `std::atomic`, making the increment/decrement operations thread-safe. - **Note**: While the reference counter itself is thread-safe, the object pointed to by the `SmartPointer` is not automatically protected. Standard thread-safety rules for the underlying type `T` apply. - Multiple threads can read the same `SmartPointer` concurrently. Concurrent modification (assignment/reset) of the *same* `SmartPointer` instance by different threads requires external synchronization.