nx_metadata_sdk 1.0 Metadata SDK

i_ref_countable.h
1 // Copyright 2018-present Network Optix, Inc. Licensed under MPL 2.0: www.mozilla.org/MPL/2.0/
2
3 #pragma once
4
5 #include <cstring>
6 #include <cstdarg>
7 #include <cassert>
8 #include <type_traits>
9
10 #include <nx/sdk/ptr.h>
11
12 namespace nx {
13 namespace sdk {
14
50 class IRefCountable
51 {
52 public:
62 struct InterfaceId
63 {
64 static constexpr int kMinSize = 16; //< For compatibility with the old SDK.
65 static constexpr int minSize() { return kMinSize; } //< For C++14, to avoid the definition.
66
67 char value[kMinSize];
68
69 InterfaceId() = delete; //< No instances - only InterfaceId* are used via reinterpret_cast.
70
71 bool operator==(const InterfaceId& other) const { return strcmp(value, other.value) == 0; }
72 bool operator!=(const InterfaceId& other) const { return !(*this == other); }
73 };
74
75 protected:
77 template<int len>
78 static constexpr const InterfaceId* makeId(const char (&charArray)[len])
79 {
80 static_assert(len + /*terminating zero*/ 1 >= InterfaceId::minSize(),
81 "Interface id is too short");
82
83 return reinterpret_cast<const InterfaceId*>(charArray);
84 }
85
86 public:
88 static auto interfaceId() { return makeId("nx::sdk::IRefCountable"); }
89
91 virtual ~IRefCountable() = default;
92
93 protected:
103 template<class TemplateInstance, class TemplateArg, int len>
104 static const InterfaceId* makeIdForTemplate(const char (&baseIdCharArray)[len])
105 {
106 static constexpr int kMaxStaticInterfaceIdSize = 256;
107
108 static_assert(len >= 1, "baseIdCharArray should not be empty");
109 static_assert(std::is_base_of<IRefCountable, TemplateInstance>::value,
110 "TemplateInstance should be inherited from IRefCountable");
111 static_assert(std::is_base_of<IRefCountable, TemplateArg>::value,
112 "TemplateArg should be inherited from IRefCountable");
113
114 // The id is stored in a static array because it is unique for the given template args.
115 static char id[kMaxStaticInterfaceIdSize];
116 assert(id[0] == '\0'); //< Assert that the static id has not been initialized yet.
117
118 const int result = snprintf(
119 id,
120 kMaxStaticInterfaceIdSize,
121 "%s<%s>",
122 baseIdCharArray,
123 TemplateArg::interfaceId()->value);
124
125 /*unused*/ (void) result; //< If assert() is wiped out in Release, `result` will be unused.
126 assert(result >= InterfaceId::minSize() - 1);
127 assert(result < kMaxStaticInterfaceIdSize);
128
129 return reinterpret_cast<const InterfaceId*>(id);
130 }
131
139 virtual IRefCountable* queryInterface(const InterfaceId* id)
140 {
141 if (*interfaceId() == *id)
142 {
143 addRef();
144 return this;
145 }
146 return nullptr;
147 }
148
149 public:
150 template<class Interface>
151 Ptr<Interface> queryInterface()
152 {
153 return toPtr(static_cast<Interface*>(queryInterface(Interface::interfaceId())));
154 }
155
156 template<class Interface>
157 Ptr<const Interface> queryInterface() const
158 {
159 return toPtr(static_cast<const Interface*>(
160 const_cast<IRefCountable*>(this)->queryInterface(Interface::interfaceId())));
161 }
162
167 virtual int addRef() const = 0;
168
173 virtual int releaseRef() const = 0;
174
179 int refCountThreadUnsafe() const
180 {
181 const void* this_ = this; //< Suppress warning that `this` cannot be null.
182 if (this_ == nullptr)
183 return 0;
184
185 /*unused*/ (void) addRef();
186 return releaseRef();
187 }
188 };
189
190 } // namespace sdk
191 } // namespace nx
nx::sdk::IRefCountable::InterfaceId
Definition: i_ref_countable.h:62
nx::sdk::Ptr
Definition: ptr.h:18
nx::sdk::IRefCountable::makeIdForTemplate
static const InterfaceId * makeIdForTemplate(const char(&baseIdCharArray)[len])
Definition: i_ref_countable.h:104
nx::sdk::IRefCountable::releaseRef
virtual int releaseRef() const =0
nx::sdk::IRefCountable::~IRefCountable
virtual ~IRefCountable()=default
nx::sdk::IRefCountable::refCountThreadUnsafe
int refCountThreadUnsafe() const
Definition: i_ref_countable.h:179
nx
Definition: apple_utils.h:6
nx::sdk::IRefCountable::interfaceId
static auto interfaceId()
Definition: i_ref_countable.h:88
nx::sdk::IRefCountable::addRef
virtual int addRef() const =0
nx::sdk::IRefCountable
Definition: i_ref_countable.h:50
nx::sdk::IRefCountable::makeId
static constexpr const InterfaceId * makeId(const char(&charArray)[len])
Definition: i_ref_countable.h:78