PMDK C++ bindings  1.10.1
This is the C++ bindings documentation for PMDK's libpmemobj.
Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions | List of all members
pmem::obj::persistent_ptr< T > Class Template Reference

Persistent pointer class. More...

#include <libpmemobj++/persistent_ptr.hpp>

Public Types

typedef pmem::detail::sp_element< T >::type element_type
 Type of the actual object with all qualifiers removed, used for easy underlying type access.
 
template<class U >
using rebind = pmem::obj::persistent_ptr< U >
 Rebind to a different type of pointer.
 
using persistency_type = p< T >
 The persistency type to be used with this pointer.
 
using bool_type = bool
 The used bool_type.
 
using iterator_category = std::random_access_iterator_tag
 Random access iterator requirements (members) More...
 
using difference_type = std::ptrdiff_t
 The persistent_ptr difference type.
 
using value_type = T
 The type of the value pointed to by the persistent_ptr.
 
using reference = T &
 The reference type of the value pointed to by the persistent_ptr.
 
using pointer = persistent_ptr< T >
 The pointer type.
 

Public Member Functions

 persistent_ptr (persistent_ptr< void > const &rhs) noexcept
 Explicit void specialization of the converting constructor.
 
 persistent_ptr (persistent_ptr< const void > const &rhs) noexcept
 Explicit const void specialization of the converting constructor.
 
 persistent_ptr (element_type *ptr)
 Volatile pointer constructor. More...
 
template<typename U , typename = typename std::enable_if< !std::is_same<T, U>::value && std::is_same<typename std::remove_cv<T>::type, U>::value>::type>
 persistent_ptr (persistent_ptr< U > const &r) noexcept
 Copy constructor from a different persistent_ptr<>. More...
 
template<typename U , typename Dummy = void, typename = typename std::enable_if< !std::is_same< typename std::remove_cv<T>::type, typename std::remove_cv<U>::type>::value && !std::is_void<U>::value, decltype(static_cast<T *>(std::declval<U *>()))>::type>
 persistent_ptr (persistent_ptr< U > const &r) noexcept
 Copy constructor from a different persistent_ptr<>. More...
 
 operator persistent_ptr< void > () const noexcept
 Persistent pointer to void conversion operator.
 
pmem::detail::sp_dereference< T >::type operator* () const noexcept
 Dereference operator.
 
pmem::detail::sp_member_access< T >::type operator-> () const noexcept
 Member access operator.
 
template<typename = typename std::enable_if<!std::is_void<T>::value>>
pmem::detail::sp_array_access< T >::type operator[] (std::ptrdiff_t i) const noexcept
 Array access operator. More...
 
persistent_ptr< T > & operator++ ()
 Prefix increment operator.
 
persistent_ptr< T > operator++ (int)
 Postfix increment operator.
 
persistent_ptr< T > & operator-- ()
 Prefix decrement operator.
 
persistent_ptr< T > operator-- (int)
 Postfix decrement operator.
 
persistent_ptr< T > & operator+= (std::ptrdiff_t s)
 Addition assignment operator.
 
persistent_ptr< T > & operator-= (std::ptrdiff_t s)
 Subtraction assignment operator.
 
template<typename Y , typename = typename std::enable_if< std::is_convertible<Y *, T *>::value>::type>
persistent_ptr< T > & operator= (persistent_ptr< Y > const &r)
 Converting assignment operator from a different persistent_ptr<>. More...
 
void persist (pool_base &pop)
 Persists the content of the underlying object. More...
 
void persist (void)
 Persists what the persistent pointer points to. More...
 
void flush (pool_base &pop)
 Flushes what the persistent pointer points to. More...
 
void flush (void)
 Flushes what the persistent pointer points to. More...
 
element_typeget () const noexcept
 Get the direct pointer. More...
 
 persistent_ptr_base () noexcept
 Default constructor, zeroes the PMEMoid.
 
 persistent_ptr_base (PMEMoid oid) noexcept
 PMEMoid constructor. More...
 
 persistent_ptr_base (persistent_ptr_base &&r) noexcept
 Move constructor.
 

Static Public Member Functions

static persistent_ptr< T > pointer_to (T &ref)
 Create a persistent pointer from a given reference. More...
 

Protected Member Functions

void verify_type ()
 Verify if element_type is not polymorphic.
 
 persistent_ptr (element_type *vptr, int)
 Private constructor enabling persistent_ptrs to volatile objects. More...
 
template<typename U >
ptrdiff_t calculate_offset () const
 Calculate in-object offset for structures with inheritance. More...
 

Detailed Description

template<typename T>
class pmem::obj::persistent_ptr< T >

Persistent pointer class.

persistent_ptr implements a smart ptr. It encapsulates the PMEMoid fat pointer and provides member access, dereference and array access operators.

Template parameter type has following requirements:

Even if all of the above requirements are met, type representation may vary depending on ABI and compiler optimizations (as stated in [class.mem]: "the order of allocation of non-static data members with different access control is unspecified"). To enforce the same layout for all ABIs and optimization levels type should satisfy StandardLayoutType requirement.

If persistent_ptr is used with array type, additional requirement is:

The persistent_ptr is not designed to work with polymorphic types, as they have runtime RTTI info embedded, which is implementation specific and thus not consistently rebuildable. Such constructs as polymorphic members or members of a union defined within a class held in a persistent_ptr will also yield undefined behavior.

C++ standard states that lifetime of an object is a runtime property [basic.lifetime]. Conditions which must be fulfilled for object's lifetime to begin, imply that using any non-trivially constructible object with persistent_ptr is undefined behaviour. This is being partially addressed by the following proposal: https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/bk8esqk-Qoo

Another caveat is that snapshotting elements in a transaction and performing rollback uses memcpy internally. Using memcpy on an object in C++ is allowed by the standard only if the type satisfies TriviallyCopyable requirement.

This type does NOT manage the life-cycle of the object. The typical usage example would be:

#include <fcntl.h>
using namespace pmem::obj;
void
persistent_ptr_example()
{
struct compound_type {
void
set_some_variable(int val)
{
some_variable = val;
}
int some_variable;
double some_other_variable;
};
// pool root structure
struct root {
} proot;
// create a pmemobj pool
auto pop = pool<root>::create("poolfile", "layout", PMEMOBJ_MIN_POOL);
// typical usage schemes
transaction::run(pop, [&] {
proot.comp = make_persistent<compound_type>(); // allocation
proot.comp->set_some_variable(12); // call function
proot.comp->some_other_variable = 2.3; // set variable
});
// reading from the persistent_ptr
compound_type tmp = *proot.comp;
(void)tmp;
// Changing a persistent_ptr<> variable outside of a transaction is a
// volatile modification. No way to ensure persistence in case of power
// failure.
proot.comp->some_variable = 12;
}

Casting to persistent_ptr_base can be easily done from any persistent_ptr<T> objects, but when casting between convertible objects be advised to use constructors or operator= specified for such conversion, see:

Below you can find an example how to and how NOT to cast persistent_ptr's:

#include <iostream>
using namespace pmem::obj;
struct root {
};
void
persistent_ptr_conversion_example(pool<root> &pop)
{
/* Casting persistent_ptr to persistent_ptr_base */
transaction::run(pop, [&] {
/* Good: any persistent_ptr<T> can be stored in a base ptr */
persistent_ptr_base i_ptr_base = make_persistent<int>(10);
/*
* Wrong: even though raw pointer can be used to create new
* persistent_ptr it's not advised to use it this way, since
* there's no information about underlying/template type
*/
persistent_ptr<double> dptr = i_ptr_base.raw();
std::cout << *dptr; // contains trash data
/*
* Acceptable: it's not advised, but it will work properly.
* Although, you have to be sure the underlying type is correct
*/
persistent_ptr<int> iptr_nonbase = i_ptr_base.raw();
std::cout << *iptr_nonbase; // contains proper data
/*
* Wrong: illegal call for derived constructor.
* no viable conversion from 'persistent_ptr_base' to
* 'persistent_ptr<int>' */
// iptr_nonbase = i_ptr_base;
/*
* Wrong: conversion from base class to persistent_ptr<T> is not
* possible: no matching conversion from 'persistent_ptr_base'
* to 'persistent_ptr<int>'
*/
// iptr_nonbase = static_cast<persistent_ptr<int>>(i_ptr_base);
/* Good: you can use base and ptr classes with volatile pointer
*/
persistent_ptr<int> i_ptr = make_persistent<int>(10);
persistent_ptr_base *i_ptr_ref = &i_ptr;
std::cout << i_ptr_ref->raw().off; // contains PMEMoid's data
});
struct A {
uint64_t a;
};
struct B {
uint64_t b;
};
struct C : public A, public B {
uint64_t c;
};
/* Convertible types, using struct A, B and C */
transaction::run(pop, [] {
/* Good: conversion from type C to B, using copy constructor */
auto cptr = make_persistent<C>();
persistent_ptr<B> bptr = cptr;
std::cout << (bptr->b ==
cptr->b); // thanks to conversion and
// recalculating offsets it's correct
/*
* Good: conversion from type C to B, using converting
* assignment operator
*/
bptr2 = cptr;
std::cout << (bptr2->b == cptr->b); // true
/* Good: direct conversion using static_cast */
persistent_ptr<B> bptr3 = static_cast<persistent_ptr<B>>(cptr);
std::cout << (bptr3->b == cptr->b); // true
/*
* Wrong: conversion to base class and then to different ptr.
* class no matching conversion from 'persistent_ptr_base' to
* 'persistent_ptr<B>'
*/
// auto cptr2 = (persistent_ptr_base)cptr;
// persistent_ptr<B> bptr4 =
// static_cast<persistent_ptr<B>>(cptr2);
/*
* Wrong: conversion to 'void *' and then to different ptr
* class. ambiguous conversion from 'void *' to
* 'persistent_ptr<B>'
*/
// auto cptr3 = (void *)&cptr;
// persistent_ptr<B> bptr5 =
// static_cast<persistent_ptr<B>>(cptr3);
});
}

Member Typedef Documentation

◆ iterator_category

template<typename T >
using pmem::obj::persistent_ptr< T >::iterator_category = std::random_access_iterator_tag

Random access iterator requirements (members)

The persistent_ptr iterator category.

Constructor & Destructor Documentation

◆ persistent_ptr() [1/4]

template<typename T >
pmem::obj::persistent_ptr< T >::persistent_ptr ( element_type ptr)
inline

Volatile pointer constructor.

If ptr does not point to an address from a valid pool, the persistent pointer will evaluate to nullptr.

Parameters
ptrvolatile pointer, pointing to persistent memory.

◆ persistent_ptr() [2/4]

template<typename T >
template<typename U , typename = typename std::enable_if< !std::is_same<T, U>::value && std::is_same<typename std::remove_cv<T>::type, U>::value>::type>
pmem::obj::persistent_ptr< T >::persistent_ptr ( persistent_ptr< U > const &  r)
inlinenoexcept

Copy constructor from a different persistent_ptr<>.

Available only for convertible types.

◆ persistent_ptr() [3/4]

template<typename T >
template<typename U , typename Dummy = void, typename = typename std::enable_if< !std::is_same< typename std::remove_cv<T>::type, typename std::remove_cv<U>::type>::value && !std::is_void<U>::value, decltype(static_cast<T *>(std::declval<U *>()))>::type>
pmem::obj::persistent_ptr< T >::persistent_ptr ( persistent_ptr< U > const &  r)
inlinenoexcept

Copy constructor from a different persistent_ptr<>.

Available only for convertible, non-void types.

◆ persistent_ptr() [4/4]

template<typename T >
pmem::obj::persistent_ptr< T >::persistent_ptr ( element_type vptr,
int   
)
inlineprotected

Private constructor enabling persistent_ptrs to volatile objects.

This is internal implementation needed only for the pointer_traits<persistent_ptr>::pointer_to to be able to create valid pointers. This is used in libstdc++'s std::vector::insert().

Member Function Documentation

◆ calculate_offset()

template<typename T >
template<typename U >
ptrdiff_t pmem::obj::persistent_ptr< T >::calculate_offset ( ) const
inlineprotected

Calculate in-object offset for structures with inheritance.

In case of the given inheritance:

A B \ / C

A pointer to B *ptr = &C should be offset by sizeof(A). This function calculates that offset.

Returns
offset between two compatible pointer types to the same object

◆ flush() [1/2]

template<typename T >
void pmem::obj::persistent_ptr< T >::flush ( pool_base pop)
inline

Flushes what the persistent pointer points to.

Parameters
[in]popPmemobj pool

◆ flush() [2/2]

template<typename T >
void pmem::obj::persistent_ptr< T >::flush ( void  )
inline

Flushes what the persistent pointer points to.

Exceptions
pool_errorwhen cannot get pool from persistent pointer

◆ get()

template<typename T >
element_type* pmem::obj::persistent_ptr< T >::get ( ) const
inlinenoexcept

Get the direct pointer.

Performs a calculations on the underlying C-style pointer.

Returns
the direct pointer to the object.

◆ operator=()

template<typename T >
template<typename Y , typename = typename std::enable_if< std::is_convertible<Y *, T *>::value>::type>
persistent_ptr<T>& pmem::obj::persistent_ptr< T >::operator= ( persistent_ptr< Y > const &  r)
inline

Converting assignment operator from a different persistent_ptr<>.

Available only for convertible types. Just like regular assignment, also automatically registers itself in a transaction.

Exceptions
pmem::transaction_errorwhen adding the object to the transaction failed.

◆ operator[]()

template<typename T >
template<typename = typename std::enable_if<!std::is_void<T>::value>>
pmem::detail::sp_array_access<T>::type pmem::obj::persistent_ptr< T >::operator[] ( std::ptrdiff_t  i) const
inlinenoexcept

Array access operator.

Contains run-time bounds checking for static arrays.

◆ persist() [1/2]

template<typename T >
void pmem::obj::persistent_ptr< T >::persist ( pool_base pop)
inline

Persists the content of the underlying object.

Parameters
[in]popPmemobj pool

◆ persist() [2/2]

template<typename T >
void pmem::obj::persistent_ptr< T >::persist ( void  )
inline

Persists what the persistent pointer points to.

Exceptions
pool_errorwhen cannot get pool from persistent pointer

◆ persistent_ptr_base()

template<typename T >
pmem::obj::persistent_ptr_base::persistent_ptr_base
inlinenoexcept

PMEMoid constructor.

Provided for easy interoperability between C++ and C API's.

Parameters
oidC-style persistent pointer

◆ pointer_to()

template<typename T >
static persistent_ptr<T> pmem::obj::persistent_ptr< T >::pointer_to ( T &  ref)
inlinestatic

Create a persistent pointer from a given reference.

This can create a persistent_ptr to a volatile object, use with extreme caution.

Parameters
refreference to an object.

The documentation for this class was generated from the following files:
pmem::obj::pool::create
static pool< T > create(const std::string &path, const std::string &layout, std::size_t size=PMEMOBJ_MIN_POOL, mode_t mode=DEFAULT_MODE)
Creates a new transactional object store pool.
Definition: pool.hpp:674
pmem::obj::persistent_ptr_base::raw
const PMEMoid & raw() const noexcept
Get PMEMoid encapsulated by this object.
Definition: persistent_ptr_base.hpp:151
pool.hpp
C++ pmemobj pool.
make_persistent.hpp
Persistent_ptr transactional allocation functions for objects.
pmem::obj::transaction::run
static void run(pool_base &pool, std::function< void()> tx, Locks &... locks)
Execute a closure-like transaction and lock locks.
Definition: transaction.hpp:393
pmem::obj
Main libpmemobj namespace.
Definition: allocation_flag.hpp:18
transaction.hpp
C++ pmemobj transactions.
pmem::obj::persistent_ptr
Persistent pointer class.
Definition: persistent_ptr.hpp:183
pmem::obj::pool
PMEMobj pool class.
Definition: pool.hpp:462
pmem::obj::persistent_ptr_base
Persistent_ptr base (non-template) class.
Definition: persistent_ptr_base.hpp:42
persistent_ptr_base.hpp
Base class for persistent_ptr.
persistent_ptr.hpp
Persistent smart pointer.