GEGELATI

Loading...
Searching...
No Matches
Classes | Public Member Functions | Public Attributes | Static Public Attributes | List of all members
Data::UntypedSharedPtr Class Reference

Class behaving as a std::shared_ptr whose type is not templated. More...

`#include <untypedSharedPtr.h>`

## Classes
struct | Concept
| Internal structure of the type erasure pattern. More...
struct | Model
| Internal templated structure of the type erasure pattern. More...

## Public Member Functions
| UntypedSharedPtr ()=delete
| Deleted default constructor.
template<typename T , class Deleter = std::default_delete<T>>
| UntypedSharedPtr (T *obj, Deleter func=Deleter())
| Main constructor of the UntypedSharedPtr class.
| UntypedSharedPtr (std::shared_ptr< Concept > concept)
| Constructor from an existing Concept.
const std::type_info & | getType () const
| Accessor to the type of data stored in the UntypedSharedPtr.
const std::type_info & | getPtrType () const
| Accessor to the pointer type of data stored in the UntypedSharedPtr.
template<typename T >
std::shared_ptr< std::remove_all_extents_t< T > > | getSharedPointer () const
| Get the shared_ptr store in the UntypedSharedPtr.

## Public Attributes
std::shared_ptr< const Concept > | sharedPtrContainer
| Shared container containing the data structure containing the actual std::shared_ptr.

## Static Public Attributes
template<typename T >
static std::function< void(T *) | emptyDestructor )()
| Get an empty destructor function for any type.

## Detailed Description

Class behaving as a std::shared_ptr whose type is not templated.

Instances of this class is that it behaves as a share_ptr, meaning that it contains a pointer to an object that is freed automatically when the last copy of the UntypedSharedPtr associated to this pointer is deleted. The deleter that can be passed as a parameter when building an instance is used to delete the object. By giving an empty function to the constructor, the deletion of the pointer can thus be prevented, and the UntypedSharedPtr can be used to store a regular pointer.

The main difference with the classical std::shared_ptr<T> is that no template parameter specifies what is stored inside the UntypedSharedPtr. Hence, a std:vector<UntypedSharedPtr> can contain shared pointer to any type of data (including primitive types), whereas a std::vector< std::shared_ptr<Base>> can contain only pointers to types derived from a given Base class, which notably prevent such a vector from containing shared pointer to several distinct primitive types.

The code of this class is based on the Type Erasure patterns, and is directly inspired by this example/

## Constructor & Destructor Documentation

## ◆ UntypedSharedPtr() [1/2]

template<typename T , class Deleter = std::default_delete<T>>

Data::UntypedSharedPtr::UntypedSharedPtr | ( | T * | obj,
|  | Deleter | func = Deleter() )
| inline

Main constructor of the UntypedSharedPtr class.

Constructs an instance of the UntypedSharedPtr class whose type is given as a template parameter T that is deduced at function call.

For example, the following codes creates an UntypedSharedPtr for an int value:

UntypedSharedPtr ptr{new int(2)}; // Template parameter 'int' deduced
Data::PrimitiveTypeArray2D
DataHandler for 2D arrays of primitive types.
Definition primitiveTypeArray2D.h:69
Data::UntypedSharedPtr
Class behaving as a std::shared_ptr whose type is not templated.
Definition untypedSharedPtr.h:72

The default deleter for the given pointer type is used by default, unless a deleter is explicitly given to the constructor. For example, a deleter doing nothing can be given to prevent the shared pointer from deallocating the memory of a variable on the stack.

// Empty Deleter for double pointers.
auto del = [](const double *){};
// Variable on the heap
double a{2.5};
{ // Beginning of a scope
UntypedSharedPtr ptrA{&a, del};
UntypedSharedPtr ptr{new int(2)};
// UntypedSharedPtr ptrA2{&a}; // Problem => deletion of the memory
// will be attempted when leaving
// ptrA2 disappears.
} // End of a scope
// Memory associated to ptr is freed with default deleter for int*
// Memory associated to ptrA is deleted with del, which does
nothing.
Data::UntypedSharedPtr::UntypedSharedPtr
UntypedSharedPtr()=delete
Deleted default constructor.

As it is the case with std::shared_ptr, when misused, these capacity may result in invalid data access.

Template Parameters

  T | type of the equivalent std::shared_pointer<T>. Beware, const qualifier matters.
  Deleter | type of the deletion function. Default value is std::default_delete<T>

Parameters

  [in] | obj | Pointer to the memory managed by the UntypedSharedPtr.
  [in] | func | The function used as Deleter when the last copy of the UntypedSharedPtr disappears. Default value is std::default_delete<T>().

## ◆ UntypedSharedPtr() [2/2]

Data::UntypedSharedPtr::UntypedSharedPtr | ( | std::shared_ptr< Concept > | concept | ) |
| inline

Constructor from an existing Concept.

This constructor is needed when the pointer type passed to the classical constructor decays automatically into something else. For example, any pointer to a C-style array allocated with 'new T[]' automatically decays to 'T*' when passed to a function. By constructing a Model<W> with the desired template type (eg. W = T[]), it is possible to force the 'getPtr()' method to return this 'T[]' type.

Parameters

  [in] | concept | the instance of the Model<T> class for building the UntypedSharedPointer.

## Member Function Documentation

## ◆ getPtrType()

const std::type_info & Data::UntypedSharedPtr::getPtrType | ( |  | ) | const
| inline

Accessor to the pointer type of data stored in the UntypedSharedPtr.

Returns
  a const ref to the std::type_info of the pointer type T* of UntypedSharedPtr at construction. Please note that this may differ from the actual type of the data, if this data has a type derived from the base pointer type T. Contrary to the getType method, const qualifiers are preserved with pointer types.

class Base {};
class Derived : public Base {};
// Non const example.
Base * ptrA = new Derived();
UntypedSharedPtr uspA{ptrA}; // shared pointer type is Base.
std::cout << std::uspA.getPtrType().name(); // Prints "Base *"
// Const example
const Base * ptrB = new Derived();
UntypedSharedPtr uspB{ptrA}; // shared pointer type is const Base.
std::cout << std::uspB.getPtrType().name(); // Prints "const Base*"

## ◆ getSharedPointer()

template<typename T >

std::shared_ptr< std::remove_all_extents_t< T > > Data::UntypedSharedPtr::getSharedPointer | ( |  | ) | const
| inline

Get the shared_ptr store in the UntypedSharedPtr.

This templated function returns the std::shared_ptr hidden in the UntypedSharedPtr. For the function to work, the given template parameter must be the same as the one given during construction of the UntypedSharedPtr. If a Derived class was given at construction, a Base type can not be given to this function. The opposite (Base at construction and Derived to this function) also does not work, even if the actual object associated to the pointer is of type Derived.

If the type given at construction was const, the type given to this function must be const. If the type given at construction was non-const, the type given to this function can either be const or non- const.

class Base {};
class Derived : public Base {};
// Non const example.
Base * ptrA = new Derived();
UntypedSharedPtr uspA{ptrA}; // shared pointer type is Base.
std::shared_ptr<Base> spA1 = uspA.getSharedPtr<Base>(); // OK
std::shared_ptr<const Base> spA2 = uspA.getSharedPtr<const Base>();
// OK
// std::shared_ptr<Derived> spA3 = uspA.getSharedPtr<Derived>(); //
KO
// Const example
const Base * ptrB = new Derived();
UntypedSharedPtr uspB{ptrA}; // shared pointer type is const Base.
//std::shared_ptr<Base> spB1 = uspB.getSharedPtr<Base>(); // KO
std::shared_ptr<const Base> spB2 = uspB.getSharedPtr<const Base>();
// OK
// std::shared_ptr<Derived> spB3 = uspB.getSharedPtr<Derived>(); //
KO

Template Parameters

  T | Type of the retrieved std::shared_ptr<T>.

Returns
  the std::shared_ptr<T> of the pointer stored in the UntypedSharedPtr.

Exceptions

  std::runtime_exception | if the template parameter differs from the type given at construction of the UntypedSharedPtr.

## ◆ getType()

const std::type_info & Data::UntypedSharedPtr::getType | ( |  | ) | const
| inline

Accessor to the type of data stored in the UntypedSharedPtr.

Returns
  a const ref to the std::type_info of the template type T of UntypedSharedPtr at construction, or the Model template type for the constructor based on std::shared_ptr<Concept>. Please note that this type may differ from the actual type of the data, if this data has a type derived from the base pointer type T. Also note that any const qualifier will be lost.

class Base {};
class Derived : public Base {};
// Non const example.
Base * ptrA = new Derived();
UntypedSharedPtr uspA{ptrA}; // shared pointer type is Base.
std::cout << std::uspA.getType().name(); // Prints "Base"
// Const example
const Base * ptrB = new Derived();
UntypedSharedPtr uspB{ptrA}; // shared pointer type is const Base.
std::cout << std::uspB.getType().name(); // Prints "Base"

## Member Data Documentation

## ◆ emptyDestructor

template<typename T >

std::function< void(T *) Data::UntypedSharedPtr::emptyDestructor) ()
| inline static

Get an empty destructor function for any type.

When building an UntypedSharedPtr, this static method can be used to provide an empty destructor for the second argument of the constructor. The template param should be the same as the type of the pointer given to the UntypedSharetPtr constructor.

Template Parameters

  T | the type of the pointer to deallocate.

Returns
  the lambda function for deallocating.

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

- D:/a/gegelati/gegelati/gegelatilib/include/data/untypedSharedPtr.h