src/util: minor xspan improvements
This commit is contained in:
+62
-20
@@ -32,12 +32,17 @@ SPAN_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
unsigned long long span_check_stats_check_range = 0;
|
unsigned long long span_check_stats_check_range = 0;
|
||||||
|
|
||||||
|
// HINT: set env-var "UPX_DEBUG_DOCTEST_DISABLE=1" for improved debugging experience
|
||||||
__acc_noinline void span_fail_nullptr() {
|
__acc_noinline void span_fail_nullptr() {
|
||||||
throwCantUnpack("span unexpected NULL pointer; take care!");
|
throwCantUnpack("span unexpected NULL pointer; take care!");
|
||||||
}
|
}
|
||||||
|
__acc_noinline void span_fail_nullbase() {
|
||||||
|
throwCantUnpack("span unexpected NULL base; take care!");
|
||||||
|
}
|
||||||
__acc_noinline void span_fail_not_same_base() {
|
__acc_noinline void span_fail_not_same_base() {
|
||||||
throwInternalError("span unexpected base pointer; take care!");
|
throwInternalError("span unexpected base pointer; take care!");
|
||||||
}
|
}
|
||||||
|
|
||||||
__acc_noinline void span_fail_range_nullptr() {
|
__acc_noinline void span_fail_range_nullptr() {
|
||||||
throwCantUnpack("span_check_range: unexpected NULL pointer; take care!");
|
throwCantUnpack("span_check_range: unexpected NULL pointer; take care!");
|
||||||
}
|
}
|
||||||
@@ -474,26 +479,63 @@ TEST_CASE("Span") {
|
|||||||
assert(ss_with_base.raw_base() == base_buf);
|
assert(ss_with_base.raw_base() == base_buf);
|
||||||
CHECK_THROWS(ss_with_base = my_null); // nullptr assignment
|
CHECK_THROWS(ss_with_base = my_null); // nullptr assignment
|
||||||
#if SPAN_CONFIG_ENABLE_SPAN_CONVERSION
|
#if SPAN_CONFIG_ENABLE_SPAN_CONVERSION
|
||||||
typedef PtrOrSpanOrNull<char> Span0;
|
{
|
||||||
Span0 s0_no_base(nullptr);
|
typedef PtrOrSpanOrNull<char> Span0;
|
||||||
Span0 s0_with_base(nullptr, 4, base_buf);
|
// v0 nullptr, b0 base, b1 base + 1
|
||||||
CHECK_THROWS(ss_with_base = s0_no_base); // nullptr assignment
|
const Span0 v0_v0(nullptr);
|
||||||
CHECK_THROWS(ss_with_base = s0_with_base); // nullptr assignment
|
const Span0 v0_b0(nullptr, 4, base_buf);
|
||||||
typedef PtrOrSpanOrNull<char> SpanP;
|
const Span0 v0_b1(nullptr, 3, base_buf + 1);
|
||||||
SpanP sp_1(base_buf + 1, 3, base_buf);
|
const Span0 b0_v0(base_buf);
|
||||||
SpanP sp_2(base_buf + 2, 2, base_buf);
|
const Span0 b0_b0(base_buf, 4, base_buf);
|
||||||
// SpanP sp_4(base_buf + 4, 0, base_buf);
|
CHECK_THROWS(SPAN_0_MAKE(char, base_buf, 3, base_buf + 1)); // b0_b1
|
||||||
SpanP sp_x(base_buf + 1, 3, base_buf + 1);
|
const Span0 b1_v0(base_buf + 1);
|
||||||
assert(ss_with_base.raw_base() == base_buf);
|
const Span0 b1_b0(base_buf + 1, 4, base_buf);
|
||||||
#if 0
|
const Span0 b1_b1(base_buf + 1, 3, base_buf + 1);
|
||||||
ss_with_base = sp_1;
|
CHECK_THROWS(ss_with_base = v0_v0); // nullptr assignment
|
||||||
assert(ss_with_base.raw_ptr() == base_buf + 1);
|
CHECK_THROWS(ss_with_base = v0_b0); // nullptr assignment
|
||||||
CHECK(*ss_with_base == 1);
|
CHECK_THROWS(ss_with_base = v0_b1); // nullptr assignment
|
||||||
ss_with_base = sp_2;
|
CHECK_NOTHROW(ss_with_base = b0_v0);
|
||||||
assert(ss_with_base.raw_ptr() == base_buf + 2);
|
CHECK_NOTHROW(ss_with_base = b0_b0);
|
||||||
CHECK_THROWS(ss_with_base = sp_x); // not same base
|
CHECK_NOTHROW(ss_with_base = b1_v0);
|
||||||
assert(ss_with_base.raw_base() == base_buf);
|
CHECK_NOTHROW(ss_with_base = b1_b0);
|
||||||
#endif
|
CHECK_THROWS(ss_with_base = b1_b1); // different base
|
||||||
|
CHECK_THROWS(SPAN_S_MAKE(char, v0_v0));
|
||||||
|
CHECK_THROWS(SPAN_S_MAKE(char, v0_b0));
|
||||||
|
CHECK_THROWS(SPAN_S_MAKE(char, v0_b1));
|
||||||
|
CHECK_THROWS(SPAN_S_MAKE(char, b0_v0));
|
||||||
|
CHECK_NOTHROW(SPAN_S_MAKE(char, b0_b0));
|
||||||
|
CHECK_THROWS(SPAN_S_MAKE(char, b1_v0));
|
||||||
|
CHECK_NOTHROW(SPAN_S_MAKE(char, b1_b0));
|
||||||
|
CHECK_NOTHROW(SPAN_S_MAKE(char, b1_b1));
|
||||||
|
//
|
||||||
|
CHECK((SPAN_S_MAKE(char, b0_b0).raw_base() == base_buf));
|
||||||
|
CHECK((SPAN_S_MAKE(char, b1_b0).raw_base() == base_buf));
|
||||||
|
CHECK((SPAN_S_MAKE(char, b1_b1).raw_base() == base_buf + 1));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
typedef PtrOrSpan<char> SpanP;
|
||||||
|
// v0 nullptr, b0 base, b1 base + 1
|
||||||
|
const SpanP b0_v0(base_buf);
|
||||||
|
const SpanP b0_b0(base_buf, 4, base_buf);
|
||||||
|
CHECK_THROWS(SPAN_P_MAKE(char, base_buf, 3, base_buf + 1)); // b0_b1
|
||||||
|
const SpanP b1_v0(base_buf + 1);
|
||||||
|
const SpanP b1_b0(base_buf + 1, 4, base_buf);
|
||||||
|
const SpanP b1_b1(base_buf + 1, 3, base_buf + 1);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b0_v0);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b0_b0);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b1_v0);
|
||||||
|
CHECK_NOTHROW(ss_with_base = b1_b0);
|
||||||
|
CHECK_THROWS(ss_with_base = b1_b1); // different base
|
||||||
|
CHECK_THROWS(SPAN_S_MAKE(char, b0_v0));
|
||||||
|
CHECK_NOTHROW(SPAN_S_MAKE(char, b0_b0));
|
||||||
|
CHECK_THROWS(SPAN_S_MAKE(char, b1_v0));
|
||||||
|
CHECK_NOTHROW(SPAN_S_MAKE(char, b1_b0));
|
||||||
|
CHECK_NOTHROW(SPAN_S_MAKE(char, b1_b1));
|
||||||
|
//
|
||||||
|
CHECK((SPAN_S_MAKE(char, b0_b0).raw_base() == base_buf));
|
||||||
|
CHECK((SPAN_S_MAKE(char, b1_b0).raw_base() == base_buf));
|
||||||
|
CHECK((SPAN_S_MAKE(char, b1_b1).raw_base() == base_buf + 1));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,9 @@
|
|||||||
|
|
||||||
SPAN_NAMESPACE_BEGIN
|
SPAN_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
// HINT: set env-var "UPX_DEBUG_DOCTEST_DISABLE=1" for improved debugging experience
|
||||||
__acc_noinline void span_fail_nullptr();
|
__acc_noinline void span_fail_nullptr();
|
||||||
|
__acc_noinline void span_fail_nullbase();
|
||||||
__acc_noinline void span_fail_not_same_base();
|
__acc_noinline void span_fail_not_same_base();
|
||||||
__acc_noinline void span_fail_range_nullptr();
|
__acc_noinline void span_fail_range_nullptr();
|
||||||
__acc_noinline void span_fail_range_nullbase();
|
__acc_noinline void span_fail_range_nullbase();
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ static __acc_forceinline pointer makePtr(pointer p) {
|
|||||||
}
|
}
|
||||||
static __acc_forceinline pointer makeBase(pointer b) {
|
static __acc_forceinline pointer makeBase(pointer b) {
|
||||||
if __acc_cte (configRequireBase && b == nullptr)
|
if __acc_cte (configRequireBase && b == nullptr)
|
||||||
span_fail_nullptr();
|
span_fail_nullbase();
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
// inverse logic for ensuring valid pointers from existing objets
|
// inverse logic for ensuring valid pointers from existing objets
|
||||||
@@ -89,8 +89,8 @@ __acc_forceinline pointer ensurePtr() const {
|
|||||||
}
|
}
|
||||||
__acc_forceinline pointer ensureBase() const {
|
__acc_forceinline pointer ensureBase() const {
|
||||||
if __acc_cte (!configRequireBase && base == nullptr)
|
if __acc_cte (!configRequireBase && base == nullptr)
|
||||||
span_fail_nullptr();
|
span_fail_nullbase();
|
||||||
return ptr;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -161,13 +161,12 @@ CSelf(std::nullptr_t, size_type, std::nullptr_t) SPAN_DELETED_FUNCTION;
|
|||||||
CSelf(const void *, size_type, std::nullptr_t) SPAN_DELETED_FUNCTION;
|
CSelf(const void *, size_type, std::nullptr_t) SPAN_DELETED_FUNCTION;
|
||||||
|
|
||||||
// unchecked constructor
|
// unchecked constructor
|
||||||
private:
|
protected:
|
||||||
enum ModeUnchecked { Unchecked };
|
enum ModeUnchecked { Unchecked };
|
||||||
CSelf(ModeUnchecked, pointer p, size_type bytes, pointer b)
|
CSelf(ModeUnchecked, pointer p, size_type bytes, pointer b)
|
||||||
: ptr(p), base(b), size_in_bytes(bytes) {
|
: ptr(p), base(b), size_in_bytes(bytes) {
|
||||||
assertInvariants();
|
assertInvariants();
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
// unchecked assignment
|
// unchecked assignment
|
||||||
Self &assign(ModeUnchecked, pointer p, size_type bytes, pointer b) {
|
Self &assign(ModeUnchecked, pointer p, size_type bytes, pointer b) {
|
||||||
ptr = p;
|
ptr = p;
|
||||||
@@ -176,6 +175,7 @@ Self &assign(ModeUnchecked, pointer p, size_type bytes, pointer b) {
|
|||||||
assertInvariants();
|
assertInvariants();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
Self &assign(ModeUnchecked, const Self &other) {
|
Self &assign(ModeUnchecked, const Self &other) {
|
||||||
ptr = other.ptr;
|
ptr = other.ptr;
|
||||||
base = other.base;
|
base = other.base;
|
||||||
|
|||||||
Reference in New Issue
Block a user