From cc22f2bf4263042d5294c7b97a443d9191c2eb1f Mon Sep 17 00:00:00 2001 From: Neil MacIntosh Date: Thu, 25 Feb 2016 11:42:26 -0800 Subject: [PATCH] first/last constructor working. --- include/span.h | 27 ++++++++---- tests/span_tests.cpp | 98 ++++++++++++-------------------------------- 2 files changed, 45 insertions(+), 80 deletions(-) diff --git a/include/span.h b/include/span.h index b8c1196..38cf9f5 100644 --- a/include/span.h +++ b/include/span.h @@ -96,13 +96,20 @@ public: // [span.cons], span constructors, copy, assignment, and destructor constexpr span() noexcept : data_(nullptr), size_(0) { static_assert(extent == dynamic_extent || extent == 0, "Cannot default initialize a fixed-length span."); } - constexpr span(nullptr_t) noexcept : span() {} + + constexpr span(nullptr_t) noexcept : span() + {} + constexpr span(pointer ptr, index_type count) : data_(ptr), size_(count) - { Expects((!ptr && count == 0) || (ptr && count >= 0)); } -#if 0 // TODO - constexpr span(pointer firstElem, pointer lastElem); + { Expects(((!ptr && count == 0) || (ptr && count >= 0)) && (extent == dynamic_extent || extent == count)); } + + constexpr span(pointer firstElem, pointer lastElem) : data_(firstElem), size_(std::distance(firstElem, lastElem)) + { Expects(size_ >= 0 && (extent == dynamic_extent || extent == size_)); } + template - constexpr span(element_type(&arr)[N]); + constexpr span(element_type(&arr)[N]) {} + +#if 0 // TODO template constexpr span(array, N>& arr); template @@ -139,11 +146,13 @@ public: constexpr index_type size_bytes() const noexcept { return size() * sizeof(element_type); } constexpr bool empty() const noexcept { return size() == 0; } -#if 0 // TODO // [span.elem], span element access - constexpr reference operator[](index_type idx) const; - constexpr reference operator()(index_type idx) const; -#endif + constexpr reference operator[](index_type idx) const + { + Expects(idx >= 0 && idx < size_); + return data_[idx]; + } + constexpr reference operator()(index_type idx) const { return this->operator[](idx); } constexpr pointer data() const noexcept { return data_; } #if 0 // TODO // [span.iter], span iterator support diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index 233ab00..11004ae 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -115,7 +115,6 @@ SUITE(span_tests) } } -#if 0 TEST(from_nullptr_length_constructor) { { @@ -135,10 +134,8 @@ SUITE(span_tests) } { -#ifdef CONFIRM_COMPILATION_ERRORS - span s{nullptr, 0}; - CHECK(s.length() == 1 && s.data() == nullptr); // explains why it can't compile -#endif + auto workaround_macro = []() { span s{ nullptr, 0 }; }; + CHECK_THROW(workaround_macro(), fail_fast); } { @@ -166,56 +163,6 @@ SUITE(span_tests) } } - TEST(from_element_constructor) - { - int i = 5; - - { - span s = i; - CHECK(s.length() == 1 && s.data() == &i); - CHECK(s[0] == 5); - - span cs = i; - CHECK(cs.length() == 1 && cs.data() == &i); - CHECK(cs[0] == 5); - } - - { -#ifdef CONFIRM_COMPILATION_ERRORS - const j = 1; - span s = j; -#endif - } - - { -#ifdef CONFIRM_COMPILATION_ERRORS - span s = i; - CHECK(s.length() == 0 && s.data() == &i); -#endif - } - - { - span s = i; - CHECK(s.length() == 1 && s.data() == &i); - CHECK(s[0] == 5); - } - - { -#ifdef CONFIRM_COMPILATION_ERRORS - span s = i; - CHECK(s.length() == 2 && s.data() == &i); -#endif - } - - { -#ifdef CONFIRM_COMPILATION_ERRORS - auto get_a_temp = []() -> int { return 4; }; - auto use_a_span = [](span s) { (void) s; }; - use_a_span(get_a_temp()); -#endif - } - } - TEST(from_pointer_length_constructor) { int arr[4] = {1, 2, 3, 4}; @@ -271,30 +218,39 @@ SUITE(span_tests) CHECK(s.length() == 0 && s.data() == &arr[0]); } + // this will fail the std::distance() precondition, which asserts on MSVC debug builds + //{ + // auto workaround_macro = [&]() { span s{&arr[1], &arr[0]}; }; + // CHECK_THROW(workaround_macro(), fail_fast); + //} + + // this will fail the std::distance() precondition, which asserts on MSVC debug builds + //{ + // int* p = nullptr; + // auto workaround_macro = [&]() { span s{&arr[0], p}; }; + // CHECK_THROW(workaround_macro(), fail_fast); + //} + { - auto workaround_macro = [&]() { span s{&arr[1], &arr[0]}; }; - CHECK_THROW(workaround_macro(), fail_fast); + int* p = nullptr; + span s{ p, p }; + CHECK(s.length() == 0 && s.data() == nullptr); } { int* p = nullptr; - auto workaround_macro = [&]() { span s{&arr[0], p}; }; - CHECK_THROW(workaround_macro(), fail_fast); + span s{ p, p }; + CHECK(s.length() == 0 && s.data() == nullptr); } - { - int* p = nullptr; - auto workaround_macro = [&]() { span s{p, p}; }; - CHECK_THROW(workaround_macro(), fail_fast); - } - - { - int* p = nullptr; - auto workaround_macro = [&]() { span s{&arr[0], p}; }; - CHECK_THROW(workaround_macro(), fail_fast); - } + // this will fail the std::distance() precondition, which asserts on MSVC debug builds + //{ + // int* p = nullptr; + // auto workaround_macro = [&]() { span s{&arr[0], p}; }; + // CHECK_THROW(workaround_macro(), fail_fast); + //} } - +#if 0 TEST(from_array_constructor) { int arr[5] = {1, 2, 3, 4, 5};