STAPL API Reference          
Overview   Containers   Algorithms   Views   Skeletons   Run-Time System
Modules     Classes    
List of all members | Classes | Public Member Functions | Public Types
stapl::typer Class Reference

typer class is used for packing, unpacking and copying objects. More...

Classes

struct  base_type_wrapper
 Helper function used to disable implicit conversions. More...
 

Public Member Functions

constexpr typer (const pass_type p) noexcept
 Creates a new typer. More...
 
template<typename T >
 typer (T &dest, T const &src, void *base, const std::size_t offset)
 Creates a new typer for packing an object. More...
 
 typer (void *base)
 Creates a new typer for unpacking an object. More...
 
 typer (typer const &)=delete
 
typeroperator= (typer const &)=delete
 
pass_type pass (void) noexcept
 Returns the current pass of the typer. More...
 
std::size_t offset (void) const noexcept
 Returns the number of bytes since the start of the current operation.
 
std::pair< bool, std::size_t > meets_requirements (void) const noexcept
 Returns if the object meets the requested requirements.
 
template<typename Base >
void base (typename base_type_wrapper< Base >::type &t)
 Processes a base class.
 
template<typename T >
void member (T &t)
 Processes member t.
 
template<typename T >
void member (T const &t)
 Processes member t. More...
 
template<typename T >
void member (T volatile &t)
 Processes member t. More...
 
template<typename T >
void member (T const volatile &t)
 Processes member t. More...
 
template<typename T >
void member (T &t, const std::size_t N)
 Processes member t with an additional integral type passed to the packing functions.
 
template<typename T >
void member (T const &t, const std::size_t N)
 Processes member t with an additional integral type passed to the packing functions. More...
 
template<typename T >
void member (T volatile &t, const std::size_t N)
 Processes member t with an additional integral type passed to the packing functions. More...
 
template<typename T >
void member (T const volatile &t, const std::size_t N)
 Processes member t with an additional integral type passed to the packing functions. More...
 
template<typename T >
void transient (T &t)
 Default constructs t at unpacking.
 
template<typename T >
void transient (T const &t)
 Default constructs t at unpacking. More...
 
template<typename T >
void transient (T volatile &t)
 Default constructs t at unpacking. More...
 
template<typename T >
void transient (T const volatile &t)
 Default constructs t at unpacking. More...
 
template<typename T , typename U >
void transient (T &t, U &&u)
 Constructs t using u at unpacking.
 
template<typename T , typename U >
void transient (T const &t, U &&u)
 
template<typename T , typename U >
void transient (T volatile &t, U &&u)
 
template<typename T , typename U >
void transient (T const volatile &t, U &&u)
 
template<typename T , typename U >
void pointer_to_member (T *&t, U *ref, const std::size_t offset=0) noexcept
 Processes a pointer t to other member ref at offset offset.
 
template<typename T , typename U >
void pointer_to_member (T *const &t, U *ref, const std::size_t offset=0) noexcept
 Processes a pointer t to other member ref at offset offset. More...
 
template<typename T , typename U >
void pointer_to_member (T *volatile &t, U *ref, const std::size_t offset=0) noexcept
 Processes a pointer t to other member ref at offset offset. More...
 
template<typename T , typename U >
void pointer_to_member (T *const volatile &t, U *ref, const std::size_t offset=0) noexcept
 Processes a pointer t to other member ref at offset offset. More...
 

Public Types

enum  pass_type {
  SIZE, COPY, MOVE, NO_MARSHAL,
  PACK, UNPACK, DESTROY
}
 

Detailed Description

typer class is used for packing, unpacking and copying objects.

It operates on user-defined class T via its T::define_type() function, which must clearly define its members to ensure proper packing/unpacking.

The body of define_type has four sections:

void define_type(stapl::typer& t)
{
// 1) base class packing
// 2) preliminary calculations
// 3) data member definitions
// 4) pointer to member definitions
}

Section 1 is for packing any base classes of T. It is undefined behavior to not pack the base classes before everything else.

Section 2 is for performing preliminary calculations and storing temporary values that may be necessary in sections 2 or 3 (e.g., offsets, sizes, etc). This is necessary because section 2 may modify the contents of members during packing/unpacking.

Section 3 is for defining data members: variables that store data, either automatically or via dynamic memory allocation. Section 3 starts with the first call to typer::member(). Upon packing of the object, each data member will be properly packed. If a data member is a user-defined object, it will be recursively packed.

Section 4 is for defining offset members: pointers used as points of reference within the data members previously defined in section 2 (e.g., some implementations of std::vector store a dynamic array of data, along with an offset pointer referencing one past the array's end). Section 4 starts with the first call to typer::pointer_to_member(). Only the relative address within the type is packaged upon packing, not the object pointed to, since that object was already packed in Section 3. Attempting to define an offset member to an object not packed in Section 3 is undefined behavior.

It is recommended that members are processed in the T::define_type() in the order they are declared in the class, although this is not necessary for correctness.

Warning
STL iterators are not directly supported by the primitives for packing/unpacking. They typically come in pairs, one for the beginning and one for the end of a sequence, so they cannot be packed in one pass. This can be overcome by using wrapper classes that explicitly implement a define_type() method that does provide the necessary information. For example, the iterators can both be stored in a class as a range with the necessary define_type() function.
If two data members both contain pointers to the same object, that object will be packed twice and after unpacking you will end up with two objects. In some cases, such shared pointers are necessary for the structure of the aggregate object and using offset pointers may still allow for a valid define_type(). For example, each node in a doubly-linked list has two pointers, allowing for forward and backward traversals through the list. Defining both pointers to be members is not valid. The correct define_type() will define the next pointer to be member, to recursively define the list, and the previous pointer to be a pointer to member, to correctly link the list.
Some implementations use define_type() to pack a class into contiguous memory. This packing may use memcpy(), or other low-level mechanisms unaware of C++ classes. The C++ Standard states that only PODs may be safely memcpy'ed. However, the purpose of define_type() is to give the typer enough information to still safely use memcpy. As such, one should not rely on the copy constructor being invoked during its packing/unpacking.
Example:
A user-defined struct for holding data, demonstrating local members.
struct simple
{
int a;
double b;
void define_type(stapl::typer& t)
{
t.member(a);
t.member(b);
}
};
Example:
A user-defined array class, demonstrating dynamic members and pointers to members.
struct array
{
int* begin;
int* end;
array(const std::size_t size)
: begin(new int[size]), end(begin + size)
{ }
~array()
{ delete[] begin; }
void define_type(stapl::typer& t)
{
const std::ptrdiff_t size = end - begin; // section 2
t.member(begin, size); // section 3
t.pointer_to_member(end, begin, size); // section 4
}
};
Example:
A user-defined inherited class, demonstrating how to pack a base class.
struct derived
: public simple
{
char c[10];
void define_type(stapl::typer& t)
{
t.base<simple>(*this);
t.member(c);
}
};

Member Enumeration Documentation

◆ pass_type

Enumerator
SIZE 

Calculate size of packed object.

COPY 

Check if object can be copied and calculate its packed size.

MOVE 

Check if object can be moved and calculate its packed size.

NO_MARSHAL 

Check if object marshaling can be avoided and calculate its packed size.

PACK 

Pack object.

UNPACK 

Unpack object.

DESTROY 

Destroy unpacked object.

Constructor & Destructor Documentation

◆ typer() [1/3]

constexpr stapl::typer::typer ( const pass_type  p)
noexcept

Creates a new typer.

Parameters
passIf SIZE, it calculates the packed size of the object. If DESTROY, it cleanups after an unpacked object. If COPY, it determines if it is safe to copy an object and calculates its packed size. If MOVE, it determines if it is safe to move an object and calculates its packed size. If NO_MARSHAL, it determines if the object does not have to be marshaled and calculates its packed size.

◆ typer() [2/3]

template<typename T >
stapl::typer::typer ( T &  dest,
T const &  src,
void *  base,
const std::size_t  offset 
)

Creates a new typer for packing an object.

Parameters
destDestination object.
srcSource object.
basePointer to buffer to pack the dynamic part of src.
offsetOffset in base.

◆ typer() [3/3]

stapl::typer::typer ( void *  base)

Creates a new typer for unpacking an object.

Parameters
basePointer to buffer to unpack the dynamic part of the object.

Member Function Documentation

◆ pass()

pass_type stapl::typer::pass ( void  )
noexcept

Returns the current pass of the typer.

Warning
If this function is called, then the object cannot be copied or moved, as it is implied that the define_type() function is performing some operation that has to happen at copying/moving.

◆ member() [1/6]

template<typename T >
void stapl::typer::member ( T const &  t)

Processes member t.

◆ member() [2/6]

template<typename T >
void stapl::typer::member ( T volatile &  t)

Processes member t.

◆ member() [3/6]

template<typename T >
void stapl::typer::member ( T const volatile &  t)

Processes member t.

◆ member() [4/6]

template<typename T >
void stapl::typer::member ( T const &  t,
const std::size_t  N 
)

Processes member t with an additional integral type passed to the packing functions.

◆ member() [5/6]

template<typename T >
void stapl::typer::member ( T volatile &  t,
const std::size_t  N 
)

Processes member t with an additional integral type passed to the packing functions.

◆ member() [6/6]

template<typename T >
void stapl::typer::member ( T const volatile &  t,
const std::size_t  N 
)

Processes member t with an additional integral type passed to the packing functions.

◆ transient() [1/6]

template<typename T >
void stapl::typer::transient ( T const &  t)

Default constructs t at unpacking.

◆ transient() [2/6]

template<typename T >
void stapl::typer::transient ( T volatile &  t)

Default constructs t at unpacking.

◆ transient() [3/6]

template<typename T >
void stapl::typer::transient ( T const volatile &  t)

Default constructs t at unpacking.

◆ transient() [4/6]

template<typename T , typename U >
void stapl::typer::transient ( T const &  t,
U &&  u 
)

◆ transient() [5/6]

template<typename T , typename U >
void stapl::typer::transient ( T volatile &  t,
U &&  u 
)

◆ transient() [6/6]

template<typename T , typename U >
void stapl::typer::transient ( T const volatile &  t,
U &&  u 
)

◆ pointer_to_member() [1/3]

template<typename T , typename U >
void stapl::typer::pointer_to_member ( T *const &  t,
U *  ref,
const std::size_t  offset = 0 
)
noexcept

Processes a pointer t to other member ref at offset offset.

◆ pointer_to_member() [2/3]

template<typename T , typename U >
void stapl::typer::pointer_to_member ( T *volatile &  t,
U *  ref,
const std::size_t  offset = 0 
)
noexcept

Processes a pointer t to other member ref at offset offset.

◆ pointer_to_member() [3/3]

template<typename T , typename U >
void stapl::typer::pointer_to_member ( T *const volatile &  t,
U *  ref,
const std::size_t  offset = 0 
)
noexcept

Processes a pointer t to other member ref at offset offset.


The documentation for this class was generated from the following files: