ENH: support cref() and shallow copies (refPtr and tmp)
- enables building HashTables with shadowed variables - support good() and valid() as synonyms in memory classes
This commit is contained in:
parent
96735dce20
commit
92d52243af
@ -32,14 +32,22 @@ struct myScalarField : public scalarField
|
||||
template<class T>
|
||||
void printInfo(const refPtr<T>& item, const bool verbose = false)
|
||||
{
|
||||
Info<< "refPtr valid:" << Switch::name(item.valid())
|
||||
Info<< "refPtr good:" << Switch::name(item.good())
|
||||
<< " pointer:" << Switch::name(item.is_pointer())
|
||||
<< " addr: " << name(item.get())
|
||||
<< " addr: " << Foam::name(item.get())
|
||||
<< " movable:" << Switch(item.movable());
|
||||
|
||||
Info<< nl;
|
||||
Info<< " move-constructible:"
|
||||
<< std::is_move_constructible<refPtr<T>>::value
|
||||
<< " move-assignable:"
|
||||
<< std::is_move_assignable<refPtr<T>>::value
|
||||
<< " nothrow:"
|
||||
<< std::is_nothrow_move_assignable<refPtr<T>>::value
|
||||
<< " trivially:"
|
||||
<< std::is_trivially_move_assignable<refPtr<T>>::value
|
||||
<< nl;
|
||||
|
||||
if (verbose && item.valid())
|
||||
if (verbose && item)
|
||||
{
|
||||
Info<< "content: " << item() << nl;
|
||||
}
|
||||
|
@ -32,18 +32,26 @@ struct myScalarField : public scalarField
|
||||
template<class T>
|
||||
void printInfo(const tmp<T>& item, const bool verbose = false)
|
||||
{
|
||||
Info<< "tmp valid:" << Switch::name(item.valid())
|
||||
Info<< "tmp good:" << Switch::name(item.good())
|
||||
<< " pointer:" << Switch::name(item.is_pointer())
|
||||
<< " addr: " << name(item.get())
|
||||
<< " addr: " << Foam::name(item.get())
|
||||
<< " movable:" << Switch(item.movable());
|
||||
|
||||
if (item.valid())
|
||||
if (item)
|
||||
{
|
||||
Info<< " refCount:" << item->count();
|
||||
}
|
||||
Info<< nl;
|
||||
|
||||
if (verbose && item.valid())
|
||||
Info<< " move-constructible:"
|
||||
<< std::is_move_constructible<tmp<T>>::value
|
||||
<< " move-assignable:"
|
||||
<< std::is_move_assignable<tmp<T>>::value
|
||||
<< " nothrow:"
|
||||
<< std::is_nothrow_move_assignable<tmp<T>>::value
|
||||
<< " trivially:"
|
||||
<< std::is_trivially_move_assignable<tmp<T>>::value
|
||||
<< nl;
|
||||
|
||||
if (verbose && item)
|
||||
{
|
||||
Info<< "content: " << item() << nl;
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ public:
|
||||
bool active() const noexcept
|
||||
{
|
||||
// Same as refPtr::movable()
|
||||
return (this->is_pointer() && this->valid());
|
||||
return (this->is_pointer() && this->good());
|
||||
}
|
||||
|
||||
//- Commit adapted content changes (no-op for const adaptor)
|
||||
@ -253,13 +253,13 @@ public:
|
||||
bool active() const noexcept
|
||||
{
|
||||
// Same as refPtr::movable()
|
||||
return (this->is_pointer() && this->valid());
|
||||
return (this->is_pointer() && this->good());
|
||||
}
|
||||
|
||||
//- Commit adapted content changes back to original input (as required)
|
||||
void commit()
|
||||
{
|
||||
if (this->active() && orig_.valid())
|
||||
if (this->active() && orig_.good())
|
||||
{
|
||||
const auto& stored = this->cref();
|
||||
auto& input = orig_.ref();
|
||||
|
@ -143,7 +143,7 @@ public:
|
||||
// Query
|
||||
|
||||
//- True if the managed pointer is non-null
|
||||
bool valid() const noexcept { return bool(ptr_); }
|
||||
bool good() const noexcept { return bool(ptr_); }
|
||||
|
||||
|
||||
// Access
|
||||
@ -165,6 +165,7 @@ public:
|
||||
// Edit
|
||||
|
||||
//- Release ownership and return the pointer.
|
||||
// \remark Method naming consistent with std::unique_ptr
|
||||
inline T* release() noexcept;
|
||||
|
||||
//- Same as \c release().
|
||||
@ -175,6 +176,7 @@ public:
|
||||
// \remark Method naming consistent with Foam::tmp
|
||||
void clear() noexcept { reset(nullptr); }
|
||||
|
||||
|
||||
//- Delete managed object and set to new given pointer
|
||||
// \remark Same as move assign, but better for code documentation
|
||||
inline void reset(autoPtr<T>&& other) noexcept;
|
||||
@ -224,7 +226,7 @@ public:
|
||||
|
||||
// Casting
|
||||
|
||||
//- True if pointer/reference is non-null. Same as valid()
|
||||
//- True if pointer/reference is non-null. Same as good()
|
||||
explicit operator bool() const noexcept { return bool(ptr_); }
|
||||
|
||||
//- Cast to pointer type
|
||||
@ -267,6 +269,9 @@ public:
|
||||
|
||||
// Housekeeping
|
||||
|
||||
//- Identical to good(), or bool operator
|
||||
bool valid() const noexcept { return bool(ptr_); }
|
||||
|
||||
//- Deprecated(2020-07) True if the managed pointer is null
|
||||
//
|
||||
// \deprecated(2020-07) - use bool operator
|
||||
@ -285,6 +290,8 @@ public:
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Global Functions
|
||||
|
||||
//- Specializes the Swap algorithm for autoPtr.
|
||||
|
@ -151,8 +151,8 @@ public:
|
||||
|
||||
// Query
|
||||
|
||||
//- True for non-null pointer/reference
|
||||
bool valid() const noexcept { return bool(ptr_); }
|
||||
//- True if pointer/reference is non-null.
|
||||
bool good() const noexcept { return bool(ptr_); }
|
||||
|
||||
//- If the stored/referenced content is const
|
||||
bool is_const() const noexcept { return type_ == CREF; }
|
||||
@ -187,20 +187,27 @@ public:
|
||||
// Fatal for a null managed pointer.
|
||||
inline T& constCast() const;
|
||||
|
||||
//- Return a shallow copy as a wrapped reference, preserving the
|
||||
//- const/non-const status.
|
||||
inline refPtr<T> shallowClone() const noexcept;
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
//- Release ownership and return the pointer.
|
||||
//- A no-op for reference objects (returns nullptr).
|
||||
// \remark Method naming consistent with std::unique_ptr
|
||||
inline T* release() noexcept;
|
||||
|
||||
//- Return managed pointer for reuse, or clone() the object reference.
|
||||
// \remark Method naming consistent with Foam::tmp
|
||||
inline T* ptr() const;
|
||||
|
||||
//- If object pointer points to valid object:
|
||||
//- delete object and set pointer to nullptr
|
||||
inline void clear() const noexcept;
|
||||
|
||||
|
||||
//- Clear existing and transfer ownership.
|
||||
inline void reset(refPtr<T>&& other) noexcept;
|
||||
|
||||
@ -213,6 +220,10 @@ public:
|
||||
//- Clear existing and transfer ownership from unique_ptr
|
||||
void reset(std::unique_ptr<T>&& other) { reset(other.release()); }
|
||||
|
||||
|
||||
//- Clear existing and set (const) reference from other
|
||||
inline void cref(const refPtr<T>& other) noexcept;
|
||||
|
||||
//- Clear existing and set (const) reference
|
||||
inline void cref(const T& obj) noexcept;
|
||||
|
||||
@ -220,6 +231,7 @@ public:
|
||||
// The pointer can be null, which is handled like a clear().
|
||||
inline void cref(const T* p) noexcept;
|
||||
|
||||
|
||||
//- Clear existing and set (non-const) reference
|
||||
inline void ref(T& obj) noexcept;
|
||||
|
||||
@ -227,6 +239,7 @@ public:
|
||||
// The pointer can be null, which is handled like a clear().
|
||||
inline void ref(T* p) noexcept;
|
||||
|
||||
|
||||
//- Swaps the managed object with other.
|
||||
inline void swap(refPtr<T>& other) noexcept;
|
||||
|
||||
@ -252,11 +265,17 @@ public:
|
||||
//- Return const reference to the object - same as cref() method.
|
||||
const T& operator()() const { return cref(); }
|
||||
|
||||
|
||||
// Casting
|
||||
|
||||
//- True if pointer/reference is non-null. Same as good()
|
||||
explicit operator bool() const noexcept { return bool(ptr_); }
|
||||
|
||||
//- Cast to underlying data type, using the cref() method.
|
||||
operator const T&() const { return cref(); }
|
||||
|
||||
//- True if pointer/reference is non-null. Same as valid()
|
||||
explicit operator bool() const noexcept { return bool(ptr_); }
|
||||
|
||||
// Assignment
|
||||
|
||||
//- Transfer ownership of the managed pointer.
|
||||
// Fatal for a null managed pointer or if the object is const.
|
||||
@ -278,6 +297,9 @@ public:
|
||||
|
||||
// Housekeeping
|
||||
|
||||
//- Identical to good(), or bool operator
|
||||
bool valid() const noexcept { return bool(ptr_); }
|
||||
|
||||
//- Deprecated(2020-07) True if a null managed pointer
|
||||
//
|
||||
// \deprecated(2020-07) - use bool operator
|
||||
@ -286,6 +308,8 @@ public:
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Global Functions
|
||||
|
||||
//- Specialized Swap algorithm for refPtr.
|
||||
|
@ -167,6 +167,8 @@ inline Foam::refPtr<T>::refPtr(const refPtr<T>& rhs, bool reuse)
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
inline Foam::refPtr<T>::~refPtr()
|
||||
{
|
||||
@ -200,7 +202,7 @@ inline const T& Foam::refPtr<T>::cref() const
|
||||
template<class T>
|
||||
inline T& Foam::refPtr<T>::ref() const
|
||||
{
|
||||
if (type_ == CREF)
|
||||
if (is_const())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Attempted non-const reference to const object: "
|
||||
@ -225,6 +227,21 @@ inline T& Foam::refPtr<T>::constCast() const
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::refPtr<T> Foam::refPtr<T>::shallowClone() const noexcept
|
||||
{
|
||||
refPtr<T> dup;
|
||||
|
||||
if (ptr_)
|
||||
{
|
||||
dup.ptr_ = ptr_;
|
||||
dup.type_ = (is_const() ? CREF : REF);
|
||||
}
|
||||
|
||||
return dup;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline T* Foam::refPtr<T>::release() noexcept
|
||||
{
|
||||
@ -299,6 +316,20 @@ inline void Foam::refPtr<T>::reset(refPtr<T>&& other) noexcept
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void Foam::refPtr<T>::cref(const refPtr<T>& other) noexcept
|
||||
{
|
||||
if (&other == this)
|
||||
{
|
||||
return; // Self-assignment is a no-op
|
||||
}
|
||||
|
||||
clear();
|
||||
ptr_ = other.ptr_;
|
||||
type_ = (ptr_ ? CREF : PTR);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void Foam::refPtr<T>::cref(const T& obj) noexcept
|
||||
{
|
||||
@ -368,7 +399,7 @@ inline const T& Foam::refPtr<T>::operator*() const
|
||||
template<class T>
|
||||
inline T& Foam::refPtr<T>::operator*()
|
||||
{
|
||||
if (type_ == CREF)
|
||||
if (is_const())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Attempt to cast const object to non-const: "
|
||||
@ -403,7 +434,7 @@ inline const T* Foam::refPtr<T>::operator->() const
|
||||
template<class T>
|
||||
inline T* Foam::refPtr<T>::operator->()
|
||||
{
|
||||
if (type_ == CREF)
|
||||
if (is_const())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Attempt to cast const object to non-const: "
|
||||
|
@ -166,8 +166,8 @@ public:
|
||||
|
||||
// Query
|
||||
|
||||
//- True if pointer/reference is non-null
|
||||
bool valid() const noexcept { return bool(ptr_); }
|
||||
//- True if pointer/reference is non-null.
|
||||
bool good() const noexcept { return bool(ptr_); }
|
||||
|
||||
//- If the stored/referenced content is const
|
||||
bool is_const() const noexcept { return type_ == CREF; }
|
||||
@ -175,9 +175,6 @@ public:
|
||||
//- True if this is a managed pointer (not a reference)
|
||||
bool is_pointer() const noexcept { return type_ == PTR; }
|
||||
|
||||
//- Identical to is_pointer()
|
||||
bool isTmp() const noexcept { return type_ == PTR; }
|
||||
|
||||
//- True if this is a non-null managed pointer with a unique ref-count
|
||||
inline bool movable() const noexcept;
|
||||
|
||||
@ -215,12 +212,17 @@ public:
|
||||
//- delete object and set pointer to nullptr
|
||||
inline void clear() const noexcept;
|
||||
|
||||
|
||||
//- Clear existing and transfer ownership.
|
||||
inline void reset(tmp<T>&& other) noexcept;
|
||||
|
||||
//- Delete managed temporary object and set to new given pointer
|
||||
inline void reset(T* p = nullptr) noexcept;
|
||||
|
||||
|
||||
//- Clear existing and set (const) reference from other
|
||||
inline void cref(const tmp<T>& other) noexcept;
|
||||
|
||||
//- Clear existing and set (const) reference
|
||||
inline void cref(const T& obj) noexcept;
|
||||
|
||||
@ -228,6 +230,7 @@ public:
|
||||
// The pointer can be null, which is handled like a clear().
|
||||
inline void cref(const T* p) noexcept;
|
||||
|
||||
|
||||
//- Clear existing and set to (non-const) reference
|
||||
inline void ref(T& obj) noexcept;
|
||||
|
||||
@ -235,12 +238,17 @@ public:
|
||||
// The pointer can be null, which is handled like a clear().
|
||||
inline void ref(T* p) noexcept;
|
||||
|
||||
|
||||
//- Swaps the managed object with other.
|
||||
inline void swap(tmp<T>& other) noexcept;
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
// Note: no 'operator*()' types since there are large chunks
|
||||
// of code that use tmp\<Field\> and Field interchangeable
|
||||
// Eg, \code (a * b) - and the '*' would be misinterpreted
|
||||
|
||||
//- Dereferences (const) pointer to the managed object.
|
||||
// Fatal for a null managed pointer.
|
||||
inline const T* operator->() const;
|
||||
@ -252,11 +260,17 @@ public:
|
||||
//- Return const reference to the object - same as cref() method.
|
||||
const T& operator()() const { return cref(); }
|
||||
|
||||
|
||||
// Casting
|
||||
|
||||
//- True if pointer/reference is non-null. Same as good()
|
||||
explicit operator bool() const noexcept { return bool(ptr_); }
|
||||
|
||||
//- Cast to underlying data type, using the cref() method.
|
||||
operator const T&() const { return cref(); }
|
||||
|
||||
//- True if pointer/reference is non-null. Same as valid()
|
||||
explicit operator bool() const noexcept { return bool(ptr_); }
|
||||
|
||||
// Assignment
|
||||
|
||||
//- Transfer ownership of the managed pointer.
|
||||
// Fatal for a null managed pointer or if the object is const.
|
||||
@ -275,6 +289,12 @@ public:
|
||||
|
||||
// Housekeeping
|
||||
|
||||
//- Identical to good(), or bool operator
|
||||
bool valid() const noexcept { return bool(ptr_); }
|
||||
|
||||
//- Identical to is_pointer()
|
||||
bool isTmp() const noexcept { return type_ == PTR; }
|
||||
|
||||
//- Deprecated(2020-07) True if a null managed pointer
|
||||
//
|
||||
// \deprecated(2020-07) - use bool operator
|
||||
@ -283,6 +303,8 @@ public:
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Global Functions
|
||||
|
||||
//- Specialized Swap algorithm for tmp.
|
||||
|
@ -191,6 +191,8 @@ inline Foam::tmp<T>::tmp(const tmp<T>& rhs, bool reuse)
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
inline Foam::tmp<T>::~tmp()
|
||||
{
|
||||
@ -224,7 +226,7 @@ inline const T& Foam::tmp<T>::cref() const
|
||||
template<class T>
|
||||
inline T& Foam::tmp<T>::ref() const
|
||||
{
|
||||
if (type_ == CREF)
|
||||
if (is_const())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Attempted non-const reference to const object: "
|
||||
@ -325,6 +327,20 @@ inline void Foam::tmp<T>::reset(tmp<T>&& other) noexcept
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void Foam::tmp<T>::cref(const tmp<T>& other) noexcept
|
||||
{
|
||||
if (&other == this)
|
||||
{
|
||||
return; // Self-assignment is a no-op
|
||||
}
|
||||
|
||||
clear();
|
||||
ptr_ = other.ptr_;
|
||||
type_ = (ptr_ ? CREF : PTR);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void Foam::tmp<T>::cref(const T& obj) noexcept
|
||||
{
|
||||
@ -395,7 +411,7 @@ inline const T* Foam::tmp<T>::operator->() const
|
||||
template<class T>
|
||||
inline T* Foam::tmp<T>::operator->()
|
||||
{
|
||||
if (type_ == CREF)
|
||||
if (is_const())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Attempt to cast const object to non-const: "
|
||||
|
Loading…
Reference in New Issue
Block a user