persistent_ptr.hpp
Go to the documentation of this file.
/*
* Copyright 2015-2017, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PMEMOBJ_PERSISTENT_PTR_HPP
#define PMEMOBJ_PERSISTENT_PTR_HPP
#include <cassert>
#include <limits>
#include <memory>
#include <ostream>
#include "libpmemobj++/detail/common.hpp"
#include "libpmemobj++/detail/persistent_ptr_base.hpp"
#include "libpmemobj++/detail/specialization.hpp"
#include "libpmemobj++/pool.hpp"
#include "libpmemobj.h"
namespace pmem
{
namespace obj
{
template <typename T>
class pool;
template <typename T>
class persistent_ptr;
/*
* persistent_ptr void specialization.
*/
template <>
class persistent_ptr<void> : public detail::persistent_ptr_base<void> {
public:
persistent_ptr() = default;
using detail::persistent_ptr_base<void>::persistent_ptr_base;
using detail::persistent_ptr_base<void>::operator=;
};
/*
* persistent_ptr const void specialization.
*/
template <>
class persistent_ptr<const void>
: public detail::persistent_ptr_base<const void> {
public:
persistent_ptr() = default;
using detail::persistent_ptr_base<const void>::persistent_ptr_base;
using detail::persistent_ptr_base<const void>::operator=;
};
template <typename T>
class persistent_ptr : public detail::persistent_ptr_base<T> {
public:
persistent_ptr() = default;
using detail::persistent_ptr_base<T>::persistent_ptr_base;
explicit persistent_ptr(persistent_ptr<void> const &rhs) noexcept
: detail::persistent_ptr_base<T>(rhs.raw())
{
}
explicit persistent_ptr(persistent_ptr<const void> const &rhs) noexcept
: detail::persistent_ptr_base<T>(rhs.raw())
{
}
operator persistent_ptr<void>() const noexcept
{
return this->get();
}
typename pmem::detail::sp_dereference<T>::type operator*() const
noexcept
{
return *this->get();
}
typename pmem::detail::sp_member_access<T>::type operator->() const
noexcept
{
return this->get();
}
template <typename = typename std::enable_if<!std::is_void<T>::value>>
typename pmem::detail::sp_array_access<T>::type
operator[](std::ptrdiff_t i) const noexcept
{
assert(i >= 0 && (i < pmem::detail::sp_extent<T>::value ||
pmem::detail::sp_extent<T>::value == 0) &&
"persistent array index out of bounds");
return this->get()[i];
}
inline persistent_ptr<T> &operator++()
{
detail::conditional_add_to_tx(this);
this->oid.off += sizeof(T);
return *this;
}
inline persistent_ptr<T> operator++(int)
{
PMEMoid noid = this->oid;
++(*this);
return persistent_ptr<T>(noid);
}
inline persistent_ptr<T> &operator--()
{
detail::conditional_add_to_tx(this);
this->oid.off -= sizeof(T);
return *this;
}
inline persistent_ptr<T> operator--(int)
{
PMEMoid noid = this->oid;
--(*this);
return persistent_ptr<T>(noid);
}
inline persistent_ptr<T> &
operator+=(std::ptrdiff_t s)
{
detail::conditional_add_to_tx(this);
this->oid.off += s * sizeof(T);
return *this;
}
inline persistent_ptr<T> &
operator-=(std::ptrdiff_t s)
{
detail::conditional_add_to_tx(this);
this->oid.off -= s * sizeof(T);
return *this;
}
void
persist(pool_base &pop)
{
pop.persist(this->get(), sizeof(T));
}
void
persist(void)
{
pmemobjpool *pop = pmemobj_pool_by_oid(this->raw());
if (pop == nullptr)
throw pool_error("Cannot get pool from "
"persistent pointer");
pmemobj_persist(pop, this->get(), sizeof(T));
}
void
flush(pool_base &pop)
{
pop.flush(this->get(), sizeof(T));
}
void
flush(void)
{
pmemobjpool *pop = pmemobj_pool_by_oid(this->raw());
if (pop == nullptr)
throw pool_error("Cannot get pool from "
"persistent pointer");
pmemobj_flush(pop, this->get(), sizeof(T));
}
/*
* Pointer traits related.
*/
static persistent_ptr<T>
pointer_to(T &ref)
{
return persistent_ptr<T>(std::addressof(ref), 0);
}
template <class U>
using rebind = pmem::obj::persistent_ptr<U>;
using persistency_type = p<T>;
using bool_type = bool;
/*
* Random access iterator requirements (members)
*/
using iterator_category = std::random_access_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = T;
using reference = T &;
using pointer = persistent_ptr<T>;
};
template <class T>
inline void
swap(persistent_ptr<T> &a, persistent_ptr<T> &b)
{
a.swap(b);
}
template <typename T, typename Y>
inline bool
operator==(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
{
return OID_EQUALS(lhs.raw(), rhs.raw());
}
template <typename T, typename Y>
inline bool
operator!=(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
{
return !(lhs == rhs);
}
template <typename T>
inline bool
operator==(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
{
return lhs.get() == nullptr;
}
template <typename T>
inline bool
operator==(std::nullptr_t, persistent_ptr<T> const &lhs) noexcept
{
return lhs.get() == nullptr;
}
template <typename T>
inline bool
operator!=(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
{
return lhs.get() != nullptr;
}
template <typename T>
inline bool
operator!=(std::nullptr_t, persistent_ptr<T> const &lhs) noexcept
{
return lhs.get() != nullptr;
}
template <typename T, typename Y>
inline bool
operator<(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
{
if (lhs.raw().pool_uuid_lo == rhs.raw().pool_uuid_lo)
return lhs.raw().off < rhs.raw().off;
else
return lhs.raw().pool_uuid_lo < rhs.raw().pool_uuid_lo;
}
template <typename T, typename Y>
inline bool
operator<=(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
{
return !(rhs < lhs);
}
template <typename T, typename Y>
inline bool
operator>(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
{
return (rhs < lhs);
}
template <typename T, typename Y>
inline bool
operator>=(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
{
return !(lhs < rhs);
}
/* nullptr comparisons */
template <typename T>
inline bool
operator<(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
{
return std::less<typename persistent_ptr<T>::element_type *>()(
lhs.get(), nullptr);
}
template <typename T>
inline bool
operator<(std::nullptr_t, persistent_ptr<T> const &rhs) noexcept
{
return std::less<typename persistent_ptr<T>::element_type *>()(
nullptr, rhs.get());
}
template <typename T>
inline bool
operator<=(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
{
return !(nullptr < lhs);
}
template <typename T>
inline bool
operator<=(std::nullptr_t, persistent_ptr<T> const &rhs) noexcept
{
return !(rhs < nullptr);
}
template <typename T>
inline bool
operator>(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
{
return nullptr < lhs;
}
template <typename T>
inline bool
operator>(std::nullptr_t, persistent_ptr<T> const &rhs) noexcept
{
return rhs < nullptr;
}
template <typename T>
inline bool
operator>=(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
{
return !(lhs < nullptr);
}
template <typename T>
inline bool
operator>=(std::nullptr_t, persistent_ptr<T> const &rhs) noexcept
{
return !(nullptr < rhs);
}
template <typename T>
inline persistent_ptr<T>
operator+(persistent_ptr<T> const &lhs, std::ptrdiff_t s)
{
PMEMoid noid;
noid.pool_uuid_lo = lhs.raw().pool_uuid_lo;
noid.off = lhs.raw().off + (s * sizeof(T));
return persistent_ptr<T>(noid);
}
template <typename T>
inline persistent_ptr<T>
operator-(persistent_ptr<T> const &lhs, std::ptrdiff_t s)
{
PMEMoid noid;
noid.pool_uuid_lo = lhs.raw().pool_uuid_lo;
noid.off = lhs.raw().off - (s * sizeof(T));
return persistent_ptr<T>(noid);
}
template <typename T, typename Y,
typename = typename std::enable_if<
std::is_same<typename std::remove_cv<T>::type,
typename std::remove_cv<Y>::type>::value>>
inline ptrdiff_t
operator-(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs)
{
assert(lhs.raw().pool_uuid_lo == rhs.raw().pool_uuid_lo);
ptrdiff_t d = lhs.raw().off - rhs.raw().off;
return d / sizeof(T);
}
template <typename T>
std::ostream &
operator<<(std::ostream &os, persistent_ptr<T> const &pptr)
{
PMEMoid raw_oid = pptr.raw();
os << std::hex << "0x" << raw_oid.pool_uuid_lo << ", 0x" << raw_oid.off
<< std::dec;
return os;
}
} /* namespace obj */
} /* namespace pmem */
#endif /* PMEMOBJ_PERSISTENT_PTR_HPP */
pmem::obj::operator==
bool operator==(standard_alloc_policy< T > const &, standard_alloc_policy< T2 > const &)
Determines if memory from another allocator can be deallocated from this one.
Definition: allocator.hpp:406
pmem::obj::persistent_ptr::operator++
persistent_ptr< T > & operator++()
Prefix increment operator.
Definition: persistent_ptr.hpp:168
pmem::detail::persistent_ptr_base
Persistent_ptr base class.
Definition: persistent_ptr_base.hpp:62
pmem::obj::persistent_ptr::persist
void persist(void)
Persists what the persistent pointer points to.
Definition: persistent_ptr.hpp:251
specialization.hpp
Helper template for persistent ptr specialization.
pmem::obj::persistent_ptr
Persistent pointer class.
Definition: common.hpp:51
pmem::obj::persistent_ptr::operator->
pmem::detail::sp_member_access< T >::type operator->() const noexcept
Member access operator.
Definition: persistent_ptr.hpp:143
pmem::obj::pool_base
The non-template pool base class.
Definition: pool.hpp:65
pmem::detail::persistent_ptr_base::swap
void swap(persistent_ptr_base &other)
Swaps two persistent_ptr objects of the same type.
Definition: persistent_ptr_base.hpp:263
pmem::pool_error
Custom pool error class.
Definition: pexceptions.hpp:53
pmem::obj::persistent_ptr::operator-=
persistent_ptr< T > & operator-=(std::ptrdiff_t s)
Subtraction assignment operator.
Definition: persistent_ptr.hpp:225
pmem::obj::persistent_ptr::persistent_ptr
persistent_ptr(persistent_ptr< const void > const &rhs) noexcept
Explicit const void specialization of the converting constructor.
Definition: persistent_ptr.hpp:118
pmem::obj::persistent_ptr::operator++
persistent_ptr< T > operator++(int)
Postfix increment operator.
Definition: persistent_ptr.hpp:179
pmem::obj::operator>=
bool operator>=(persistent_ptr< T > const &lhs, persistent_ptr< Y > const &rhs) noexcept
Greater or equal than operator.
Definition: persistent_ptr.hpp:478
pmem::obj::persistent_ptr::persist
void persist(pool_base &pop)
Persists the content of the underlying object.
Definition: persistent_ptr.hpp:239
pmem::obj::persistent_ptr::bool_type
bool bool_type
The used bool_type.
Definition: persistent_ptr.hpp:323
pmem::obj::persistent_ptr::flush
void flush(pool_base &pop)
Flushes what the persistent pointer points to.
Definition: persistent_ptr.hpp:268
pmem::obj::pool
PMEMobj pool class.
Definition: persistent_ptr.hpp:59
pmem::obj::persistent_ptr::operator--
persistent_ptr< T > operator--(int)
Postfix decrement operator.
Definition: persistent_ptr.hpp:201
pmem::obj::operator+
persistent_ptr< T > operator+(persistent_ptr< T > const &lhs, std::ptrdiff_t s)
Addition operator for persistent pointers.
Definition: persistent_ptr.hpp:572
common.hpp
Commonly used functionality.
pmem::obj::persistent_ptr::iterator_category
std::random_access_iterator_tag iterator_category
The persistent_ptr iterator category.
Definition: persistent_ptr.hpp:332
pmem::obj::persistent_ptr::operator--
persistent_ptr< T > & operator--()
Prefix decrement operator.
Definition: persistent_ptr.hpp:190
pmem::obj::persistent_ptr::operator+=
persistent_ptr< T > & operator+=(std::ptrdiff_t s)
Addition assignment operator.
Definition: persistent_ptr.hpp:213
pmem::obj::persistent_ptr::flush
void flush(void)
Flushes what the persistent pointer points to.
Definition: persistent_ptr.hpp:280
pmem::obj::pool_base::persist
void persist(const void *addr, size_t len) noexcept
Performs persist operation on a given chunk of memory.
Definition: pool.hpp:282
pmem::obj::persistent_ptr::operator[]
pmem::detail::sp_array_access< T >::type operator[](std::ptrdiff_t i) const noexcept
Array access operator.
Definition: persistent_ptr.hpp:156
pmem::obj::persistent_ptr::pointer_to
static persistent_ptr< T > pointer_to(T &ref)
Create a persistent pointer from a given reference.
Definition: persistent_ptr.hpp:304
pmem::obj::operator-
persistent_ptr< T > operator-(persistent_ptr< T > const &lhs, std::ptrdiff_t s)
Subtraction operator for persistent pointers.
Definition: persistent_ptr.hpp:585
pmem::detail::persistent_ptr_base::raw
const PMEMoid & raw() const noexcept
Get PMEMoid encapsulated by this object.
Definition: persistent_ptr_base.hpp:296
pmem::obj::persistent_ptr::operator*
pmem::detail::sp_dereference< T >::type operator*() const noexcept
Dereference operator.
Definition: persistent_ptr.hpp:134
pmem::obj::p
Resides on pmem class.
Definition: p.hpp:64
pmem::obj::operator!=
bool operator!=(const allocator< T, P, Tr > &lhs, const OtherAllocator &rhs)
Determines if memory from another allocator can be deallocated from this one.
Definition: allocator.hpp:522
pmem::obj::persistent_ptr::value_type
T value_type
The type of the value pointed to by the persistent_ptr.
Definition: persistent_ptr.hpp:342
pmem
Definition: allocator.hpp:48
pmem::obj::pool_base::flush
void flush(const void *addr, size_t len) noexcept
Performs flush operation on a given chunk of memory.
Definition: pool.hpp:318
pmem::obj::persistent_ptr::difference_type
std::ptrdiff_t difference_type
The persistent_ptr difference type.
Definition: persistent_ptr.hpp:337
pmem::obj::operator>
bool operator>(persistent_ptr< T > const &lhs, persistent_ptr< Y > const &rhs) noexcept
Greater than operator.
Definition: persistent_ptr.hpp:466
pmem::obj::persistent_ptr::persistent_ptr
persistent_ptr(persistent_ptr< void > const &rhs) noexcept
Explicit void specialization of the converting constructor.
Definition: persistent_ptr.hpp:110
pool.hpp
C++ pmemobj pool.
pmem::obj::persistent_ptr::reference
T & reference
The reference type of the value pointed to by the persistent_ptr.
Definition: persistent_ptr.hpp:347