Skip to content
DryPerspective edited this page Sep 23, 2023 · 4 revisions

A recreation of the standard <memory> header, for high-level memory manipulation. While a surprising amount of the modern header relies on variadic templates, some if it can be safely reimplemented into C++98.

Note that this header includes shared_ptr and scoped_ptr.

As the memory header itself is very comprehensive, these pointers are offered separately from the core functions which were reimplemented, in an attempt to prevent the entire memory header from slowing compile times for users who only really want to use a smart pointer.

Features

Included headers:

shared_ptr A copyable, reference-counted smart pointer type, with support types included
scoped_ptr A simple, uncopyable, scoped-based smart pointer which models unique ownership

Functionality:

pointer_traits Provides general information about pointer types
uses_allocator Checks if the specified type supports "uses-allocator" construction
to_address Obtains a raw pointer from an applicable pointer type
addressof Obtains the address of an object, even if operator& is overloaded
uninitialized_copy_n Copies a number of elements into uninitialized memory
uninitialized_default_construct Default-constructs objects into a region of uninitialised memory, by range
uninitialized_default_construct_n Default-constructs a number of objects into a region of uninitialised memory
uninitialized_value_construct Value-constructs objects into a region of uninitialised memory, by range
uninitialized_value_construct_n Value-constructs a number of objects into a region of uninitialised memory.
destroy_at Destroys the object at a given address
destroy Destroys a range of objects
destroy_n Destroys a number of objects

Sample code

#include <iostream>
#include "cpp98/memory.h"
 
template<class T>
struct Ptr
{
    T* pad; // add pad to show difference between 'this' and 'data'
    T* data;
    Ptr(T* arg) : pad(NULL), data(arg)
    {
        std::cout << "Ctor this = " << this << '\n';
    }
 
    ~Ptr() { delete data; }
    T** operator&() { return &data; }
};
 
template<class T>
void f(Ptr<T>* p)
{
    std::cout << "Ptr   overload called with p = " << p << '\n';
}
 
void f(int** p)
{
    std::cout << "int** overload called with p = " << p << '\n';
}
 
int main()
{
    Ptr<int> p(new int(42));
    f(&p);                // calls int** overload
    f(dp::addressof(p)); // calls Ptr<int>* overload, (= this)
}

Clone this wiki locally