summaryrefslogtreecommitdiffstats
path: root/source/core/slang-rtti-util.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2023-03-16 15:19:20 -0400
committerGitHub <noreply@github.com>2023-03-16 15:19:20 -0400
commit4cb899f824ee5e4421f36506e4c77f682b238b09 (patch)
treec348029866666fad59531032ba76f325d67c32ab /source/core/slang-rtti-util.cpp
parent1036d1a9edec83d8840577f388af8599b5e18f5f (diff)
Preliminary SourceMap support (#2701)
* #include an absolute path didn't work - because paths were taken to always be relative. * WIP source map. * Split out handling of RttiTypeFuncs to a map type. * Make RttiTypeFuncsMap hold default impls. * Slightly more sophisticated RttiTypeFuncsMap * Source map decoding. * Fix tabs. * Fix asserts due to negative values. * Use less obscure mechanisms in SourceMap.
Diffstat (limited to 'source/core/slang-rtti-util.cpp')
-rw-r--r--source/core/slang-rtti-util.cpp554
1 files changed, 271 insertions, 283 deletions
diff --git a/source/core/slang-rtti-util.cpp b/source/core/slang-rtti-util.cpp
index b4b2ddae2..9d02ec23b 100644
--- a/source/core/slang-rtti-util.cpp
+++ b/source/core/slang-rtti-util.cpp
@@ -2,215 +2,13 @@
namespace Slang {
-/* static */SlangResult RttiUtil::setInt(int64_t value, const RttiInfo* rttiInfo, void* dst)
-{
- SLANG_ASSERT(rttiInfo->isIntegral());
-
- // We could check ranges are appropriate, but for now we just write.
- // Passing in rttiInfo allows for other more complex types to be econverted
- switch (rttiInfo->m_kind)
- {
- case RttiInfo::Kind::I32: *(int32_t*)dst = int32_t(value); break;
- case RttiInfo::Kind::U32: *(uint32_t*)dst = uint32_t(value); break;
- case RttiInfo::Kind::I64: *(int64_t*)dst = int64_t(value); break;
- case RttiInfo::Kind::U64: *(uint64_t*)dst = uint64_t(value); break;
- default: return SLANG_FAIL;
- }
- return SLANG_OK;
-}
-
-/* static */int64_t RttiUtil::getInt64(const RttiInfo* rttiInfo, const void* src)
-{
- SLANG_ASSERT(rttiInfo->isIntegral());
-
- switch (rttiInfo->m_kind)
- {
- case RttiInfo::Kind::I32: return *(const int32_t*)src;
- case RttiInfo::Kind::U32: return *(const uint32_t*)src;
- case RttiInfo::Kind::I64: return *(const int64_t*)src;
- case RttiInfo::Kind::U64: return *(const uint64_t*)src;
- default: break;
- }
-
- SLANG_ASSERT(!"Not integral!");
- return -1;
-}
-
-/* static */double RttiUtil::asDouble(const RttiInfo* rttiInfo, const void* src)
-{
- if (rttiInfo->isIntegral())
- {
- return (double)getInt64(rttiInfo, src);
- }
- else if (rttiInfo->isFloat())
- {
- switch (rttiInfo->m_kind)
- {
- case RttiInfo::Kind::F32: return *(const float*)src;
- case RttiInfo::Kind::F64: return *(const double*)src;
- default: break;
- }
- }
-
- SLANG_ASSERT(!"Cannot convert to float");
- return 0.0;
-}
-
-/* static */SlangResult RttiUtil::setFromDouble(double v, const RttiInfo* rttiInfo, void* dst)
-{
- if (rttiInfo->isIntegral())
- {
- return setInt(int64_t(v), rttiInfo, dst);
- }
- else if (rttiInfo->isFloat())
- {
- switch (rttiInfo->m_kind)
- {
- case RttiInfo::Kind::F32: *(float*)dst = float(v); return SLANG_OK;
- case RttiInfo::Kind::F64: *(double*)dst = v; return SLANG_OK;
- default: break;
- }
- }
-
- return SLANG_FAIL;
-}
-
-/* static */bool RttiUtil::asBool(const RttiInfo* rttiInfo, const void* src)
-{
- if (rttiInfo->m_kind == RttiInfo::Kind::Bool)
- {
- return *(const bool*)src;
- }
-
- if (rttiInfo->isIntegral())
- {
- return getInt64(rttiInfo, src) != 0;
- }
- else if (rttiInfo->isFloat())
- {
- return asDouble(rttiInfo, src) != 0.0;
- }
-
- SLANG_ASSERT(!"Cannot convert to bool");
- return false;
-}
-
-static int64_t _getIntDefaultValue(RttiDefaultValue value)
-{
- switch (value)
- {
- default:
- case RttiDefaultValue::Normal: return 0;
- case RttiDefaultValue::One: return 1;
- case RttiDefaultValue::MinusOne: return -1;
- }
-}
-
-static bool _isStructDefault(const StructRttiInfo* type, const void* src)
-{
- if (type->m_super)
- {
- if (!_isStructDefault(type->m_super, src))
- {
- return false;
- }
- }
-
- const Byte* base = (const Byte*)src;
-
- const Index count = type->m_fieldCount;
- for (Index i = 0; i < count; ++i)
- {
- const auto& field = type->m_fields[i];
-
- const RttiDefaultValue defaultValue = RttiDefaultValue(field.m_flags & uint8_t(RttiDefaultValue::Mask));
-
- if (!RttiUtil::isDefault(defaultValue, field.m_type, base + field.m_offset))
- {
- return false;
- }
- }
-
- return true;
-}
-
-/* static */bool RttiUtil::isDefault(RttiDefaultValue defaultValue, const RttiInfo* rttiInfo, const void* src)
-{
- if (rttiInfo->isIntegral())
- {
- const auto value = getInt64(rttiInfo, src);
- return _getIntDefaultValue(defaultValue) == value;
- }
- else if (rttiInfo->isFloat())
- {
- const auto value = asDouble(rttiInfo, src);
- return _getIntDefaultValue(defaultValue) == value;
- }
-
- switch (rttiInfo->m_kind)
- {
- case RttiInfo::Kind::Invalid: return true;
- case RttiInfo::Kind::Bool: return *(const bool*)src == (_getIntDefaultValue(defaultValue) != 0);
- case RttiInfo::Kind::String:
- {
- return ((const String*)src)->getLength() == 0;
- }
- case RttiInfo::Kind::UnownedStringSlice:
- {
- return ((const UnownedStringSlice*)src)->getLength() == 0;
- }
- case RttiInfo::Kind::Struct:
- {
- return _isStructDefault(static_cast<const StructRttiInfo*>(rttiInfo), src);
- }
- case RttiInfo::Kind::Enum:
- {
- SLANG_ASSERT(!"Not implemented yet");
- return false;
- }
- case RttiInfo::Kind::List:
- {
- const auto& v = *(const List<Byte>*)src;
- return v.getCount() == 0;
- }
- case RttiInfo::Kind::Dictionary:
- {
- const auto& v = *(const Dictionary<Byte, Byte>*)src;
- return v.Count() == 0;
- }
- case RttiInfo::Kind::Other:
- {
- const OtherRttiInfo* otherRttiInfo = static_cast<const OtherRttiInfo*>(rttiInfo);
- return otherRttiInfo->m_isDefaultFunc && otherRttiInfo->m_isDefaultFunc(rttiInfo, src);
- }
- default:
- {
- return false;
- }
- }
-}
-
-template <typename T>
-struct GetRttiTypeFuncsForBuiltIn
-{
- static void ctorArray(const RttiInfo* rttiInfo, void* dst, Index count) { SLANG_UNUSED(rttiInfo); ::memset(dst, 0, sizeof(T) * count); }
- static void dtorArray(const RttiInfo* rttiInfo, void* dst, Index count) { SLANG_UNUSED(rttiInfo); SLANG_UNUSED(dst); SLANG_UNUSED(count); }
- static void copyArray(const RttiInfo* rttiInfo, void* dst, const void* src, Index count) { SLANG_UNUSED(rttiInfo); ::memcpy(dst, src, sizeof(T) * count); }
-
- static RttiTypeFuncs getFuncs()
- {
- RttiTypeFuncs funcs;
- funcs.copyArray = &copyArray;
- funcs.dtorArray = &dtorArray;
- funcs.ctorArray = &ctorArray;
- return funcs;
- }
-};
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RttiTypeFuncs Impls !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
struct ListFuncs
{
- static void ctorArray(const RttiInfo* rttiInfo, void* inDst, Index count)
+ static void ctorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, Index count)
{
+ SLANG_UNUSED(typeMap);
SLANG_UNUSED(rttiInfo);
SLANG_ASSERT(rttiInfo->m_kind == RttiInfo::Kind::List);
@@ -225,14 +23,14 @@ struct ListFuncs
new (dst + i) Type;
}
}
- static void copyArray(const RttiInfo* rttiInfo, void* inDst, const void* inSrc, Index count)
+ static void copyArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, const void* inSrc, Index count)
{
SLANG_ASSERT(rttiInfo->m_kind == RttiInfo::Kind::List);
const ListRttiInfo* listRttiInfo = static_cast<const ListRttiInfo*>(rttiInfo);
const auto elementType = listRttiInfo->m_elementType;
// We need to get the type funcs
- auto typeFuncs = RttiUtil::getTypeFuncs(elementType);
+ auto typeFuncs = typeMap->getFuncsForType(elementType);
SLANG_ASSERT(typeFuncs.isValid());
// We need a type that we can get information from the list from - List<Byte> gives us the functions we need.
@@ -256,8 +54,8 @@ struct ListFuncs
void* newBuffer = ::malloc(count * elementType->m_size);
// Initialize it all first
- typeFuncs.ctorArray(elementType, newBuffer, count);
- typeFuncs.copyArray(elementType, newBuffer, oldBuffer, count);
+ typeFuncs.ctorArray(typeMap, elementType, newBuffer, count);
+ typeFuncs.copyArray(typeMap, elementType, newBuffer, oldBuffer, count);
// Attach the new buffer
dstList.attachBuffer((Byte*)newBuffer, count, count);
@@ -265,20 +63,20 @@ struct ListFuncs
// Free the old buffer
if (oldBuffer)
{
- typeFuncs.dtorArray(elementType, oldBuffer, dstCapacity);
+ typeFuncs.dtorArray(typeMap, elementType, oldBuffer, dstCapacity);
::free(oldBuffer);
}
}
else
{
- typeFuncs.copyArray(elementType, dstList.getBuffer(), srcList.getBuffer(), srcCount);
+ typeFuncs.copyArray(typeMap, elementType, dstList.getBuffer(), srcList.getBuffer(), srcCount);
dstList.unsafeShrinkToCount(srcCount);
}
}
}
- static void dtorArray(const RttiInfo* rttiInfo, void* inDst, Index count)
+ static void dtorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, Index count)
{
SLANG_ASSERT(rttiInfo->m_kind == RttiInfo::Kind::List);
const ListRttiInfo* listRttiInfo = static_cast<const ListRttiInfo*>(rttiInfo);
@@ -286,7 +84,7 @@ struct ListFuncs
const auto elementType = listRttiInfo->m_elementType;
// We need to get the type funcs
- auto typeFuncs = RttiUtil::getTypeFuncs(elementType);
+ auto typeFuncs = typeMap->getFuncsForType(elementType);
SLANG_ASSERT(typeFuncs.isValid());
typedef List<Byte> Type;
@@ -301,7 +99,7 @@ struct ListFuncs
if (buffer)
{
- typeFuncs.dtorArray(elementType, buffer, capacity);
+ typeFuncs.dtorArray(typeMap, elementType, buffer, capacity);
::free(buffer);
}
}
@@ -319,10 +117,9 @@ struct ListFuncs
struct StructFuncs
{
-
-
- static void ctorArray(const RttiInfo* rttiInfo, void* inDst, Index count)
+ static void ctorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, Index count)
{
+ SLANG_UNUSED(typeMap);
SLANG_UNUSED(rttiInfo);
SLANG_ASSERT(rttiInfo->m_kind == RttiInfo::Kind::List);
@@ -337,14 +134,14 @@ struct StructFuncs
new (dst + i) Type;
}
}
- static void copyArray(const RttiInfo* rttiInfo, void* inDst, const void* inSrc, Index count)
+ static void copyArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, const void* inSrc, Index count)
{
SLANG_ASSERT(rttiInfo->m_kind == RttiInfo::Kind::List);
const ListRttiInfo* listRttiInfo = static_cast<const ListRttiInfo*>(rttiInfo);
const auto elementType = listRttiInfo->m_elementType;
// We need to get the type funcs
- auto typeFuncs = RttiUtil::getTypeFuncs(elementType);
+ auto typeFuncs = typeMap->getFuncsForType(elementType);
SLANG_ASSERT(typeFuncs.isValid());
// We need a type that we can get information from the list from - List<Byte> gives us the functions we need.
@@ -368,8 +165,8 @@ struct StructFuncs
void* newBuffer = ::malloc(count * elementType->m_size);
// Initialize it all first
- typeFuncs.ctorArray(elementType, newBuffer, count);
- typeFuncs.copyArray(elementType, newBuffer, oldBuffer, count);
+ typeFuncs.ctorArray(typeMap, elementType, newBuffer, count);
+ typeFuncs.copyArray(typeMap, elementType, newBuffer, oldBuffer, count);
// Attach the new buffer
dstList.attachBuffer((Byte*)newBuffer, count, count);
@@ -377,20 +174,20 @@ struct StructFuncs
// Free the old buffer
if (oldBuffer)
{
- typeFuncs.dtorArray(elementType, oldBuffer, dstCapacity);
+ typeFuncs.dtorArray(typeMap, elementType, oldBuffer, dstCapacity);
::free(oldBuffer);
}
}
else
{
- typeFuncs.copyArray(elementType, dstList.getBuffer(), srcList.getBuffer(), srcCount);
+ typeFuncs.copyArray(typeMap, elementType, dstList.getBuffer(), srcList.getBuffer(), srcCount);
dstList.unsafeShrinkToCount(srcCount);
}
}
}
- static void dtorArray(const RttiInfo* rttiInfo, void* inDst, Index count)
+ static void dtorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, Index count)
{
SLANG_ASSERT(rttiInfo->m_kind == RttiInfo::Kind::List);
const ListRttiInfo* listRttiInfo = static_cast<const ListRttiInfo*>(rttiInfo);
@@ -398,7 +195,7 @@ struct StructFuncs
const auto elementType = listRttiInfo->m_elementType;
// We need to get the type funcs
- auto typeFuncs = RttiUtil::getTypeFuncs(elementType);
+ auto typeFuncs = typeMap->getFuncsForType(elementType);
SLANG_ASSERT(typeFuncs.isValid());
typedef List<Byte> Type;
@@ -413,7 +210,7 @@ struct StructFuncs
if (buffer)
{
- typeFuncs.dtorArray(elementType, buffer, capacity);
+ typeFuncs.dtorArray(typeMap, elementType, buffer, capacity);
::free(buffer);
}
}
@@ -429,40 +226,45 @@ struct StructFuncs
}
};
-static void _ctorStructArray(const RttiInfo* rttiInfo, void* inDst, Index count)
+struct StructArrayFuncs
{
- RttiUtil::ctorArray(rttiInfo, inDst, rttiInfo->m_size, count);
-}
+ static void ctorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, Index count)
+ {
+ return RttiUtil::ctorArray(typeMap, rttiInfo, inDst, rttiInfo->m_size, count);
+ }
-static void _copyStructArray(const RttiInfo* rttiInfo, void* inDst, const void* inSrc, Index count)
-{
- RttiUtil::copyArray(rttiInfo, inDst, inSrc, rttiInfo->m_size, count);
-}
+ static void copyArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, const void* inSrc, Index count)
+ {
+ return RttiUtil::copyArray(typeMap, rttiInfo, inDst, inSrc, rttiInfo->m_size, count);
+ }
-static void _dtorStructArray(const RttiInfo* rttiInfo, void* inDst, Index count)
-{
- RttiUtil::dtorArray(rttiInfo, inDst, rttiInfo->m_size, count);
-}
+ static void dtorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, Index count)
+ {
+ return RttiUtil::dtorArray(typeMap, rttiInfo, inDst, rttiInfo->m_size, count);
+ }
-static RttiTypeFuncs _getStructTypeFuncs()
-{
- RttiTypeFuncs funcs;
- funcs.copyArray = _copyStructArray;
- funcs.dtorArray = _dtorStructArray;
- funcs.ctorArray = _ctorStructArray;
- return funcs;
-}
+ static RttiTypeFuncs getFuncs()
+ {
+ RttiTypeFuncs funcs;
+ funcs.copyArray = copyArray;
+ funcs.dtorArray = dtorArray;
+ funcs.ctorArray = ctorArray;
+ return funcs;
+ }
+};
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RttiUtil !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
+RttiTypeFuncs RttiUtil::getDefaultTypeFuncs(const RttiInfo* rttiInfo)
{
if (rttiInfo->isBuiltIn())
{
switch (rttiInfo->m_size)
{
- case 1: return GetRttiTypeFuncsForBuiltIn<uint8_t>::getFuncs();
- case 2: return GetRttiTypeFuncsForBuiltIn<uint16_t>::getFuncs();
- case 4: return GetRttiTypeFuncsForBuiltIn<uint32_t>::getFuncs();
- case 8: return GetRttiTypeFuncsForBuiltIn<uint64_t>::getFuncs();
+ case 1: return GetRttiTypeFuncsForZeroPod<uint8_t>::getFuncs();
+ case 2: return GetRttiTypeFuncsForZeroPod<uint16_t>::getFuncs();
+ case 4: return GetRttiTypeFuncsForZeroPod<uint32_t>::getFuncs();
+ case 8: return GetRttiTypeFuncsForZeroPod<uint64_t>::getFuncs();
}
return RttiTypeFuncs::makeEmpty();
}
@@ -472,14 +274,202 @@ RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
case RttiInfo::Kind::String: return GetRttiTypeFuncs<String>::getFuncs();
case RttiInfo::Kind::UnownedStringSlice: return GetRttiTypeFuncs<UnownedStringSlice>::getFuncs();
case RttiInfo::Kind::List: return ListFuncs::getFuncs();
- case RttiInfo::Kind::Struct: return _getStructTypeFuncs();
+ case RttiInfo::Kind::Struct: return StructArrayFuncs::getFuncs();
default: break;
}
return RttiTypeFuncs::makeEmpty();
}
-/* static */SlangResult RttiUtil::setListCount(const RttiInfo* elementType, void* dst, Index count)
+/* static */SlangResult RttiUtil::setInt(int64_t value, const RttiInfo* rttiInfo, void* dst)
+{
+ SLANG_ASSERT(rttiInfo->isIntegral());
+
+ // We could check ranges are appropriate, but for now we just write.
+ // Passing in rttiInfo allows for other more complex types to be econverted
+ switch (rttiInfo->m_kind)
+ {
+ case RttiInfo::Kind::I32: *(int32_t*)dst = int32_t(value); break;
+ case RttiInfo::Kind::U32: *(uint32_t*)dst = uint32_t(value); break;
+ case RttiInfo::Kind::I64: *(int64_t*)dst = int64_t(value); break;
+ case RttiInfo::Kind::U64: *(uint64_t*)dst = uint64_t(value); break;
+ default: return SLANG_FAIL;
+ }
+ return SLANG_OK;
+}
+
+/* static */int64_t RttiUtil::getInt64(const RttiInfo* rttiInfo, const void* src)
+{
+ SLANG_ASSERT(rttiInfo->isIntegral());
+
+ switch (rttiInfo->m_kind)
+ {
+ case RttiInfo::Kind::I32: return *(const int32_t*)src;
+ case RttiInfo::Kind::U32: return *(const uint32_t*)src;
+ case RttiInfo::Kind::I64: return *(const int64_t*)src;
+ case RttiInfo::Kind::U64: return *(const uint64_t*)src;
+ default: break;
+ }
+
+ SLANG_ASSERT(!"Not integral!");
+ return -1;
+}
+
+/* static */double RttiUtil::asDouble(const RttiInfo* rttiInfo, const void* src)
+{
+ if (rttiInfo->isIntegral())
+ {
+ return (double)getInt64(rttiInfo, src);
+ }
+ else if (rttiInfo->isFloat())
+ {
+ switch (rttiInfo->m_kind)
+ {
+ case RttiInfo::Kind::F32: return *(const float*)src;
+ case RttiInfo::Kind::F64: return *(const double*)src;
+ default: break;
+ }
+ }
+
+ SLANG_ASSERT(!"Cannot convert to float");
+ return 0.0;
+}
+
+/* static */SlangResult RttiUtil::setFromDouble(double v, const RttiInfo* rttiInfo, void* dst)
+{
+ if (rttiInfo->isIntegral())
+ {
+ return setInt(int64_t(v), rttiInfo, dst);
+ }
+ else if (rttiInfo->isFloat())
+ {
+ switch (rttiInfo->m_kind)
+ {
+ case RttiInfo::Kind::F32: *(float*)dst = float(v); return SLANG_OK;
+ case RttiInfo::Kind::F64: *(double*)dst = v; return SLANG_OK;
+ default: break;
+ }
+ }
+
+ return SLANG_FAIL;
+}
+
+/* static */bool RttiUtil::asBool(const RttiInfo* rttiInfo, const void* src)
+{
+ if (rttiInfo->m_kind == RttiInfo::Kind::Bool)
+ {
+ return *(const bool*)src;
+ }
+
+ if (rttiInfo->isIntegral())
+ {
+ return getInt64(rttiInfo, src) != 0;
+ }
+ else if (rttiInfo->isFloat())
+ {
+ return asDouble(rttiInfo, src) != 0.0;
+ }
+
+ SLANG_ASSERT(!"Cannot convert to bool");
+ return false;
+}
+
+static int64_t _getIntDefaultValue(RttiDefaultValue value)
+{
+ switch (value)
+ {
+ default:
+ case RttiDefaultValue::Normal: return 0;
+ case RttiDefaultValue::One: return 1;
+ case RttiDefaultValue::MinusOne: return -1;
+ }
+}
+
+static bool _isStructDefault(const StructRttiInfo* type, const void* src)
+{
+ if (type->m_super)
+ {
+ if (!_isStructDefault(type->m_super, src))
+ {
+ return false;
+ }
+ }
+
+ const Byte* base = (const Byte*)src;
+
+ const Index count = type->m_fieldCount;
+ for (Index i = 0; i < count; ++i)
+ {
+ const auto& field = type->m_fields[i];
+
+ const RttiDefaultValue defaultValue = RttiDefaultValue(field.m_flags & uint8_t(RttiDefaultValue::Mask));
+
+ if (!RttiUtil::isDefault(defaultValue, field.m_type, base + field.m_offset))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* static */bool RttiUtil::isDefault(RttiDefaultValue defaultValue, const RttiInfo* rttiInfo, const void* src)
+{
+ if (rttiInfo->isIntegral())
+ {
+ const auto value = getInt64(rttiInfo, src);
+ return _getIntDefaultValue(defaultValue) == value;
+ }
+ else if (rttiInfo->isFloat())
+ {
+ const auto value = asDouble(rttiInfo, src);
+ return _getIntDefaultValue(defaultValue) == value;
+ }
+
+ switch (rttiInfo->m_kind)
+ {
+ case RttiInfo::Kind::Invalid: return true;
+ case RttiInfo::Kind::Bool: return *(const bool*)src == (_getIntDefaultValue(defaultValue) != 0);
+ case RttiInfo::Kind::String:
+ {
+ return ((const String*)src)->getLength() == 0;
+ }
+ case RttiInfo::Kind::UnownedStringSlice:
+ {
+ return ((const UnownedStringSlice*)src)->getLength() == 0;
+ }
+ case RttiInfo::Kind::Struct:
+ {
+ return _isStructDefault(static_cast<const StructRttiInfo*>(rttiInfo), src);
+ }
+ case RttiInfo::Kind::Enum:
+ {
+ SLANG_ASSERT(!"Not implemented yet");
+ return false;
+ }
+ case RttiInfo::Kind::List:
+ {
+ const auto& v = *(const List<Byte>*)src;
+ return v.getCount() == 0;
+ }
+ case RttiInfo::Kind::Dictionary:
+ {
+ const auto& v = *(const Dictionary<Byte, Byte>*)src;
+ return v.Count() == 0;
+ }
+ case RttiInfo::Kind::Other:
+ {
+ const OtherRttiInfo* otherRttiInfo = static_cast<const OtherRttiInfo*>(rttiInfo);
+ return otherRttiInfo->m_isDefaultFunc && otherRttiInfo->m_isDefaultFunc(rttiInfo, src);
+ }
+ default:
+ {
+ return false;
+ }
+ }
+}
+
+/* static */SlangResult RttiUtil::setListCount(RttiTypeFuncsMap* typeMap, const RttiInfo* elementType, void* dst, Index count)
{
// NOTE! The following only works because List<T> has capacity initialized members, and
// setting the count if it is <= capacity just sets the count (ie things aren't released(!)).
@@ -496,22 +486,17 @@ RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
return SLANG_OK;
}
- // Get funcs needed
- const auto typeFuncs = RttiUtil::getTypeFuncs(elementType);
-
- if (!typeFuncs.isValid())
- {
- return SLANG_FAIL;
- }
+ const auto typeFuncs = typeMap->getFuncsForType(elementType);
+ SLANG_ASSERT(typeFuncs.isValid());
const Index dstCapacity = dstList.getCapacity();
void* oldBuffer = dstList.detachBuffer();
void* newBuffer = ::malloc(count * elementType->m_size);
// Initialize it all first
- typeFuncs.ctorArray(elementType, newBuffer, count);
+ typeFuncs.ctorArray(typeMap, elementType, newBuffer, count);
- typeFuncs.copyArray(elementType, newBuffer, oldBuffer, oldCount);
+ typeFuncs.copyArray(typeMap, elementType, newBuffer, oldBuffer, oldCount);
// Attach the new buffer
dstList.attachBuffer((Byte*)newBuffer, count, count);
@@ -519,7 +504,7 @@ RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
// Free the old buffer
if (oldBuffer)
{
- typeFuncs.dtorArray(elementType, oldBuffer, dstCapacity);
+ typeFuncs.dtorArray(typeMap, elementType, oldBuffer, dstCapacity);
::free(oldBuffer);
}
@@ -707,7 +692,7 @@ RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
}
}
-/* static */void RttiUtil::ctorArray(const RttiInfo* rttiInfo, void* inDst, ptrdiff_t stride, Index count)
+/* static */void RttiUtil::ctorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, ptrdiff_t stride, Index count)
{
if (count <= 0)
{
@@ -741,14 +726,14 @@ RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
if (fixedArrayRttiInfo->m_size == stride)
{
// It's contiguous do in one go
- ctorArray(fixedArrayRttiInfo->m_elementType, dst, fixedArrayRttiInfo->m_elementType->m_size, fixedArrayRttiInfo->m_elementCount * count);
+ ctorArray(typeMap, fixedArrayRttiInfo->m_elementType, dst, fixedArrayRttiInfo->m_elementType->m_size, fixedArrayRttiInfo->m_elementCount * count);
}
else
{
// Do it in array runs
for (Index i = 0; i < count; ++i, dst += stride)
{
- ctorArray(fixedArrayRttiInfo->m_elementType, dst, fixedArrayRttiInfo->m_elementType->m_size, fixedArrayRttiInfo->m_elementCount);
+ ctorArray(typeMap, fixedArrayRttiInfo->m_elementType, dst, fixedArrayRttiInfo->m_elementType->m_size, fixedArrayRttiInfo->m_elementCount);
}
}
return;
@@ -757,19 +742,20 @@ RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
case RttiInfo::Kind::Dictionary:
case RttiInfo::Kind::Other:
{
- auto funcs = getTypeFuncs(rttiInfo);
+ auto funcs = typeMap->getFuncsForType(rttiInfo);
+ SLANG_ASSERT(funcs.isValid());
const OtherRttiInfo* otherRttiInfo = static_cast<const OtherRttiInfo*>(rttiInfo);
if (otherRttiInfo->m_size == stride)
{
- funcs.ctorArray(rttiInfo, dst, count);
+ funcs.ctorArray(typeMap, rttiInfo, dst, count);
}
else
{
// Do it in array runs
for (Index i = 0; i < count; ++i, dst += stride)
{
- funcs.ctorArray(rttiInfo, dst, 1);
+ funcs.ctorArray(typeMap, rttiInfo, dst, 1);
}
}
return;
@@ -787,7 +773,7 @@ RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
for (Index i = 0; i < fieldCount; ++i)
{
const auto& field = fields[i];
- ctorArray(field.m_type, dst + field.m_offset, stride, count);
+ ctorArray(typeMap, field.m_type, dst + field.m_offset, stride, count);
}
structRttiInfo = structRttiInfo->m_super;
}
@@ -800,7 +786,7 @@ RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
SLANG_ASSERT(!"Unexpected");
}
-/* static */void RttiUtil::copyArray(const RttiInfo* rttiInfo, void* inDst, const void* inSrc, ptrdiff_t stride, Index count)
+/* static */void RttiUtil::copyArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, const void* inSrc, ptrdiff_t stride, Index count)
{
if (count <= 0)
{
@@ -840,14 +826,14 @@ RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
if (ptrdiff_t(size) == stride)
{
// It's contiguous do in one go
- copyArray(elementType, dst, src, elementSize, elementCount * count);
+ copyArray(typeMap, elementType, dst, src, elementSize, elementCount * count);
}
else
{
// Do it in array runs
for (Index i = 0; i < count; ++i, dst += stride, src += stride)
{
- copyArray(elementType, dst, src, elementSize, elementCount);
+ copyArray(typeMap, elementType, dst, src, elementSize, elementCount);
}
}
return;
@@ -856,18 +842,19 @@ RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
case RttiInfo::Kind::Dictionary:
case RttiInfo::Kind::Other:
{
- auto funcs = getTypeFuncs(rttiInfo);
+ auto funcs = typeMap->getFuncsForType(rttiInfo);
+ SLANG_ASSERT(funcs.isValid());
const OtherRttiInfo* otherRttiInfo = static_cast<const OtherRttiInfo*>(rttiInfo);
if (otherRttiInfo->m_size == stride)
{
- funcs.copyArray(rttiInfo, dst, src, count);
+ funcs.copyArray(typeMap, rttiInfo, dst, src, count);
}
else
{
for (Index i = 0; i < count; ++i, dst += stride, src += stride)
{
- funcs.copyArray(rttiInfo, dst, src, 1);
+ funcs.copyArray(typeMap, rttiInfo, dst, src, 1);
}
}
return;
@@ -885,7 +872,7 @@ RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
for (Index i = 0; i < fieldCount; ++i)
{
const auto& field = fields[i];
- copyArray(field.m_type, dst + field.m_offset, src + field.m_offset, stride, count);
+ copyArray(typeMap, field.m_type, dst + field.m_offset, src + field.m_offset, stride, count);
}
structRttiInfo = structRttiInfo->m_super;
}
@@ -898,7 +885,7 @@ RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
SLANG_ASSERT(!"Unexpected");
}
-/* static */void RttiUtil::dtorArray(const RttiInfo* rttiInfo, void* inDst, ptrdiff_t stride, Index count)
+/* static */void RttiUtil::dtorArray(RttiTypeFuncsMap* typeMap, const RttiInfo* rttiInfo, void* inDst, ptrdiff_t stride, Index count)
{
if (count <= 0 || !hasDtor(rttiInfo))
{
@@ -920,14 +907,14 @@ RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
if (ptrdiff_t(size) == stride)
{
// It's contiguous do in one go
- dtorArray(elementType, dst, elementSize, elementCount * count);
+ dtorArray(typeMap, elementType, dst, elementSize, elementCount * count);
}
else
{
// Do it in array runs
for (Index i = 0; i < count; ++i, dst += stride)
{
- dtorArray(elementType, dst, elementSize, elementCount);
+ dtorArray(typeMap, elementType, dst, elementSize, elementCount);
}
}
return;
@@ -936,18 +923,19 @@ RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
case RttiInfo::Kind::Dictionary:
case RttiInfo::Kind::Other:
{
- auto funcs = getTypeFuncs(rttiInfo);
+ auto funcs = typeMap->getFuncsForType(rttiInfo);
+ SLANG_ASSERT(funcs.isValid());
const OtherRttiInfo* otherRttiInfo = static_cast<const OtherRttiInfo*>(rttiInfo);
if (otherRttiInfo->m_size == stride)
{
- funcs.dtorArray(rttiInfo, dst, count);
+ funcs.dtorArray(typeMap, rttiInfo, dst, count);
}
else
{
for (Index i = 0; i < count; ++i, dst += stride)
{
- funcs.dtorArray(rttiInfo, dst, 1);
+ funcs.dtorArray(typeMap, rttiInfo, dst, 1);
}
}
return;
@@ -965,7 +953,7 @@ RttiTypeFuncs RttiUtil::getTypeFuncs(const RttiInfo* rttiInfo)
for (Index i = 0; i < fieldCount; ++i)
{
const auto& field = fields[i];
- dtorArray(field.m_type, dst + field.m_offset, stride, count);
+ dtorArray(typeMap, field.m_type, dst + field.m_offset, stride, count);
}
structRttiInfo = structRttiInfo->m_super;
}