AGX Dynamics 2.41.3.0
Loading...
Searching...
No Matches
Name.h
Go to the documentation of this file.
1/*
2Copyright 2007-2025. Algoryx Simulation AB.
3
4All AGX source code, intellectual property, documentation, sample code,
5tutorials, scene files and technical white papers, are copyrighted, proprietary
6and confidential material of Algoryx Simulation AB. You may not download, read,
7store, distribute, publish, copy or otherwise disseminate, use or expose this
8material unless having a written signed agreement with Algoryx Simulation AB, or having been
9advised so by Algoryx Simulation AB for a time limited evaluation, or having purchased a
10valid commercial license from Algoryx Simulation AB.
11
12Algoryx Simulation AB disclaims all responsibilities for loss or damage caused
13from using this software, unless otherwise stated in written agreements with
14Algoryx Simulation AB.
15*/
16
17#ifndef AGX_NAME_H
18#define AGX_NAME_H
19
20#include <agx/String.h>
21#include <agx/AtomicValue.h>
22#include <agx/HashFunction.h>
23#include <string.h>
24#include <iosfwd>
25
26namespace agx
27{
33 {
34 public:
35 Name();
36 Name(const char *name);
37 Name(const agx::String& name);
38 Name(const std::string& name);
39 Name(const Name& name);
40
41 ~Name();
42
46 operator agx::String() const;
47 operator std::string() const;
48 // operator const char *() const;
49
54
58 const char *c_str() const;
59
63 agx::UInt32 length() const;
64
65
69 agx::UInt32 size() const;
70
74 bool empty() const;
75
76
80 char operator[] (size_t index) const;
81
83 agx::Name& operator= (const agx::Name& other);
84 agx::Name& operator= (const std::string& other);
85 agx::Name& operator= (const agx::String& other);
86 agx::Name& operator= (const char *other);
87
88
90 bool operator== (const agx::Name& other) const;
91 bool operator== (const std::string& other) const;
92 bool operator== (const agx::String& other) const;
93 bool operator== (const char *other) const;
94
95 bool operator!= (const agx::Name& other) const;
96 bool operator!= (const std::string& other) const;
97 bool operator!= (const agx::String& other) const;
98 bool operator!= (const char *other) const;
99
101 agx::String operator+ (const agx::Name& other) const;
102 agx::String operator+ (const std::string& other) const;
103 agx::String operator+ (const agx::String& other) const;
104 agx::String operator+ (const char *other) const;
105
106
107 // Hash function
108 UInt32 hash() const;
109
110 void swap(Name& rhs);
111
112 private:
113 struct Header
114 {
115 agx::AtomicValue refCount;
116 agx::UInt32 length;
117 };
118
119 private:
120 void init(const char *name);
121 static char *allocateSharedString(const char *string);
122
123 static const char *getSharedString(const char *str);
124 static void destroySharedString(const char *str);
125 static Header& getHeader(const char *buf);
126
127 Header& header();
128 const Header& header() const;
129 void incRef();
130 void decRef();
131
132
133 private:
134 static const char *s_emptyString; // Important that empty name share string buffer, which is not guaranteed when using "" literals
135
144 const char *m_buf;
145 };
146
147 bool operator== (const std::string& str, const agx::Name& name);
148 bool operator== (const agx::String& str, const agx::Name& name);
149 bool operator== (const char *str, const agx::Name& name);
150
151 bool operator!= (const std::string& str, const agx::Name& name);
152 bool operator!= (const agx::String& str, const agx::Name& name);
153 bool operator!= (const char *str, const agx::Name& name);
154
155 AGXCORE_EXPORT std::ostream& operator << ( std::ostream& stream, const Name& name );
156
157
158
159
160
161 /* Implementation */
163 {
164 if (!s_emptyString)
165 {
166 // getSharedString return an already incremented ref, to avoid race conditions
167 s_emptyString = Name::getSharedString("");
168 m_buf = s_emptyString;
169 }
170 else
171 {
172 m_buf = s_emptyString;
173 this->incRef();
174 }
175 }
176
177 AGX_FORCE_INLINE Name::Name(const Name& name) : m_buf(name.m_buf)
178 {
179 this->incRef();
180 }
181
182
184 {
185 this->decRef();
186 }
187
188
189 AGX_FORCE_INLINE const char *Name::c_str() const { return m_buf; }
190 // AGX_FORCE_INLINE Name::operator const char *() const { return m_buf; }
191
192 AGX_FORCE_INLINE agx::UInt32 Name::length() const { return header().length; }
194 AGX_FORCE_INLINE bool Name::empty() const { return length() == 0; }
195
196 // Dangerous cast from char*, with alignment requirement 1, to Header*, with
197 // alignment requirement 4. We guarantee that the cast is safe because the
198 // casted pointer is in fact what was returned from malloc.
199 //
200 // A better way to solve this would be to keep the malloced pointer, the pointer
201 // pointing to the Header, in Name::m_buf and add either a char* or a char[0]
202 // member to Header to get at the string data.
203 //
204 // It is not enough to keep the Header as is and compute the string pointer as
205 // const char* string = reinterpret_cast<const char*>(m_buf) + sizeof(Header)
206 // because that would create, and most likely later dereference, a pointer
207 // pointing past the end of the object from which the original pointer was created.
208 // May be a special case here since we stay within a single malloc'ed buffer,
209 // but I'm not sure.
211 AGX_FORCE_INLINE Name::Header& Name::getHeader(const char *buf) { agxAssert(buf); return *(Header *)(buf - sizeof(Header)); }
212 #include <agx/PopDisableWarnings.h>
213
214 AGX_FORCE_INLINE Name::Header& Name::header() { return Name::getHeader(m_buf); }
215 AGX_FORCE_INLINE const Name::Header& Name::header() const { return Name::getHeader(m_buf); }
216
217 AGX_FORCE_INLINE void Name::incRef() { this->header().refCount.inc(); }
218 AGX_FORCE_INLINE void Name::decRef()
219 {
220 UInt32 refCount = (UInt32)this->header().refCount.dec()-1;
221
222 if (refCount == 0)
223 {
224 Name::destroySharedString(m_buf);
225 m_buf = nullptr;
226 }
227 }
228
230 {
231 // Can hash on buffer ptr rather than string content, because identical names always share buffer
232 return agx::hash((void *)m_buf);
233 }
234
235 AGX_FORCE_INLINE char Name::operator[] (size_t index) const
236 {
237 agxAssert(index < length());
238 return m_buf[index];
239 }
240
241
242 AGX_FORCE_INLINE agx::Name& Name::operator= (const std::string& other)
243 {
244 (*this) = other.c_str();
245 return *this;
246 }
247
249 {
250 (*this) = other.c_str();
251 return *this;
252 }
253
255 {
256 this->decRef();
257 this->init(other);
258 return *this;
259 }
260
262 {
263 const_cast<Name&>(other).incRef(); // incRef before decRef to handle case where name is assigned to itself
264 this->decRef();
265 m_buf = other.m_buf;
266 return *this;
267 }
268
269
270 AGX_FORCE_INLINE bool Name::operator== (const Name& other) const
271 {
272 // Only need to compare string buffer pointer since it is shared by identical names
273 return m_buf == other.m_buf;
274 }
275
276 AGX_FORCE_INLINE bool Name::operator== (const std::string& other) const
277 {
278 // Use default std::string comparison
279 return m_buf == other;
280 }
281
283 {
284 // Use default std::string comparison.
285 return m_buf == static_cast<const std::string&>(other);
286 }
287
288
289 AGX_FORCE_INLINE bool Name::operator== (const char *other) const
290 {
291 return strcmp(m_buf, other) == 0;
292 }
293
294
295 AGX_FORCE_INLINE bool Name::operator!= (const Name& other) const { return !this->operator==(other); }
296 AGX_FORCE_INLINE bool Name::operator!= (const std::string& other) const { return !this->operator==(other); }
297 AGX_FORCE_INLINE bool Name::operator!= (const agx::String& other) const { return !this->operator==(other); }
298 AGX_FORCE_INLINE bool Name::operator!= (const char *other) const { return !this->operator==(other); }
299
300
301 AGX_FORCE_INLINE bool operator== (const std::string& str, const Name& name) { return name == str; }
302 AGX_FORCE_INLINE bool operator== (const agx::String& str, const Name& name) { return name == str; }
303 AGX_FORCE_INLINE bool operator== (const char *str, const Name& name) { return name == str; }
304
305 AGX_FORCE_INLINE bool operator!= (const std::string& str, const Name& name) { return name != str; }
306 AGX_FORCE_INLINE bool operator!= (const agx::String& str, const Name& name) { return name != str; }
307 AGX_FORCE_INLINE bool operator!= (const char *str, const Name& name) { return name != str; }
308
310 {
311 std::swap(m_buf, rhs.m_buf);
312 }
313
314
315}
316
317AGXCORE_EXPORT agx::String operator+ (const std::string& str, const agx::Name& name);
319AGXCORE_EXPORT agx::String operator+ (const char *str, const agx::Name& name);
320
321namespace std
322{
324 {
325 lhs.swap(rhs);
326 }
327}
328
329
330
331#endif /* AGX_NAME_H */
AGXCORE_EXPORT agx::String operator+(const std::string &str, const agx::Name &name)
#define AGXCORE_EXPORT
Representation of a name string.
Definition: Name.h:33
agx::UInt32 size() const
Definition: Name.h:193
agx::Name & operator=(const agx::Name &other)
Copy operators.
Definition: Name.h:261
char operator[](size_t index) const
Definition: Name.h:235
agx::UInt32 length() const
Definition: Name.h:192
Name(const std::string &name)
bool operator==(const agx::Name &other) const
Comparison operators.
Definition: Name.h:270
const char * c_str() const
Definition: Name.h:189
bool operator!=(const agx::Name &other) const
Definition: Name.h:295
Name(const agx::String &name)
Name()
Definition: Name.h:162
bool empty() const
Definition: Name.h:194
Name(const char *name)
~Name()
Definition: Name.h:183
void swap(Name &rhs)
Definition: Name.h:309
agx::String str() const
UInt32 hash() const
Definition: Name.h:229
#define agxAssert(expr)
Definition: debug.h:143
#define AGX_FORCE_INLINE
Definition: macros.h:58
The agx namespace contains the dynamics/math part of the AGX Dynamics API.
UInt32 hash(const T &key)
Definition: HashFunction.h:65
uint32_t UInt32
Definition: Integer.h:32
bool operator!=(T val, InvalidIndexStruct)
Definition: agx.h:222
AgXString< std::string > String
Definition: String.h:427
std::ostream & operator<<(std::ostream &os, const agx::AddedMassInteraction::Matrix6x6 &m)
bool operator==(T val, InvalidIndexStruct)
Definition: agx.h:213
void AGXPHYSICS_EXPORT init()
Initialize AGX Dynamics API including thread resources and must be executed before using the AGX API.
STL namespace.
void swap(agx::Name &lhs, agx::Name &rhs)
Definition: Name.h:323