Branch data Line data Source code
1 : : /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 : : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
3 : : // SPDX-FileCopyrightText: 2024 Philip Chimento <philip.chimento@gmail.com>
4 : :
5 : : #pragma once
6 : :
7 : : #include <config.h>
8 : :
9 : : #include <girepository.h>
10 : : #include <glib.h>
11 : :
12 : : #include <js/GCPolicyAPI.h>
13 : :
14 : : #include "gjs/auto.h"
15 : :
16 : : // This file contains auto pointers for libgirepository.
17 : : // There are type aliases for auto pointers for every kind of introspection info
18 : : // (GI::AutoFooInfo), with wrappers for commonly used APIs such as
19 : : // g_base_info_get_name(), g_base_info_get_namespace(), and
20 : : // g_base_info_get_type().
21 : :
22 : : namespace GI {
23 : :
24 : : // Use this class for owning a GIBaseInfo* of indeterminate type. Any type (e.g.
25 : : // GIFunctionInfo*, GIObjectInfo*) will fit. If you know that the info is of a
26 : : // certain type (e.g. you are storing the return value of a function that
27 : : // returns GIFunctionInfo*,) use one of the derived classes below.
28 : : struct AutoBaseInfo : Gjs::AutoPointer<GIBaseInfo, GIBaseInfo,
29 : 283137 : g_base_info_unref, g_base_info_ref> {
30 : : using AutoPointer::AutoPointer;
31 : :
32 : 59239 : [[nodiscard]] const char* name() const {
33 : 59239 : return g_base_info_get_name(*this);
34 : : }
35 : 9448 : [[nodiscard]] const char* ns() const {
36 : 9448 : return g_base_info_get_namespace(*this);
37 : : }
38 : 41019 : [[nodiscard]] GIInfoType type() const {
39 : 41019 : return g_base_info_get_type(*this);
40 : : }
41 : : };
42 : :
43 : : // Use GI::AutoInfo, preferably its typedefs below, when you know for sure that
44 : : // the info is either of a certain type or null.
45 : : template <GIInfoType TAG>
46 : : struct AutoInfo : AutoBaseInfo {
47 : : using AutoBaseInfo::AutoBaseInfo;
48 : :
49 : : // Normally one-argument constructors should be explicit, but we are trying
50 : : // to conform to the interface of std::unique_ptr here.
51 : 195274 : AutoInfo(GIBaseInfo* ptr = nullptr) // NOLINT(runtime/explicit)
52 : 195274 : : AutoBaseInfo(ptr) {
53 : : #ifndef G_DISABLE_CAST_CHECKS
54 : 195274 : validate();
55 : : #endif
56 : 195274 : }
57 : :
58 : 9480 : void reset(GIBaseInfo* other = nullptr) {
59 : 9480 : AutoBaseInfo::reset(other);
60 : : #ifndef G_DISABLE_CAST_CHECKS
61 : 9480 : validate();
62 : : #endif
63 : 9480 : }
64 : :
65 : : // You should not need this method, because you already know the answer.
66 : : GIInfoType type() = delete;
67 : :
68 : : private:
69 : 204754 : void validate() const {
70 [ + + ]: 204754 : if (GIBaseInfo* base = *this)
71 : 164516 : g_assert(g_base_info_get_type(base) == TAG);
72 : 204754 : }
73 : : };
74 : :
75 : : using AutoArgInfo = AutoInfo<GI_INFO_TYPE_ARG>;
76 : : using AutoEnumInfo = AutoInfo<GI_INFO_TYPE_ENUM>;
77 : : using AutoFieldInfo = AutoInfo<GI_INFO_TYPE_FIELD>;
78 : : using AutoFunctionInfo = AutoInfo<GI_INFO_TYPE_FUNCTION>;
79 : : using AutoInterfaceInfo = AutoInfo<GI_INFO_TYPE_INTERFACE>;
80 : : using AutoObjectInfo = AutoInfo<GI_INFO_TYPE_OBJECT>;
81 : : using AutoPropertyInfo = AutoInfo<GI_INFO_TYPE_PROPERTY>;
82 : : using AutoStructInfo = AutoInfo<GI_INFO_TYPE_STRUCT>;
83 : : using AutoSignalInfo = AutoInfo<GI_INFO_TYPE_SIGNAL>;
84 : : using AutoTypeInfo = AutoInfo<GI_INFO_TYPE_TYPE>;
85 : : using AutoValueInfo = AutoInfo<GI_INFO_TYPE_VALUE>;
86 : : using AutoVFuncInfo = AutoInfo<GI_INFO_TYPE_VFUNC>;
87 : :
88 : : // GI::CallableInfo can be one of several tags, so we have to have a separate
89 : : // class, and use GI_IS_CALLABLE_INFO() to validate.
90 : : struct AutoCallableInfo : AutoBaseInfo {
91 : : using AutoBaseInfo::AutoBaseInfo;
92 : :
93 : 10 : AutoCallableInfo(GIBaseInfo* ptr = nullptr) // NOLINT(runtime/explicit)
94 : 10 : : AutoBaseInfo(ptr) {
95 : 10 : validate();
96 : 10 : }
97 : :
98 : : void reset(GIBaseInfo* other = nullptr) {
99 : : AutoBaseInfo::reset(other);
100 : : validate();
101 : : }
102 : :
103 : : private:
104 : 10 : void validate() const {
105 [ + + ]: 10 : if (*this)
106 : 6 : g_assert(GI_IS_CALLABLE_INFO(get()));
107 : 10 : }
108 : : };
109 : :
110 : : } // namespace GI
111 : :
112 : : namespace Gjs {
113 : : template <>
114 : : struct SmartPointer<GIBaseInfo> : GI::AutoBaseInfo {
115 : : using AutoBaseInfo::AutoBaseInfo;
116 : : };
117 : : } // namespace Gjs
118 : :
119 : : /* For use of GjsAutoInfo<TAG> in GC hash maps */
120 : : namespace JS {
121 : : template <GIInfoType TAG>
122 : : struct GCPolicy<GI::AutoInfo<TAG>> : public IgnoreGCPolicy<GI::AutoInfo<TAG>> {
123 : : };
124 : : } // namespace JS
|