wxMaxima
|
Implementation of an observing weak Cell pointer. More...
#include <wx/debug.h>
#include <wx/log.h>
#include <utility>
#include <cstddef>
#include <cstdint>
#include <cinttypes>
#include <memory>
#include <type_traits>
Go to the source code of this file.
Data Structures | |
class | Observed |
Objects deriving from this class can be observed by the CellPtr. More... | |
class | CellPtrBase |
An implementation detail for the type-specific templated cell pointers. More... | |
class | CellPtr< T > |
A weak non-owning pointer that becomes null whenever the observed object is destroyed. More... | |
Macros | |
#define | CELLPTR_CAST_TO_PTR 1 |
Set to 1 to enable casting from CellPtr<U> to U*. | |
#define | CELLPTR_COUNT_INSTANCES 0 |
Set to 1 to count CellPtr, Observed (Cell) and Observed::ControlBlock instances. | |
#define | CELLPTR_LOG_REFS 0 |
Set to 1 to enable CellPtr control block reference count logs. | |
#define | CELLPTR_LOG_INSTANCES 0 |
Set to 1 to enable CellPtr lifetime logging. | |
#define | CELLPTR_LOG_METHOD wxLogDebug |
Set to the type of logging you wish for CellPtr (can be e.g. wxLogDebug or wxLogMessage) | |
Functions | |
void | swap (Observed::CellPtrImplPointer &a, Observed::CellPtrImplPointer &b) noexcept |
template<typename T , typename U > | |
bool | operator== (const CellPtr< T > &left, const CellPtr< U > &right) noexcept |
template<typename T , typename U , typename std::enable_if< CellPtrBase::is_pointer< U >(), bool >::type = true> | |
bool | operator== (const CellPtr< T > &left, U right) noexcept |
template<typename T , typename U > | |
bool | operator!= (const CellPtr< T > &left, const CellPtr< U > &right) noexcept |
template<typename T , typename U , typename std::enable_if< CellPtrBase::is_pointer< U >(), bool >::type = true> | |
bool | operator!= (const CellPtr< T > &left, U right) noexcept |
template<typename T , typename U > | |
bool | operator< (const CellPtr< T > &left, const CellPtr< U > &right) noexcept |
template<typename T , typename U , typename std::enable_if< CellPtrBase::is_pointer< U >(), bool >::type = true> | |
bool | operator< (const CellPtr< T > &left, U right) noexcept |
template<typename Derived , typename Base > | |
std::unique_ptr< Derived > | static_unique_ptr_cast (std::unique_ptr< Base > &&p) noexcept |
A cast for unique pointers, used to downcast to a derived type iff we're certain the cell is indeed of a derived type. | |
template<typename Derived , typename Base > | |
std::unique_ptr< Derived > | dynamic_unique_ptr_cast (std::unique_ptr< Base > &&p) noexcept |
A cast for unique pointers, used to downcast to a derived type in a type-safe manner. | |
Implementation of an observing weak Cell pointer.
It doesn't have the overhead of atomic reference counting, as would be imposed by shared_ptr. The latter has high likelihood of misuse, and suffers from the locking boilerplate needed to use the weak_ptr
. But - above all - wxMaxima's data model does not use shared ownership. All cells are have a single owner - either a cell list rooted in a unique_ptr, or are owned by internal cell pointers.
Author's Note: I'm not particularly happy with this code, since it could be factored much better. Observe that all three classes that implement this system are the same: they are a pointer. An Observed
is a pointer, a CellPtrBase
is a pointer, an an Observed::ControlBlock
is a pointer. The currently "dumb" CellPtrImplPointer
class could be at the heart of all three without any special-casing, and could better handle the reference counting in one spot. But observe the potential performance impact of subtle mistakes in any such refactoring: it takes lots of time to get it right. At the moment, we're at a point where small improvements can gain about 0.5% time reduction in the hs(17) benchmark, listed below. 0.5% time reduction is observed as 1s+ speed-up over runtime of about 180s.
hs(n):=ratsimp(ratexpand(product(x-a[i],i,1,n))); hs(17);