mirror of https://code.videolan.org/videolan/vlc
vlc_objects: expose wrappers around vlc_object_create/delete
Using placement new and manual call to the destructor. It ensures that C++ objects are correctly handled when creating C++ objects through vlc_object_create<>(), and that their destructors are correctly called when the (C++) object is destroyed. According to the C++ draft standard, the vlc_object_t won't get overwritten by the placement new since (7.1) will apply to the C++ object being allocated and placement-new'ed, which triggers the default initialization of members, and the default initialization of the vlc_object_t member enters the (7.3) case since no constructors exists for the structure. (It's an extern "C" structure). To default-initialize an object of type T means: (7.1) If T is a (possibly cv-qualified) class type ([class]), constructors are considered. The applicable constructors are enumerated ([over.match.ctor]), and the best one for the initializer () is chosen through overload resolution ([over.match]). The constructor thus selected is called, with an empty argument list, to initialize the object. (7.2) If T is an array type, each element is default-initialized. (7.3) Otherwise, no initialization is performed. --: https://eel.is/c++draft/dcl.init#general-7 However, it's not possible to use a zero-initializing placement-new operation.
This commit is contained in:
parent
1701e2da5c
commit
6cfbabfc55
|
@ -24,6 +24,7 @@
|
|||
#define VLC_OBJECTS_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <new>
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
@ -314,8 +315,22 @@ template<typename T, typename O> VLC_MALLOC VLC_USED
|
|||
static inline T* vlc_object_create(O *obj)
|
||||
{
|
||||
static_assert(std::is_pointer<T>::value == false, "vlc_object_create can only create objects");
|
||||
return static_cast<T*>(vlc_object_create(VLC_OBJECT(obj), sizeof(T)));
|
||||
void *object = vlc_object_create(VLC_OBJECT(obj), sizeof(T));
|
||||
if (object == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return new(object) T;
|
||||
}
|
||||
|
||||
#undef vlc_object_delete
|
||||
template<typename O>
|
||||
static inline void vlc_object_delete(O *obj)
|
||||
{
|
||||
if (!std::is_trivially_destructible<O>::value)
|
||||
obj->~O();
|
||||
vlc_object_delete(VLC_OBJECT(obj));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
|
Loading…
Reference in New Issue