From 3cfc396ecd49c1f52ca7804b8d05b4a511045ece Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Sun, 8 Jan 2017 13:12:58 -0600 Subject: COMMON: Simplify Span code Implicitly generated constructors can be used instead of explicit constructors, which reduces the amount of necessary boilerplate. Long lists of identical typedefs to the superclass are now defined using a macro. data() const now returns a pointer to data that matches the value_type of the data, instead of forcing the data to be const. This better matches the intent of the Span class, which provides a view into data, rather than being a container that holds data. --- test/common/span.h | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 2 deletions(-) (limited to 'test/common/span.h') diff --git a/test/common/span.h b/test/common/span.h index f8ab5d0f80..d73a2e2266 100644 --- a/test/common/span.h +++ b/test/common/span.h @@ -10,7 +10,75 @@ class SpanTestSuite : public CxxTest::TestSuite { int a; }; + template class Derived> + class SiblingSpanImpl : public Common::SpanImpl { + typedef Common::SpanImpl super_type; + public: + COMMON_SPAN_TYPEDEFS + SiblingSpanImpl() : super_type() {} + SiblingSpanImpl(pointer data_, size_type size_) : super_type(data_, size_) {} + }; + + template + class SiblingSpan : public SiblingSpanImpl { + typedef SiblingSpanImpl super_type; + public: + COMMON_SPAN_TYPEDEFS + SiblingSpan() : super_type() {} + SiblingSpan(pointer data_, size_type size_) : super_type(data_, size_) {} + }; + + template class Derived> + class SubSpanImpl : public Common::NamedSpanImpl { + typedef Common::NamedSpanImpl super_type; + public: + COMMON_SPAN_TYPEDEFS + SubSpanImpl() : super_type() {} + SubSpanImpl(pointer data_, + size_type size_, + const Common::String &name_ = Common::String(), + const size_type sourceByteOffset_ = 0) : + super_type(data_, size_, name_, sourceByteOffset_) {} + + template + SubSpanImpl(const Other &other) : super_type(other) {} + }; + + template + class SubSpan : public SubSpanImpl { + typedef SubSpanImpl super_type; + public: + COMMON_SPAN_TYPEDEFS + SubSpan() : super_type() {} + SubSpan(pointer data_, + size_type size_, + const Common::String &name_ = Common::String(), + const size_type sourceByteOffset_ = 0) : + super_type(data_, size_, name_, sourceByteOffset_) {} + + template + SubSpan(const Other &other) : super_type(other) {} + }; + public: + void test_sibling_span() { + byte data[] = { 'h', 'e', 'l', 'l', 'o' }; + SiblingSpan ss(data, sizeof(data)); + Common::Span superInstance = ss; + TS_ASSERT_EQUALS(ss.data(), data); + TS_ASSERT_EQUALS(superInstance.data(), data); + } + + void test_sub_span() { + byte data[] = { 'h', 'e', 'l', 'l', 'o' }; + SubSpan ss(data, sizeof(data), "custom subspan"); + Common::NamedSpan namedSuper = ss; + Common::Span unnamedSuper = ss; + TS_ASSERT(ss.name() == "custom subspan"); + TS_ASSERT(namedSuper.name() == ss.name()); + TS_ASSERT(unnamedSuper.name() == Common::String::format("%p", (void *)data)); + } + void test_span_iterator_const() { byte data[] = { 'h', 'e', 'l', 'l', 'o' }; const Common::Span span(data, sizeof(data)); @@ -210,6 +278,11 @@ public: // tests destruction of held pointer by reassignment owner2 = owner; + + // tests nullipotence of assignment to self + dataPtr = owner2->data(); + owner2 = owner2; + TS_ASSERT(owner2->data() == dataPtr); } { @@ -561,8 +634,9 @@ public: TS_ASSERT(!span.checkInvalidBounds(6, 0)); TS_ASSERT(!span.checkInvalidBounds(2, -2)); TS_ASSERT(span.checkInvalidBounds(-2, 2)); // negative index disallowed - TS_ASSERT(span.checkInvalidBounds(6, 1)); // positive overflow (+7) + TS_ASSERT(span.checkInvalidBounds(6, 1)); // combined positive overflow (+7) TS_ASSERT(span.checkInvalidBounds(2, -4)); // negative overflow (-2) + TS_ASSERT(span.checkInvalidBounds(0, 10)); // delta positive overflow const ptrdiff_t big = 1L << (8 * sizeof(ptrdiff_t) - 1); TS_ASSERT(span.checkInvalidBounds(big, 0)); @@ -653,7 +727,7 @@ public: } Common::NamedSpan span2; - span2 = span; + span = span2 = span; TS_ASSERT_EQUALS(span2, span); TS_ASSERT(span2.name() == span.name()); TS_ASSERT(span2.sourceByteOffset() == span.sourceByteOffset()); -- cgit v1.2.3