summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2023-06-09 12:38:24 -0400
committerGitHub <noreply@github.com>2023-06-09 12:38:24 -0400
commitd9118d260034319d58376c2ecf67b339568d85fb (patch)
tree3146461052bd96146b1db5e987b65f6bf6f587be
parent3913091a021a8f4525f0050dfb83d1c2b8fc6f6b (diff)
Small improvements around StringBlob (#2924)
* #include an absolute path didn't work - because paths were taken to always be relative. * Small fixes and improvements around reflection tool. * Make PrettyWriter printing a class. * Sundary improvements around StringBlob.
-rw-r--r--source/core/slang-blob.cpp67
-rw-r--r--source/core/slang-blob.h24
-rw-r--r--source/core/slang-string.h12
3 files changed, 50 insertions, 53 deletions
diff --git a/source/core/slang-blob.cpp b/source/core/slang-blob.cpp
index c360f483b..19a4281bd 100644
--- a/source/core/slang-blob.cpp
+++ b/source/core/slang-blob.cpp
@@ -35,71 +35,53 @@ void* BlobBase::castAs(const SlangUUID& guid)
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StringBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-void StringBlob::_uniqueInit(StringRepresentation* uniqueRep)
+void StringBlob::_setUniqueRep(StringRepresentation* uniqueRep)
{
- // When initing the rep either has to be nullptr *or* uniquely referenced
- // so we can take ownership of it.
-
SLANG_ASSERT(uniqueRep == nullptr || uniqueRep->isUniquelyReferenced());
- m_rep = uniqueRep;
-
- // If it's nullptr, that means the string is the empty string. To handle we
- //
- if (!uniqueRep)
- {
- m_chars = "";
- m_charsCount = 0;
- }
- else
- {
- m_chars = uniqueRep->getData();
- m_charsCount = uniqueRep->getLength();
- }
+ m_uniqueRep = uniqueRep;
- _checkRep();
+ m_slice = uniqueRep ?
+ UnownedTerminatedStringSlice(uniqueRep->getData(), uniqueRep->getLength()) :
+ UnownedTerminatedStringSlice();
}
-void StringBlob::_init(StringRepresentation* rep)
+/* static */StringRepresentation* StringBlob::_createUniqueCopy(StringRepresentation* rep)
{
if (rep)
{
- // Even if the uniqueRep is 1, we can't assume we can take ownership
- // So we make a copy
-
// If the length is 0, we can just init as empty
auto length = rep->getLength();
if (length == 0)
{
- rep = nullptr;
+ return nullptr;
}
else
{
const UnownedStringSlice slice(rep->getData(), length);
- rep = StringRepresentation::createWithReference(slice);
+ return StringRepresentation::createWithReference(slice);
}
}
+ return nullptr;
+}
- // Must be unique at this point
- _uniqueInit(rep);
-
- _checkRep();
+void StringBlob::_setWithCopy(StringRepresentation* rep)
+{
+ _setUniqueRep(_createUniqueCopy(rep));
}
-void StringBlob::_moveInit(StringRepresentation* rep)
+void StringBlob::_setWithMove(StringRepresentation* rep)
{
if (rep && !rep->isUniquelyReferenced())
{
- // Will make a copy of the rep
- _init(rep);
+ _setUniqueRep(_createUniqueCopy(rep));
// We need to release a ref as rep is passed in with the 'current' ref count
rep->releaseReference();
}
else
{
- _uniqueInit(rep);
+ _setUniqueRep(rep);
}
- _checkRep();
}
/* static */ComPtr<ISlangBlob> StringBlob::create(const UnownedStringSlice& slice)
@@ -110,38 +92,39 @@ void StringBlob::_moveInit(StringRepresentation* rep)
rep = StringRepresentation::createWithReference(slice);
}
- // rep must be unique at this point
auto blob = new StringBlob;
- blob->_uniqueInit(rep);
+
+ // rep must be unique at this point
+ blob->_setUniqueRep(rep);
return ComPtr<ISlangBlob>(blob);
}
/* static */ComPtr<ISlangBlob> StringBlob::create(const String& in)
{
auto blob = new StringBlob;
- blob->_init(in.getStringRepresentation());
+ blob->_setWithCopy(in.getStringRepresentation());
return ComPtr<ISlangBlob>(blob);
}
/* static */ComPtr<ISlangBlob> StringBlob::moveCreate(String& in)
{
auto blob = new StringBlob;
- blob->_moveInit(in.detachStringRepresentation());
+ blob->_setWithMove(in.detachStringRepresentation());
return ComPtr<ISlangBlob>(blob);
}
/* static */ComPtr<ISlangBlob> StringBlob::moveCreate(String&& in)
{
auto blob = new StringBlob;
- blob->_moveInit(in.detachStringRepresentation());
+ blob->_setWithMove(in.detachStringRepresentation());
return ComPtr<ISlangBlob>(blob);
}
StringBlob::~StringBlob()
{
- if (m_rep)
+ if (m_uniqueRep)
{
- delete m_rep;
+ delete m_uniqueRep;
}
}
void* StringBlob::castAs(const SlangUUID& guid)
@@ -163,7 +146,7 @@ void* StringBlob::getObject(const Guid& guid)
// Can always be accessed as terminated char*
if (guid == SlangTerminatedChars::getTypeGuid())
{
- return const_cast<char*>(m_chars);
+ return const_cast<char*>(m_slice.begin());
}
return nullptr;
}
diff --git a/source/core/slang-blob.h b/source/core/slang-blob.h
index f439a4eae..7a2c4d967 100644
--- a/source/core/slang-blob.h
+++ b/source/core/slang-blob.h
@@ -45,8 +45,8 @@ public:
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
// ISlangBlob
- SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_chars; }
- SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_charsCount; }
+ SLANG_NO_THROW void const* SLANG_MCALL getBufferPointer() SLANG_OVERRIDE { return m_slice.begin(); }
+ SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_slice.getLength(); }
/// Since in is not being moved will *always* create a new representation, unless the in is empty
static ComPtr<ISlangBlob> create(const String& in);
@@ -63,21 +63,23 @@ public:
~StringBlob();
protected:
- /// Use when rep *must* be unique (ie nullptr, and has a ref count of 1, that can be `taken` by the blob
- void _uniqueInit(StringRepresentation* uniqueRep);
+
/// Init with a rep when can't be owned.
- void _init(StringRepresentation* rep);
+ void _setWithCopy(StringRepresentation* rep);
/// Init with a representation that has been moved.
- void _moveInit(StringRepresentation* rep);
+ void _setWithMove(StringRepresentation* rep);
+
+ /// Create a unique copy of rep.
+ /// If nullptr will work (if rep is empty, will return that)
+ static StringRepresentation* _createUniqueCopy(StringRepresentation* rep);
- /// Checks that m_rep is either nullptr or has a ref count of 1 (ie it is owned by the blob)
- SLANG_FORCE_INLINE void _checkRep() const { SLANG_ASSERT(m_rep == nullptr || m_rep->isUniquelyReferenced()); }
+ /// Rep can only be nullptr or have a single ref
+ void _setUniqueRep(StringRepresentation* rep);
void* getObject(const Guid& guid);
- char* m_chars = nullptr; ///< Pointer to the contained data.
- size_t m_charsCount = 0; ///< The amount of chars *not* including terminating 0
- StringRepresentation* m_rep = nullptr; ///< Holds actual bytes. Can be nullptr if it's an empty string.
+ UnownedTerminatedStringSlice m_slice; ///< The contents
+ StringRepresentation* m_uniqueRep = nullptr; ///< Holds actual bytes. Can be nullptr if it's an empty string.
};
class ListBlob : public BlobBase
diff --git a/source/core/slang-string.h b/source/core/slang-string.h
index b4583d0b2..65fd3a315 100644
--- a/source/core/slang-string.h
+++ b/source/core/slang-string.h
@@ -81,6 +81,10 @@ namespace Slang
public:
typedef UnownedStringSlice ThisType;
+ // Type to indicate that a ctor is with a length to disabmiguate 0/nullptr
+ // causing ambiguity.
+ struct WithLength {};
+
UnownedStringSlice()
: m_begin(nullptr)
, m_end(nullptr)
@@ -98,6 +102,10 @@ namespace Slang
: m_begin(b)
, m_end(b + len)
{}
+ UnownedStringSlice(WithLength, char const* b, size_t len)
+ : m_begin(b)
+ , m_end(b + len)
+ {}
SLANG_FORCE_INLINE char const* begin() const { return m_begin; }
@@ -190,6 +198,7 @@ namespace Slang
SLANG_FORCE_INLINE static UnownedStringSlice fromLiteral(const char (&in)[SIZE]) { return UnownedStringSlice(in, SIZE - 1); }
protected:
+
char const* m_begin;
char const* m_end;
};
@@ -216,6 +225,9 @@ namespace Slang
template <size_t SIZE>
SLANG_FORCE_INLINE static ThisType fromLiteral(const char(&in)[SIZE]) { return ThisType(in, SIZE - 1); }
+ /// Default constructor
+ UnownedTerminatedStringSlice():Super(Super::WithLength(), "", 0) {}
+
/// Note, b cannot be null because if it were then the string would not be null terminated
UnownedTerminatedStringSlice(char const* b)
: Super(b, b + strlen(b))