summaryrefslogtreecommitdiffstats
path: root/source/core
diff options
context:
space:
mode:
Diffstat (limited to 'source/core')
-rw-r--r--source/core/core.natvis4
-rw-r--r--source/core/slang-io.cpp45
-rw-r--r--source/core/slang-string.cpp251
-rw-r--r--source/core/slang-string.h658
-rw-r--r--source/core/smart-pointer.h593
-rw-r--r--source/core/stream.h2
-rw-r--r--source/core/text-io.cpp6
-rw-r--r--source/core/text-io.h4
8 files changed, 757 insertions, 806 deletions
diff --git a/source/core/core.natvis b/source/core/core.natvis
index 19c6db395..3d9ac702e 100644
--- a/source/core/core.natvis
+++ b/source/core/core.natvis
@@ -3,8 +3,8 @@
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="Slang::String">
- <DisplayString>{buffer.pointer,s}</DisplayString>
- <StringView>buffer.pointer,s</StringView>
+ <DisplayString>{((char*) (buffer.pointer+1)),s}</DisplayString>
+ <StringView>((char*) (buffer.pointer+1)),s</StringView>
</Type>
<Type Name="Slang::ArrayView&lt;*&gt;">
diff --git a/source/core/slang-io.cpp b/source/core/slang-io.cpp
index dc2793fc4..684fed0a1 100644
--- a/source/core/slang-io.cpp
+++ b/source/core/slang-io.cpp
@@ -40,24 +40,46 @@ namespace Slang
sb.Append(newExt);
return sb.ProduceString();
}
+
+ static UInt findLastSeparator(String const& path)
+ {
+ UInt slashPos = path.LastIndexOf('/');
+ UInt backslashPos = path.LastIndexOf('\\');
+
+ if (slashPos == -1) return backslashPos;
+ if (backslashPos == -1) return slashPos;
+
+ UInt pos = slashPos;
+ if (backslashPos > slashPos)
+ pos = backslashPos;
+
+ return pos;
+ }
+
String Path::GetFileName(const String & path)
{
- int pos = path.LastIndexOf('/');
- pos = Math::Max(path.LastIndexOf('\\'), pos) + 1;
- return path.SubString(pos, path.Length()-pos);
+ UInt pos = findLastSeparator(path);
+ if (pos != -1)
+ {
+ pos = pos + 1;
+ return path.SubString(pos, path.Length() - pos);
+ }
+ else
+ {
+ return path;
+ }
}
String Path::GetFileNameWithoutEXT(const String & path)
{
- int pos = path.LastIndexOf('/');
- pos = Math::Max(path.LastIndexOf('\\'), pos) + 1;
- int dotPos = path.LastIndexOf('.');
- if (dotPos <= pos)
- dotPos = path.Length();
- return path.SubString(pos, dotPos - pos);
+ String fileName = GetFileName(path);
+ int dotPos = fileName.LastIndexOf('.');
+ if (dotPos == -1)
+ return fileName;
+ return fileName.SubString(0, dotPos);
}
String Path::GetFileExt(const String & path)
{
- int dotPos = path.LastIndexOf('.');
+ UInt dotPos = path.LastIndexOf('.');
if (dotPos != -1)
return path.SubString(dotPos+1, path.Length()-dotPos-1);
else
@@ -65,8 +87,7 @@ namespace Slang
}
String Path::GetDirectoryName(const String & path)
{
- int pos = path.LastIndexOf('/');
- pos = Math::Max(path.LastIndexOf('\\'), pos);
+ UInt pos = findLastSeparator(path);
if (pos != -1)
return path.SubString(0, pos);
else
diff --git a/source/core/slang-string.cpp b/source/core/slang-string.cpp
index b7eaadcb3..3b9bcc87f 100644
--- a/source/core/slang-string.cpp
+++ b/source/core/slang-string.cpp
@@ -3,42 +3,76 @@
namespace Slang
{
+ // OSString
+
+ OSString::OSString()
+ : beginData(0)
+ , endData(0)
+ {}
+
+ OSString::OSString(wchar_t* begin, wchar_t* end)
+ : beginData(begin)
+ , endData(end)
+ {}
+
+ OSString::~OSString()
+ {
+ if (beginData)
+ {
+ delete[] beginData;
+ }
+ }
+
+ static const wchar_t kEmptyOSString[] = { 0 };
+
+ wchar_t const* OSString::begin() const
+ {
+ return beginData ? beginData : kEmptyOSString;
+ }
+
+ wchar_t const* OSString::end() const
+ {
+ return endData ? endData : kEmptyOSString;
+ }
+
+ // StringSlice
+
+ StringSlice::StringSlice()
+ : representation(0)
+ , beginIndex(0)
+ , endIndex(0)
+ {}
+
+ StringSlice::StringSlice(String const& str, UInt beginIndex, UInt endIndex)
+ : representation(str.buffer)
+ , beginIndex(beginIndex)
+ , endIndex(endIndex)
+ {}
+
+
+ //
+
_EndLine EndLine;
- String StringConcat(const char * lhs, int leftLen, const char * rhs, int rightLen)
- {
- String res;
- res.length = leftLen + rightLen;
- res.buffer = new char[res.length + 1];
- strcpy_s(res.buffer.Ptr(), res.length + 1, lhs);
- strcpy_s(res.buffer + leftLen, res.length + 1 - leftLen, rhs);
- return res;
- }
- String operator+(const char * op1, const String & op2)
- {
- if(!op2.buffer)
- return String(op1);
- return StringConcat(op1, (int)strlen(op1), op2.buffer.Ptr(), op2.length);
+ String operator+(const char * op1, const String & op2)
+ {
+ String result(op1);
+ result.append(op2);
+ return result;
}
String operator+(const String & op1, const char * op2)
{
- if(!op1.buffer)
- return String(op2);
-
- return StringConcat(op1.buffer.Ptr(), op1.length, op2, (int)strlen(op2));
+ String result(op1);
+ result.append(op2);
+ return result;
}
String operator+(const String & op1, const String & op2)
{
- if(!op1.buffer && !op2.buffer)
- return String();
- else if(!op1.buffer)
- return String(op2);
- else if(!op2.buffer)
- return String(op1);
-
- return StringConcat(op1.buffer.Ptr(), op1.length, op2.buffer.Ptr(), op2.length);
+ String result(op1);
+ result.append(op2);
+ return result;
}
int StringToInt(const String & str, int radix)
@@ -64,6 +98,7 @@ namespace Slang
return strtof(str.Buffer(), NULL);
}
+#if 0
String String::ReplaceAll(String src, String dst) const
{
String rs = *this;
@@ -77,6 +112,7 @@ namespace Slang
}
return rs;
}
+#endif
String String::FromWString(const wchar_t * wstr)
{
@@ -113,51 +149,150 @@ namespace Slang
return String(buf);
}
- const wchar_t * String::ToWString(int * len) const
+ OSString String::ToWString(int* outLength) const
{
if (!buffer)
{
- if (len)
- *len = 0;
- return L"";
+ return OSString();
}
else
{
- if (wcharBuffer)
- {
- if (len)
- *len = (int)wcslen(wcharBuffer);
- return wcharBuffer;
- }
List<char> buf;
Slang::Encoding::UTF16->GetBytes(buf, *this);
- if (len)
- *len = buf.Count() / sizeof(wchar_t);
+
+ auto length = buf.Count() / sizeof(wchar_t);
+ if (outLength)
+ *outLength = length;
+
buf.Add(0);
buf.Add(0);
- const_cast<String*>(this)->wcharBuffer = (wchar_t*)buf.Buffer();
+
+ wchar_t* beginData = (wchar_t*)buf.Buffer();
+ wchar_t* endData = beginData + length;
+
buf.ReleaseBuffer();
- return wcharBuffer;
+
+ return OSString(beginData, endData);
}
}
- String String::PadLeft(char ch, int pLen)
- {
- StringBuilder sb;
- for (int i = 0; i < pLen - this->length; i++)
- sb << ch;
- for (int i = 0; i < this->length; i++)
- sb << buffer[i];
- return sb.ProduceString();
- }
+ //
- String String::PadRight(char ch, int pLen)
- {
- StringBuilder sb;
- for (int i = 0; i < this->length; i++)
- sb << buffer[i];
- for (int i = 0; i < pLen - this->length; i++)
- sb << ch;
- return sb.ProduceString();
- }
+ void String::ensureUniqueStorageWithCapacity(UInt requiredCapacity)
+ {
+ if (buffer && buffer->isUniquelyReferenced() && buffer->capacity >= requiredCapacity)
+ return;
+
+ UInt newCapacity = buffer ? 2*buffer->capacity : 16;
+ if (newCapacity < requiredCapacity)
+ {
+ newCapacity = requiredCapacity;
+ }
+
+ UInt length = getLength();
+ StringRepresentation* newRepresentation = StringRepresentation::createWithCapacityAndLength(newCapacity, length);
+
+ if (buffer)
+ {
+ memcpy(newRepresentation->getData(), buffer->getData(), length + 1);
+ }
+
+ buffer = newRepresentation;
+ }
+
+ char* String::prepareForAppend(UInt count)
+ {
+ auto oldLength = getLength();
+ auto newLength = oldLength + count;
+ ensureUniqueStorageWithCapacity(newLength);
+ return getData() + oldLength;
+ }
+
+
+ void String::append(const char* textBegin, char const* textEnd)
+ {
+ auto oldLength = getLength();
+ auto textLength = textEnd - textBegin;
+
+ auto newLength = oldLength + textLength;
+
+ ensureUniqueStorageWithCapacity(newLength);
+
+ memcpy(getData() + oldLength, textBegin, textLength);
+ getData()[newLength] = 0;
+ buffer->length = newLength;
+ }
+
+ void String::append(char const* str)
+ {
+ if (str)
+ {
+ append(str, str + strlen(str));
+ }
+ }
+
+ void String::append(char chr)
+ {
+ append(&chr, &chr + 1);
+ }
+
+ void String::append(String const& str)
+ {
+ if (!buffer)
+ {
+ buffer = str.buffer;
+ return;
+ }
+
+ append(str.begin(), str.end());
+ }
+
+ void String::append(StringSlice const& slice)
+ {
+ append(slice.begin(), slice.end());
+ }
+
+ void String::append(int value, int radix)
+ {
+ enum { kCount = 33 };
+ char* data = prepareForAppend(kCount);
+ auto count = IntToAscii(data, value, radix);
+ ReverseInternalAscii(data, count);
+ buffer->length += count;
+ }
+
+ void String::append(unsigned int value, int radix)
+ {
+ enum { kCount = 33 };
+ char* data = prepareForAppend(kCount);
+ auto count = IntToAscii(data, value, radix);
+ ReverseInternalAscii(data, count);
+ buffer->length += count;
+ }
+
+ void String::append(long long value, int radix)
+ {
+ enum { kCount = 65 };
+ char* data = prepareForAppend(kCount);
+ auto count = IntToAscii(data, value, radix);
+ ReverseInternalAscii(data, count);
+ buffer->length += count;
+ }
+
+
+ void String::append(float val, const char * format)
+ {
+ enum { kCount = 128 };
+ char* data = prepareForAppend(kCount);
+ sprintf_s(data, kCount, format, val);
+ buffer->length += strnlen_s(data, kCount);
+ }
+
+ void String::append(double val, const char * format)
+ {
+ enum { kCount = 128 };
+ char* data = prepareForAppend(kCount);
+ sprintf_s(data, kCount, format, val);
+ buffer->length += strnlen_s(data, kCount);
+ }
}
diff --git a/source/core/slang-string.h b/source/core/slang-string.h
index 448b351aa..8294d4bc3 100644
--- a/source/core/slang-string.h
+++ b/source/core/slang-string.h
@@ -8,6 +8,8 @@
#include "hash.h"
#include "secure-crt.h"
+#include <new>
+
namespace Slang
{
class _EndLine
@@ -58,35 +60,182 @@ namespace Slang
return (((unsigned char)ch) & 0xC0) == 0x80;
}
+ // A `StringRepresentation` provides the backing storage for
+ // all reference-counted string-related types.
+ class StringRepresentation : public RefObject
+ {
+ public:
+ UInt length;
+ UInt capacity;
+
+ UInt getLength()
+ {
+ return length;
+ }
+
+ char* getData()
+ {
+ return (char*) (this + 1);
+ }
+
+ static StringRepresentation* createWithCapacityAndLength(UInt capacity, UInt length)
+ {
+ assert(capacity >= length);
+ void* allocation = operator new(sizeof(StringRepresentation) + capacity + 1);
+ StringRepresentation* obj = new(allocation) StringRepresentation();
+ obj->capacity = capacity;
+ obj->length = length;
+ obj->getData()[length] = 0;
+ return obj;
+ }
+
+ static StringRepresentation* createWithCapacity(UInt capacity)
+ {
+ return createWithCapacityAndLength(capacity, 0);
+ }
+
+ static StringRepresentation* createWithLength(UInt length)
+ {
+ return createWithCapacityAndLength(length, length);
+ }
+
+ StringRepresentation* cloneWithCapacity(UInt newCapacity)
+ {
+ StringRepresentation* newObj = createWithCapacityAndLength(newCapacity, length);
+ memcpy(getData(), newObj->getData(), length + 1);
+ return newObj;
+ }
+
+ StringRepresentation* clone()
+ {
+ return cloneWithCapacity(length);
+ }
+
+ StringRepresentation* ensureCapacity(UInt required)
+ {
+ if (capacity >= required) return this;
+
+ UInt newCapacity = capacity;
+ if (!newCapacity) newCapacity = 16; // TODO: figure out good value for minimum capacity
+
+ while (newCapacity < required)
+ {
+ newCapacity = 2 * newCapacity;
+ }
+
+ return cloneWithCapacity(newCapacity);
+ }
+ };
+
+ class String;
+
+ struct UnownedStringSlice
+ {
+ public:
+
+ char const* begin() const
+ {
+ return beginData;
+ }
+
+ char const* end() const
+ {
+ return endData;
+ }
+
+ private:
+ char const* beginData;
+ char const* endData;
+ };
+
+ struct StringSlice
+ {
+ public:
+ StringSlice();
+
+ StringSlice(String const& str, UInt beginIndex, UInt endIndex);
+
+ UInt getLength() const
+ {
+ return endIndex - beginIndex;
+ }
+
+ char const* begin() const
+ {
+ return representation ? representation->getData() + beginIndex : "";
+ }
+
+ char const* end() const
+ {
+ return begin() + getLength();
+ }
+
+ private:
+ RefPtr<StringRepresentation> representation;
+ UInt beginIndex;
+ UInt endIndex;
+
+ friend class String;
+
+ StringSlice(RefPtr<StringRepresentation> const& representation, UInt beginIndex, UInt endIndex)
+ : representation(representation)
+ , beginIndex(beginIndex)
+ , endIndex(endIndex)
+ {}
+ };
+
+ /// String as expected by underlying platform APIs
+ class OSString
+ {
+ public:
+ OSString();
+ OSString(wchar_t* begin, wchar_t* end);
+ ~OSString();
+
+ operator wchar_t const*() const
+ {
+ return begin();
+ }
+
+ wchar_t const* begin() const;
+ wchar_t const* end() const;
+
+ private:
+ wchar_t* beginData;
+ wchar_t* endData;
+ };
+
/*!
@brief Represents a UTF-8 encoded string.
*/
class String
{
+ friend struct StringSlice;
friend class StringBuilder;
private:
- RefPtr<char, RefPtrArrayDestructor> buffer;
- wchar_t * wcharBuffer = nullptr;
- int length = 0;
- void Free()
- {
- if (buffer)
- buffer = 0;
- if (wcharBuffer)
- delete[] wcharBuffer;
- buffer = 0;
- wcharBuffer = 0;
- length = 0;
- }
- public:
- static String FromBuffer(RefPtr<char, RefPtrArrayDestructor> buffer, int len)
- {
- String rs;
- rs.buffer = buffer;
- rs.length = len;
- return rs;
- }
+
+
+ char* getData() const
+ {
+ return buffer ? buffer->getData() : "";
+ }
+
+ UInt getLength() const
+ {
+ return buffer ? buffer->getLength() : 0;
+ }
+
+ void ensureUniqueStorageWithCapacity(UInt capacity);
+ char* prepareForAppend(UInt count);
+
+ RefPtr<StringRepresentation> buffer;
+
+ String(StringRepresentation* buffer)
+ : buffer(buffer)
+ {}
+
+ public:
static String FromWString(const wchar_t * wstr);
static String FromWString(const wchar_t * wstr, const wchar_t * wend);
static String FromWChar(const wchar_t ch);
@@ -94,409 +243,376 @@ namespace Slang
String()
{
}
+
const char * begin() const
{
- return buffer.Ptr();
+ return getData();
}
const char * end() const
{
- return buffer.Ptr() + length;
+ return getData() + getLength();
}
+
+ void append(int value, int radix = 10);
+ void append(unsigned int value, int radix = 10);
+ void append(long long value, int radix = 10);
+ void append(float val, const char * format = "%g");
+ void append(double val, const char * format = "%g");
+
+ void append(char const* str);
+ void append(const char* textBegin, char const* textEnd);
+ void append(char chr);
+ void append(String const& str);
+ void append(StringSlice const& slice);
+
String(int val, int radix = 10)
{
- buffer = new char[33];
- length = IntToAscii(buffer.Ptr(), val, radix);
- ReverseInternalAscii(buffer.Ptr(), length);
+ append(val, radix);
+#if 0
+ buffer = StringRepresentation::createWithLength(33);
+ buffer->length = IntToAscii(getData(), val, radix);
+ ReverseInternalAscii(getData(), getLength());
+#endif
}
String(unsigned int val, int radix = 10)
{
- buffer = new char[33];
- length = IntToAscii(buffer.Ptr(), val, radix);
- ReverseInternalAscii(buffer.Ptr(), length);
+ append(val, radix);
+#if 0
+ buffer = StringRepresentation::createWithLength(33);
+ buffer->length = IntToAscii(getData(), val, radix);
+ ReverseInternalAscii(getData(), getLength());
+#endif
}
String(long long val, int radix = 10)
{
- buffer = new char[65];
- length = IntToAscii(buffer.Ptr(), val, radix);
- ReverseInternalAscii(buffer.Ptr(), length);
+ append(val, radix);
+#if 0
+ buffer = StringRepresentation::createWithLength(65);
+ buffer->length = IntToAscii(getData(), val, radix);
+ ReverseInternalAscii(getData(), getLength());
+#endif
}
String(float val, const char * format = "%g")
{
- buffer = new char[128];
- sprintf_s(buffer.Ptr(), 128, format, val);
- length = (int)strnlen_s(buffer.Ptr(), 128);
+ append(val, format);
+#if 0
+ buffer = StringRepresentation::createWithLength(128);
+ sprintf_s(getData(), 128, format, val);
+ buffer->length = (int)strnlen_s(begin(), 128);
+#endif
}
String(double val, const char * format = "%g")
{
- buffer = new char[128];
- sprintf_s(buffer.Ptr(), 128, format, val);
- length = (int)strnlen_s(buffer.Ptr(), 128);
+ append(val, format);
+#if 0
+ buffer = StringRepresentation::createWithLength(128);
+ sprintf_s(getData(), 128, format, val);
+ buffer->length = (int)strnlen_s(begin(), 128);
+#endif
}
String(const char * str)
{
+ append(str);
+#if 0
if (str)
{
- length = (int)strlen(str);
- buffer = new char[length + 1];
- memcpy(buffer.Ptr(), str, length + 1);
+ buffer = StringRepresentation::createWithLength(strlen(str));
+ memcpy(buffer.Ptr(), str, getLength() + 1);
}
+#endif
}
String(const char* textBegin, char const* textEnd)
{
+ append(textBegin, textEnd);
+#if 0
if (textBegin != textEnd)
{
- length = (int)(textEnd - textBegin);
- buffer = new char[length + 1];
- memcpy(buffer.Ptr(), textBegin, length + 1);
- buffer.Ptr()[length] = 0;
+ buffer = StringRepresentation::createWithLength(textEnd - textBegin);
+ memcpy(buffer.Ptr(), textBegin, getLength());
+ buffer->getData()[getLength()] = 0;
}
+#endif
}
String(char chr)
{
+ append(chr);
+#if 0
if (chr)
{
- length = 1;
- buffer = new char[2];
- buffer[0] = chr;
- buffer[1] = '\0';
+ buffer = StringRepresentation::createWithLength(1);
+ buffer->getData()[0] = chr;
+ buffer->getData()[1] = 0;
}
+#endif
}
- String(const String & str)
+ String(String const& str)
{
+ buffer = str.buffer;
+#if 0
this->operator=(str);
+#endif
}
String(String&& other)
{
- this->operator=(static_cast<String&&>(other));
+ buffer = _Move(other.buffer);
}
+
+ String(StringSlice const& slice)
+ {
+ append(slice);
+ }
+
~String()
{
- Free();
+ buffer = 0;
}
+
String & operator=(const String & str)
{
- if (str.buffer == buffer)
- return *this;
- Free();
- if (str.buffer)
- {
- length = str.length;
- buffer = str.buffer;
- wcharBuffer = 0;
- }
+ buffer = str.buffer;
return *this;
}
String & operator=(String&& other)
{
- if (this != &other)
- {
- Free();
- buffer = _Move(other.buffer);
- length = other.length;
- wcharBuffer = other.wcharBuffer;
- other.buffer = 0;
- other.length = 0;
- other.wcharBuffer = 0;
- }
- return *this;
+ buffer = _Move(other.buffer);
+ return *this;
}
- char operator[](int id) const
+ char operator[](UInt id) const
{
#if _DEBUG
- if (id < 0 || id >= length)
+ if (id < 0 || id >= getLength())
throw "Operator[]: index out of range.";
#endif
- return buffer.Ptr()[id];
+ return begin()[id];
}
- friend String StringConcat(const char * lhs, int leftLen, const char * rhs, int rightLen);
friend String operator+(const char*op1, const String & op2);
friend String operator+(const String & op1, const char * op2);
friend String operator+(const String & op1, const String & op2);
- String TrimStart() const
+ StringSlice TrimStart() const
{
if (!buffer)
- return *this;
- int startIndex = 0;
- while (startIndex < length &&
- (buffer[startIndex] == ' ' || buffer[startIndex] == '\t' || buffer[startIndex] == '\r' || buffer[startIndex] == '\n'))
+ return StringSlice();
+ UInt startIndex = 0;
+ while (startIndex < getLength() &&
+ (getData()[startIndex] == ' ' || getData()[startIndex] == '\t' || getData()[startIndex] == '\r' || getData()[startIndex] == '\n'))
startIndex++;
- return String(buffer + startIndex);
+ return StringSlice(buffer, startIndex, getLength());
}
- String TrimEnd() const
+ StringSlice TrimEnd() const
{
if (!buffer)
- return *this;
+ return StringSlice();
- int endIndex = length - 1;
- while (endIndex >= 0 &&
- (buffer[endIndex] == ' ' || buffer[endIndex] == '\t' || buffer[endIndex] == '\r' || buffer[endIndex] == '\n'))
+ UInt endIndex = getLength();
+ while (endIndex > 0 &&
+ (getData()[endIndex-1] == ' ' || getData()[endIndex-1] == '\t' || getData()[endIndex-1] == '\r' || getData()[endIndex-1] == '\n'))
endIndex--;
- String res;
- res.length = endIndex + 1;
- res.buffer = new char[endIndex + 2];
- strncpy_s(res.buffer.Ptr(), endIndex + 2, buffer.Ptr(), endIndex + 1);
- return res;
+
+ return StringSlice(buffer, 0, endIndex);
}
- String Trim() const
+ StringSlice Trim() const
{
if (!buffer)
- return *this;
+ return StringSlice();
- int startIndex = 0;
- while (startIndex < length &&
- (buffer[startIndex] == ' ' || buffer[startIndex] == '\t'))
+ UInt startIndex = 0;
+ while (startIndex < getLength() &&
+ (getData()[startIndex] == ' ' || getData()[startIndex] == '\t'))
startIndex++;
- int endIndex = length - 1;
- while (endIndex >= startIndex &&
- (buffer[endIndex] == ' ' || buffer[endIndex] == '\t'))
+ UInt endIndex = getLength();
+ while (endIndex > startIndex &&
+ (getData()[endIndex-1] == ' ' || getData()[endIndex-1] == '\t'))
endIndex--;
- String res;
- res.length = endIndex - startIndex + 1;
- res.buffer = new char[res.length + 1];
- memcpy(res.buffer.Ptr(), buffer + startIndex, res.length);
- res.buffer[res.length] = '\0';
- return res;
+ return StringSlice(buffer, startIndex, endIndex);
}
- String SubString(int id, int len) const
+ StringSlice SubString(UInt id, UInt len) const
{
if (len == 0)
- return "";
- if (id + len > length)
- len = length - id;
+ return StringSlice();
+
+ if (id + len > getLength())
+ len = getLength() - id;
#if _DEBUG
- if (id < 0 || id >= length || (id + len) > length)
+ if (id < 0 || id >= getLength() || (id + len) > getLength())
throw "SubString: index out of range.";
if (len < 0)
throw "SubString: length less than zero.";
#endif
- String res;
- res.buffer = new char[len + 1];
- res.length = len;
- strncpy_s(res.buffer.Ptr(), len + 1, buffer + id, len);
- res.buffer[len] = 0;
- return res;
+ return StringSlice(buffer, id, id + len);
}
- const char * Buffer() const
+ char const* Buffer() const
{
- if (buffer)
- return buffer.Ptr();
- else
- return "";
+ return getData();
}
- const wchar_t * ToWString(int * len = 0) const;
+ OSString ToWString(int* len = 0) const;
bool Equals(const String & str, bool caseSensitive = true)
{
- if (!buffer)
- return (str.buffer == 0);
if (caseSensitive)
- return (strcmp(buffer.Ptr(), str.buffer.Ptr()) == 0);
+ return (strcmp(begin(), str.begin()) == 0);
else
{
#ifdef _MSC_VER
- return (_stricmp(buffer.Ptr(), str.buffer.Ptr()) == 0);
+ return (_stricmp(begin(), str.begin()) == 0);
#else
- return (strcasecmp(buffer.Ptr(), str.buffer.Ptr()) == 0);
+ return (strcasecmp(begin(), str.begin()) == 0);
#endif
}
}
bool operator==(const char * strbuffer) const
{
- if (!buffer)
- return (strbuffer == 0 || strcmp(strbuffer, "") == 0);
- if (!strbuffer)
- return buffer == nullptr || strcmp(buffer.Ptr(), "") == 0;
- return (strcmp(buffer.Ptr(), strbuffer) == 0);
+ return (strcmp(begin(), strbuffer) == 0);
}
bool operator==(const String & str) const
{
- if (!buffer)
- return (str.buffer == 0 || strcmp(str.buffer.Ptr(), "") == 0);
- if (!str.buffer)
- return buffer == nullptr || strcmp(buffer.Ptr(), "") == 0;
- return (strcmp(buffer.Ptr(), str.buffer.Ptr()) == 0);
+ return (strcmp(begin(), str.begin()) == 0);
}
bool operator!=(const char * strbuffer) const
{
- if (!buffer)
- return (strbuffer != 0 && strcmp(strbuffer, "") != 0);
- if (strbuffer == 0)
- return length != 0;
- return (strcmp(buffer.Ptr(), strbuffer) != 0);
+ return (strcmp(begin(), strbuffer) != 0);
}
bool operator!=(const String & str) const
{
- if (!buffer)
- return (str.buffer != 0 && strcmp(str.buffer.Ptr(), "") != 0);
- if (str.buffer.Ptr() == 0)
- return length != 0;
- return (strcmp(buffer.Ptr(), str.buffer.Ptr()) != 0);
+ return (strcmp(begin(), str.begin()) != 0);
}
bool operator>(const String & str) const
{
- if (!buffer)
- return false;
- if (!str.buffer)
- return buffer.Ptr() != nullptr && length != 0;
- return (strcmp(buffer.Ptr(), str.buffer.Ptr()) > 0);
+ return (strcmp(begin(), str.begin()) > 0);
}
bool operator<(const String & str) const
{
- if (!buffer)
- return (str.buffer != 0);
- if (!str.buffer)
- return false;
- return (strcmp(buffer.Ptr(), str.buffer.Ptr()) < 0);
+ return (strcmp(begin(), str.begin()) < 0);
}
bool operator>=(const String & str) const
{
- if (!buffer)
- return (str.buffer == 0);
- if (!str.buffer)
- return length == 0;
- int res = strcmp(buffer.Ptr(), str.buffer.Ptr());
- return (res > 0 || res == 0);
+ return (strcmp(begin(), str.begin()) >= 0);
}
bool operator<=(const String & str) const
{
- if (!buffer)
- return true;
- if (!str.buffer)
- return length > 0;
- int res = strcmp(buffer.Ptr(), str.buffer.Ptr());
- return (res < 0 || res == 0);
+ return (strcmp(begin(), str.begin()) <= 0);
}
String ToUpper() const
{
- if (!buffer)
- return *this;
- String res;
- res.length = length;
- res.buffer = new char[length + 1];
- for (int i = 0; i <= length; i++)
- res.buffer[i] = (buffer[i] >= 'a' && buffer[i] <= 'z') ?
- (buffer[i] - 'a' + 'A') : buffer[i];
- return res;
+ String result;
+ for (auto c : *this)
+ {
+ int d = (c >= 'a' && c <= 'z') ? (c - ('a' - 'A')) : c;
+ result.append(d);
+ }
+ return result;
}
String ToLower() const
{
- if (!buffer)
- return *this;
- String res;
- res.length = length;
- res.buffer = new char[length + 1];
- for (int i = 0; i <= length; i++)
- res.buffer[i] = (buffer[i] >= 'A' && buffer[i] <= 'Z') ?
- (buffer[i] - 'A' + 'a') : buffer[i];
- return res;
+ String result;
+ for (auto c : *this)
+ {
+ int d = (c >= 'A' && c <= 'Z') ? (c - ('A' - 'a')) : c;
+ result.append(d);
+ }
+ return result;
}
- int Length() const
+ UInt Length() const
{
- return length;
+ return getLength();
}
- int IndexOf(const char * str, int id) const // String str
+ UInt IndexOf(const char * str, UInt id) const // String str
{
- if (!buffer)
- return -1;
- if (id < 0 || id >= length)
- return -1;
- auto findRs = strstr(buffer + id, str);
- int res = findRs ? (int)(findRs - buffer.Ptr()) : -1;
- if (res >= 0)
- return res;
- else
- return -1;
+ if (id < 0 || id >= getLength())
+ return UInt(-1);
+ auto findRs = strstr(begin() + id, str);
+ UInt res = findRs ? findRs - begin() : -1;
+ return res;
}
- int IndexOf(const String & str, int id) const
+ UInt IndexOf(const String & str, UInt id) const
{
- return IndexOf(str.buffer.Ptr(), id);
+ return IndexOf(str.begin(), id);
}
- int IndexOf(const char * str) const
+ UInt IndexOf(const char * str) const
{
return IndexOf(str, 0);
}
- int IndexOf(const String & str) const
+ UInt IndexOf(const String & str) const
{
- return IndexOf(str.buffer.Ptr(), 0);
+ return IndexOf(str.begin(), 0);
}
- int IndexOf(char ch, int id) const
+ UInt IndexOf(char ch, UInt id) const
{
#if _DEBUG
- if (id < 0 || id >= length)
+ if (id < 0 || id >= getLength())
throw "SubString: index out of range.";
#endif
if (!buffer)
- return -1;
- for (int i = id; i < length; i++)
- if (buffer[i] == ch)
+ return UInt(-1);
+ for (UInt i = id; i < getLength(); i++)
+ if (getData()[i] == ch)
return i;
- return -1;
+ return UInt(-1);
}
- int IndexOf(char ch) const
+ UInt IndexOf(char ch) const
{
return IndexOf(ch, 0);
}
- int LastIndexOf(char ch) const
+ UInt LastIndexOf(char ch) const
{
- for (int i = length - 1; i >= 0; i--)
- if (buffer[i] == ch)
- return i;
- return -1;
+ for (UInt i = getLength(); i > 0; i--)
+ if (getData()[i-1] == ch)
+ return i-1;
+ return UInt(-1);
}
bool StartsWith(const char * str) const // String str
{
if (!buffer)
return false;
- int strLen = (int)strlen(str);
- if (strLen > length)
+ UInt strLen = strlen(str);
+ if (strLen > getLength())
return false;
- for (int i = 0; i < strLen; i++)
- if (str[i] != buffer[i])
+ for (UInt i = 0; i < strLen; i++)
+ if (str[i] != getData()[i])
return false;
return true;
}
bool StartsWith(const String & str) const
{
- return StartsWith(str.buffer.Ptr());
+ return StartsWith(str.begin());
}
- bool EndsWith(char * str) const // String str
+ bool EndsWith(char const * str) const // String str
{
if (!buffer)
return false;
- int strLen = (int)strlen(str);
- if (strLen > length)
+ UInt strLen = strlen(str);
+ if (strLen > getLength())
return false;
- for (int i = strLen - 1; i >= 0; i--)
- if (str[i] != buffer[length - strLen + i])
+ for (UInt i = strLen; i > 0; i--)
+ if (str[i-1] != getData()[getLength() - strLen + i-1])
return false;
return true;
}
bool EndsWith(const String & str) const
{
- return EndsWith(str.buffer.Ptr());
+ return EndsWith(str.begin());
}
bool Contains(const char * str) const // String str
@@ -508,52 +624,27 @@ namespace Slang
bool Contains(const String & str) const
{
- return Contains(str.buffer.Ptr());
+ return Contains(str.begin());
}
int GetHashCode() const
{
- return Slang::GetHashCode((const char*)buffer.Ptr());
+ return Slang::GetHashCode((const char*)begin());
}
- String PadLeft(char ch, int length);
- String PadRight(char ch, int length);
- String ReplaceAll(String src, String dst) const;
};
- class StringBuilder
+ class StringBuilder : public String
{
private:
- char * buffer;
- int length;
- int bufferSize;
- static const int InitialSize = 512;
+ static const int InitialSize = 1024;
public:
- StringBuilder(int bufferSize = 1024)
- :buffer(0), length(0), bufferSize(0)
- {
- buffer = new char[InitialSize]; // new a larger buffer
- buffer[0] = '\0';
- length = 0;
- bufferSize = InitialSize;
- }
- ~StringBuilder()
+ explicit StringBuilder(int bufferSize = InitialSize)
{
- if (buffer)
- delete[] buffer;
+ ensureUniqueStorageWithCapacity(bufferSize);
}
void EnsureCapacity(int size)
{
- if (bufferSize < size)
- {
- char * newBuffer = new char[size + 1];
- if (buffer)
- {
- strcpy_s(newBuffer, size + 1, buffer);
- delete[] buffer;
- }
- buffer = newBuffer;
- bufferSize = size;
- }
+ ensureUniqueStorageWithCapacity(size);
}
StringBuilder & operator << (char ch)
{
@@ -649,31 +740,10 @@ namespace Slang
}
void Append(const char * str, int strLen)
{
- int newLength = length + strLen;
- if (bufferSize < newLength + 1)
- {
- int newBufferSize = InitialSize;
- while (newBufferSize < newLength + 1)
- newBufferSize <<= 1;
- char * newBuffer = new char[newBufferSize];
- if (buffer)
- {
- memcpy(newBuffer, buffer, length);
- delete[] buffer;
- }
- memcpy(newBuffer + length, str, strLen);
- newBuffer[newLength] = '\0';
- buffer = newBuffer;
- bufferSize = newBufferSize;
- }
- else
- {
- memcpy(buffer + length, str, strLen);
- buffer[newLength] = '\0';
- }
- length = newLength;
+ append(str, str + strLen);
}
+#if 0
int Capacity()
{
return bufferSize;
@@ -688,24 +758,19 @@ namespace Slang
{
return length;
}
+#endif
String ToString()
{
- return String(buffer);
+ return *this;
}
String ProduceString()
{
- String rs;
- rs.buffer = buffer;
- rs.length = length;
- buffer = 0;
- bufferSize = 0;
- length = 0;
- return rs;
-
+ return *this;
}
+#if 0
String GetSubString(int start, int count)
{
String rs;
@@ -715,7 +780,9 @@ namespace Slang
rs.buffer[count] = 0;
return rs;
}
+#endif
+#if 0
void Remove(int id, int len)
{
#if _DEBUG
@@ -729,12 +796,11 @@ namespace Slang
buffer[i - actualDelLength] = buffer[i];
length -= actualDelLength;
}
+#endif
void Clear()
{
- length = 0;
- if (buffer)
- buffer[0] = 0;
+ buffer = 0;
}
};
diff --git a/source/core/smart-pointer.h b/source/core/smart-pointer.h
index d307e4e13..c31cdefe0 100644
--- a/source/core/smart-pointer.h
+++ b/source/core/smart-pointer.h
@@ -3,462 +3,191 @@
#include "type-traits.h"
+#include <assert.h>
+
namespace Slang
{
- class RefPtrDefaultDestructor
- {
- public:
- template<typename T>
- void operator ()(T * ptr)
- {
- delete ptr;
- }
- };
-
- class RefPtrArrayDestructor
- {
- public:
- template<typename T>
- void operator() (T * ptr)
- {
- delete [] ptr;
- }
- };
+ // TODO: Need to centralize these typedefs
+ typedef uintptr_t UInt;
+
+ // Base class for all reference-counted objects
+ class RefObject
+ {
+ private:
+ UInt referenceCount;
+
+ public:
+ RefObject()
+ : referenceCount(0)
+ {}
+
+ RefObject(const RefObject &)
+ : referenceCount(0)
+ {}
+
+ virtual ~RefObject()
+ {}
+
+ void addReference()
+ {
+ referenceCount++;
+ }
+
+ void releaseReference()
+ {
+ assert(referenceCount != 0);
+ if(--referenceCount == 0)
+ {
+ delete this;
+ }
+ }
+
+ bool isUniquelyReferenced()
+ {
+ assert(referenceCount != 0);
+ return referenceCount == 1;
+ }
+ };
+
+ inline void addReference(RefObject* obj)
+ {
+ if(obj) obj->addReference();
+ }
+
+ inline void releaseReference(RefObject* obj)
+ {
+ if(obj) obj->releaseReference();
+ }
+
+ // "Smart" pointer to a reference-counted object
+ template<typename T>
+ struct RefPtr
+ {
+ RefPtr()
+ : pointer(0)
+ {}
+
+ RefPtr(T* p)
+ : pointer(p)
+ {
+ addReference(p);
+ }
+
+ RefPtr(RefPtr<T> const& p)
+ : pointer(p.pointer)
+ {
+ addReference(p.pointer);
+ }
+
+ RefPtr(RefPtr<T>&& p)
+ : pointer(p.pointer)
+ {
+ p.pointer = 0;
+ }
+
+ template <typename U>
+ RefPtr(RefPtr<U> const& p,
+ typename EnableIf<IsConvertible<T*, U*>::Value, void>::type * = 0)
+ : pointer((U*) p)
+ {
+ addReference((U*) p);
+ }
+
+#if 0
+ void operator=(T* p)
+ {
+ T* old = pointer;
+ addReference(p);
+ pointer = p;
+ releaseReference(old);
+ }
+#endif
+
+ void operator=(RefPtr<T> const& p)
+ {
+ T* old = pointer;
+ addReference(p.pointer);
+ pointer = p.pointer;
+ releaseReference(old);
+ }
+
+ void operator=(RefPtr<T>&& p)
+ {
+ T* old = pointer;
+ pointer = p.pointer;
+ p.pointer = old;
+ }
+
+ template <typename U>
+ typename EnableIf<IsConvertible<T*, U*>::value, void>::type
+ operator=(RefPtr<U> const& ptr)
+ {
+ T* old = pointer;
+ addReference(p.pointer);
+ pointer = p.pointer;
+ releaseReference(old);
+ }
- class ReferenceCounted
- {
- template<typename T, bool b, typename Destructor>
- friend class RefPtrImpl;
- private:
- int _refCount = 0;
- public:
- ReferenceCounted() {}
- ReferenceCounted(const ReferenceCounted &)
+ int GetHashCode()
{
- _refCount = 0;
+ return (int)(long long)(void*)pointer;
}
- };
-
- class RefObject : public ReferenceCounted
- {
- public:
- virtual ~RefObject()
- {}
- };
+ bool operator==(const T * ptr) const
+ {
+ return pointer == ptr;
+ }
- template<typename T, bool HasBuiltInCounter, typename Destructor>
- class RefPtrImpl
- {
- };
+ bool operator!=(const T * ptr) const
+ {
+ return pointer != ptr;
+ }
- template<typename T, typename Destructor = RefPtrDefaultDestructor>
- using RefPtr = RefPtrImpl<T, IsBaseOf<ReferenceCounted, T>::Value, Destructor>;
-
- template<typename T, typename Destructor>
- class RefPtrImpl<T, 0, Destructor>
- {
- template<typename T1, bool b, typename Destructor1>
- friend class RefPtrImpl;
- private:
- T * pointer;
- int * refCount;
-
- public:
- RefPtrImpl()
- {
- pointer = 0;
- refCount = 0;
- }
- RefPtrImpl(T * ptr)
- : pointer(0), refCount(0)
+ bool operator==(RefPtr<T> const& ptr) const
{
- this->operator=(ptr);
- }
- RefPtrImpl(const RefPtrImpl<T, 0, Destructor> & ptr)
- : pointer(0), refCount(0)
- {
- this->operator=(ptr);
- }
- RefPtrImpl(RefPtrImpl<T, 0, Destructor> && str)
- : pointer(0), refCount(0)
- {
- this->operator=(static_cast<RefPtrImpl<T, 0, Destructor> &&>(str));
+ return pointer == ptr.pointer;
}
- template <typename U>
- RefPtrImpl(const RefPtrImpl<U, 0, Destructor>& ptr,
- typename EnableIf<IsConvertible<T*, U*>::Value, void>::type * = 0)
- : pointer(0), refCount(0)
+ bool operator!=(RefPtr<T> const& ptr) const
{
- pointer = ptr.pointer;
- if (ptr)
- {
- refCount = ptr.refCount;
- (*refCount)++;
- }
- else
- refCount = 0;
+ return pointer != ptr.pointer;
}
- template <typename U>
- typename EnableIf<IsConvertible<T*, U*>::value, RefPtrImpl<T, 0, Destructor>>::type&
- operator=(const RefPtrImpl<U,0,Destructor> & ptr)
- {
- Unreference();
-
- pointer = ptr;
- if (ptr)
- {
- refCount = ptr.refCount;
- (*refCount)++;
- }
- else
- refCount = 0;
- return *this;
- }
+ template<typename U>
+ RefPtr<U> As() const
+ {
+ RefPtr<U> result(dynamic_cast<U*>(pointer));
+ return result;
+ }
- RefPtrImpl<T, 0, Destructor>& operator=(const RefPtrImpl<T, 0, Destructor> & ptr)
- {
- Unreference();
- pointer = ptr.pointer;
- if (ptr)
- {
- refCount = ptr.refCount;
- (*refCount)++;
- }
- else
- refCount = 0;
- return *this;
- }
+ ~RefPtr()
+ {
+ releaseReference(pointer);
+ }
- RefPtrImpl<T, 0, Destructor>& operator=(T * ptr)
- {
- if (ptr != pointer)
- {
- Unreference();
-
- pointer = ptr;
- if (ptr)
- {
- refCount = new int;
- (*refCount) = 1;
- }
- else
- refCount = 0;
- }
- return *this;
- }
- int GetHashCode()
- {
- return (int)(long long)(void*)pointer;
- }
- bool operator == (const T * ptr) const
- {
- return pointer == ptr;
- }
- bool operator != (const T * ptr) const
- {
- return pointer != ptr;
- }
- template<typename U>
- bool operator == (const RefPtr<U, Destructor> & ptr) const
- {
- return pointer == ptr.pointer;
- }
- template<typename U>
- bool operator != (const RefPtr<U, Destructor> & ptr) const
- {
- return pointer != ptr.pointer;
- }
- template<typename U>
- RefPtrImpl<U, 0, Destructor> As() const
- {
- RefPtrImpl<U, 0, Destructor> result;
- if (pointer)
- {
- result.pointer = dynamic_cast<U*>(pointer);
- if (result.pointer)
- {
- result.refCount = refCount;
- (*refCount)++;
- }
- }
- return result;
- }
+ T& operator*() const
+ {
+ return *pointer;
+ }
- T* operator +(int offset) const
- {
- return pointer+offset;
- }
- T& operator [](int idx) const
- {
- return *(pointer + idx);
- }
- RefPtrImpl<T, 0, Destructor>& operator=(RefPtrImpl<T, 0, Destructor> && ptr)
- {
- if(ptr.pointer != pointer)
- {
- Unreference();
- pointer = ptr.pointer;
- refCount = ptr.refCount;
- ptr.pointer = 0;
- ptr.refCount = 0;
- }
- return *this;
- }
- T* Release()
- {
- if(pointer)
- {
- if((*refCount) > 1)
- {
- (*refCount)--;
- }
- else
- {
- delete refCount;
- }
- }
- auto rs = pointer;
- refCount = 0;
- pointer = 0;
- return rs;
- }
- ~RefPtrImpl()
- {
- Unreference();
- }
+ T* operator->() const
+ {
+ return pointer;
+ }
- void Unreference()
- {
- if(pointer)
- {
- if((*refCount) > 1)
- {
- (*refCount)--;
- }
- else
- {
- Destructor destructor;
- destructor(pointer);
- delete refCount;
- }
- }
- }
- T & operator *() const
- {
- return *pointer;
- }
- T * operator->() const
- {
- return pointer;
- }
T * Ptr() const
{
return pointer;
}
- public:
- explicit operator bool() const
- {
- if (pointer)
- return true;
- else
- return false;
- }
- };
-
-
- template<typename T, typename Destructor>
- class RefPtrImpl<T, 1, Destructor>
- {
- template<typename T1, bool b, typename Destructor1>
- friend class RefPtrImpl;
-
- private:
- T * pointer;
- public:
- RefPtrImpl()
- {
- pointer = 0;
- }
- RefPtrImpl(T * ptr)
- : pointer(0)
- {
- this->operator=(ptr);
- }
- RefPtrImpl(const RefPtrImpl<T, 1, Destructor> & ptr)
- : pointer(0)
- {
- this->operator=(ptr);
- }
- RefPtrImpl(RefPtrImpl<T, 1, Destructor> && str)
- : pointer(0)
- {
- this->operator=(static_cast<RefPtrImpl<T, 1, Destructor> &&>(str));
- }
- template <typename U>
- RefPtrImpl(const RefPtrImpl<U, 1, Destructor>& ptr,
- typename EnableIf<IsConvertible<T*, U*>::Value, void>::type * = 0)
- : pointer(0)
- {
- pointer = ptr.pointer;
- if (ptr)
- {
- ptr->_refCount++;
- }
- }
- template <typename U>
- typename EnableIf<IsConvertible<T*, U*>::value, RefPtrImpl<T, 1, Destructor>&>::type
- operator=(const RefPtrImpl<U, 1, Destructor> & ptr)
- {
- Unreference();
-
- pointer = ptr.pointer;
- if (ptr)
- {
- ptr->_refCount++;
- }
- return *this;
- }
- RefPtrImpl<T, 1, Destructor>& operator=(T * ptr)
- {
- if (ptr != pointer)
- {
- Unreference();
-
- pointer = ptr;
- if (ptr)
- {
- ptr->_refCount++;
- }
- }
- return *this;
- }
- RefPtrImpl<T, 1, Destructor>& operator=(const RefPtrImpl<T, 1, Destructor> & ptr)
- {
- // Note: It is possible that the object this pointer references owns
- // (directly or indirectly) the storage for the argument `ptr`. If
- // that is the case and the `Unreference()` call below frees this
- // object, then the argument would become invalid.
- //
- // We copy the pointer value out of the argument first, in order
- // to protected against this case.
- T* ptrPointer = ptr.pointer;
- if (ptrPointer != pointer)
- {
- if (ptrPointer)
- ptrPointer->_refCount++;
- Unreference();
- pointer = ptrPointer;
- }
- return *this;
- }
- int GetHashCode()
- {
- return (int)(long long)(void*)pointer;
- }
- bool operator == (const T * ptr) const
- {
- return pointer == ptr;
- }
- bool operator != (const T * ptr) const
- {
- return pointer != ptr;
- }
- template<typename U>
- bool operator == (const RefPtr<U, Destructor> & ptr) const
- {
- return pointer == ptr.pointer;
- }
- template<typename U>
- bool operator != (const RefPtr<U, Destructor> & ptr) const
- {
- return pointer != ptr.pointer;
- }
- template<typename U>
- RefPtrImpl<U, 1, Destructor> As() const
- {
- RefPtrImpl<U, 1, Destructor> result;
- if (pointer)
- {
- result.pointer = dynamic_cast<U*>(pointer);
- if (result.pointer)
- {
- result.pointer->_refCount++;
- }
- }
- return result;
- }
- T* operator +(int offset) const
- {
- return pointer + offset;
- }
- T& operator [](int idx) const
- {
- return *(pointer + idx);
- }
- RefPtrImpl<T, 1, Destructor>& operator=(RefPtrImpl<T, 1, Destructor> && ptr)
- {
- if (ptr.pointer != pointer)
- {
- Unreference();
- pointer = ptr.pointer;
- ptr.pointer = nullptr;
- }
- return *this;
- }
- T* Release()
- {
- if (pointer)
- {
- pointer->_refCount--;
- }
- auto rs = pointer;
- pointer = 0;
- return rs;
- }
- ~RefPtrImpl()
- {
- Unreference();
- }
+ operator T*() const
+ {
+ return pointer;
+ }
- void Unreference()
- {
- if (pointer)
- {
- if (pointer->_refCount > 1)
- {
- pointer->_refCount--;
- }
- else
- {
- Destructor destructor;
- destructor(pointer);
- }
- }
- }
- T & operator *() const
- {
- return *pointer;
- }
- T * operator->() const
- {
- return pointer;
- }
- T * Ptr() const
- {
- return pointer;
- }
- public:
- explicit operator bool() const
- {
- if (pointer)
- return true;
- else
- return false;
- }
+ private:
+ T* pointer;
+
};
}
diff --git a/source/core/stream.h b/source/core/stream.h
index 0f5991cb7..9a8ea8366 100644
--- a/source/core/stream.h
+++ b/source/core/stream.h
@@ -32,7 +32,7 @@ namespace Slang
Start, End, Current
};
- class Stream
+ class Stream : public RefObject
{
public:
virtual ~Stream() {}
diff --git a/source/core/text-io.cpp b/source/core/text-io.cpp
index 3e5013cf3..7815d7422 100644
--- a/source/core/text-io.cpp
+++ b/source/core/text-io.cpp
@@ -28,7 +28,7 @@ namespace Slang
public:
virtual void GetBytes(List<char> & result, const String & str) override
{
- int ptr = 0;
+ UInt ptr = 0;
while (ptr < str.Length())
{
int codePoint = GetUnicodePointFromUTF8([&](int)
@@ -66,7 +66,7 @@ namespace Slang
{}
virtual void GetBytes(List<char> & result, const String & str) override
{
- int ptr = 0;
+ UInt ptr = 0;
while (ptr < str.Length())
{
int codePoint = GetUnicodePointFromUTF8([&](int)
@@ -156,7 +156,7 @@ namespace Slang
#else
newLine = "\n";
#endif
- for (int i = 0; i < str.Length(); i++)
+ for (UInt i = 0; i < str.Length(); i++)
{
if (str[i] == '\r')
sb << newLine;
diff --git a/source/core/text-io.h b/source/core/text-io.h
index acdaf0b9d..9519d51f1 100644
--- a/source/core/text-io.h
+++ b/source/core/text-io.h
@@ -263,7 +263,7 @@ namespace Slang
}
void ReleaseStream()
{
- stream.Release();
+ stream = 0;
}
};
@@ -308,7 +308,7 @@ namespace Slang
}
void ReleaseStream()
{
- stream.Release();
+ stream = 0;
}
};
}