Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / widget / gtk / nsGtkUtils.h
blobae26049e7f959dd399abdbf1bb736ebe26bdbba0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
3 */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #ifndef nsGtkUtils_h__
9 #define nsGtkUtils_h__
11 #include <glib.h>
13 // Some gobject functions expect functions for gpointer arguments.
14 // gpointer is void* but C++ doesn't like casting functions to void*.
15 template <class T>
16 static inline gpointer FuncToGpointer(T aFunction) {
17 return reinterpret_cast<gpointer>(
18 reinterpret_cast<uintptr_t>
19 // This cast just provides a warning if T is not a function.
20 (reinterpret_cast<void (*)()>(aFunction)));
23 // Type-safe alternative to glib's g_clear_pointer.
25 // Using `g_clear_pointer` itself causes UBSan to report undefined
26 // behavior. The function-based definition of `g_clear_pointer` (as
27 // opposed to the older preprocessor macro) treats the `destroy`
28 // function as a `void (*)(void *)`, but the actual destroy functions
29 // that are used (say `wl_buffer_destroy`) usually have more specific
30 // pointer types.
32 // C++ draft n4901 [expr.call] para 6:
34 // Calling a function through an expression whose function type E
35 // is different from the function type F of the called function’s
36 // definition results in undefined behavior unless the type
37 // “pointer to F” can be converted to the type “pointer to E” via
38 // a function pointer conversion (7.3.14).
40 // §7.3.14 only talks about converting between noexcept and ordinary
41 // function pointers.
42 template <class T>
43 static inline void MozClearPointer(T*& pointer, void (*destroy)(T*)) {
44 T* hold = pointer;
45 pointer = nullptr;
46 if (hold) {
47 destroy(hold);
51 template <class T>
52 static inline void MozClearHandleID(T& handle, gboolean (*destroy)(T)) {
53 if (handle) {
54 destroy(handle);
55 handle = 0;
59 #endif // nsGtkUtils_h__