diff --git a/groups/bsl/bslstl/bslstl_span.h b/groups/bsl/bslstl/bslstl_span.h index 465acfb5d8..309b825a90 100644 --- a/groups/bsl/bslstl/bslstl_span.h +++ b/groups/bsl/bslstl/bslstl_span.h @@ -409,7 +409,7 @@ class span { // Destroy this object. // ACCESSORS - BSLS_KEYWORD_CONSTEXPR_CPP14 reference back() const BSLS_KEYWORD_NOEXCEPT + BSLS_KEYWORD_CONSTEXPR_CPP14 reference back() const // Return a reference to the last element of this span. The behavior // is undefined if this span is empty. { @@ -427,19 +427,19 @@ class span { template BSLS_KEYWORD_CONSTEXPR_CPP14 - span first() const BSLS_KEYWORD_NOEXCEPT; + span first() const; // Return a statically-sized span consisting of the first 'COUNT' // elements of this span. The behavior is undefined unless // 'COUNT <= size()'. BSLS_KEYWORD_CONSTEXPR_CPP14 span - first(size_type count) const BSLS_KEYWORD_NOEXCEPT; + first(size_type count) const; // Return a dynamically-sized span consisting of the first (specified) // 'count' elements of this span. The behavior is undefined unless // 'count <= size()'. - BSLS_KEYWORD_CONSTEXPR_CPP14 reference front() const BSLS_KEYWORD_NOEXCEPT + BSLS_KEYWORD_CONSTEXPR_CPP14 reference front() const // Return a reference to the first element of this span. The behavior // is undefined if this span is empty. { @@ -450,14 +450,14 @@ class span { template BSLS_KEYWORD_CONSTEXPR_CPP14 - span last() const BSLS_KEYWORD_NOEXCEPT; + span last() const; // Return a statically-sized span consisting of the last 'COUNT' // elements of this span. The behavior is undefined unless // 'COUNT <= size()'. BSLS_KEYWORD_CONSTEXPR_CPP14 span - last(size_type count) const BSLS_KEYWORD_NOEXCEPT; + last(size_type count) const; // Return a dynamically-sized span consisting of the last (specified) // 'count' elements of this span. The behavior is undefined unless // 'count <= size()'. @@ -480,7 +480,7 @@ class span { #endif BSLS_KEYWORD_CONSTEXPR_CPP14 typename Span_Utility::SubspanReturnType::type - subspan() const BSLS_KEYWORD_NOEXCEPT + subspan() const // If the template parameter 'COUNT' is 'dynamic_extent', return a // dynamically-sized span consisting consisting of the elements of this // span in the half-open range '[OFFSET, EXTENT)'. Otherwise, return a @@ -501,8 +501,7 @@ class span { BSLS_KEYWORD_CONSTEXPR_CPP14 span - subspan(size_type offset, size_type count = dynamic_extent) - const BSLS_KEYWORD_NOEXCEPT; + subspan(size_type offset, size_type count = dynamic_extent) const; // Return a dynamically-sized span starting at the specified 'offset'. // If the optionally specified 'count' is 'dynamic_extent', the span // will consist of the half-open range '[offset, size () - offset)' and @@ -511,7 +510,7 @@ class span { // behavior is undefined if 'offset + count > size()'. BSLS_KEYWORD_CONSTEXPR_CPP14 - reference operator[](size_type index) const BSLS_KEYWORD_NOEXCEPT + reference operator[](size_type index) const // Return a reference to the element at the specified 'index'. The // behavior is undefined unless 'index < size()'. { @@ -736,7 +735,7 @@ class span { // Destroy this object. // ACCESSORS - BSLS_KEYWORD_CONSTEXPR_CPP14 reference back() const BSLS_KEYWORD_NOEXCEPT; + BSLS_KEYWORD_CONSTEXPR_CPP14 reference back() const; // Return a reference to the last element of this span. The behavior // is undefined if this span is empty. @@ -748,32 +747,32 @@ class span { template BSLS_KEYWORD_CONSTEXPR_CPP14 - span first() const BSLS_KEYWORD_NOEXCEPT; + span first() const; // Return a statically-sized span consisting of the first 'COUNT' // elements of this span. The behavior is undefined unless // 'COUNT <= size()'. BSLS_KEYWORD_CONSTEXPR_CPP14 span - first(size_type count) const BSLS_KEYWORD_NOEXCEPT; + first(size_type count) const; // Return a dynamically-sized span consisting of the first (specified) // 'count' elements of this span. The behavior is undefined unless // 'count <= size()'. - BSLS_KEYWORD_CONSTEXPR_CPP14 reference front() const BSLS_KEYWORD_NOEXCEPT; + BSLS_KEYWORD_CONSTEXPR_CPP14 reference front() const; // Return a reference to the first element of this span. The behavior // is undefined if this span is empty. template BSLS_KEYWORD_CONSTEXPR_CPP14 - span last() const BSLS_KEYWORD_NOEXCEPT; + span last() const; // Return a statically-sized span consisting of the last 'COUNT' // elements of this span. The behavior is undefined unless // 'COUNT <= size()'. BSLS_KEYWORD_CONSTEXPR_CPP14 span - last(size_type count) const BSLS_KEYWORD_NOEXCEPT; + last(size_type count) const; // Return a dynamically-sized span consisting of the last (specified) // 'count' elements of this span. The behavior is undefined unless // 'count <= size()'. @@ -791,14 +790,13 @@ class span { size_t COUNT> #endif BSLS_KEYWORD_CONSTEXPR_CPP14 - span subspan() const BSLS_KEYWORD_NOEXCEPT; + span subspan() const; // Return a dynamically-sized span consisting of the 'COUNT' elements // of this span starting at 'OFFSET'. The behavior is undefined unless // 'COUNT + OFFSET <= size()'. BSLS_KEYWORD_CONSTEXPR_CPP14 span - subspan(size_type offset, size_type count = dynamic_extent) - const BSLS_KEYWORD_NOEXCEPT; + subspan(size_type offset, size_type count = dynamic_extent) const; // Return a dynamically-sized span starting at the specified 'offset'. // If the optionally specified 'count' is 'dynamic_extent', the span // will consist of the half-open range '[offset, size () - offset)' and @@ -807,7 +805,7 @@ class span { // behavior is undefined unless 'offset + count <= size()'. BSLS_KEYWORD_CONSTEXPR_CPP14 - reference operator[](size_type index) const BSLS_KEYWORD_NOEXCEPT; + reference operator[](size_type index) const; // Return a reference to the element at the specified 'index'. The // behavior is undefined unless 'index < size()'. @@ -1084,7 +1082,7 @@ template template BSLS_KEYWORD_CONSTEXPR_CPP14 inline bsl::span -bsl::span::first() const BSLS_KEYWORD_NOEXCEPT +bsl::span::first() const { typedef bsl::span ReturnType; BSLMF_ASSERT(COUNT <= EXTENT); @@ -1094,7 +1092,7 @@ bsl::span::first() const BSLS_KEYWORD_NOEXCEPT template BSLS_KEYWORD_CONSTEXPR_CPP14 inline bsl::span -bsl::span::first(size_type count) const BSLS_KEYWORD_NOEXCEPT +bsl::span::first(size_type count) const { typedef bsl::span ReturnType; BSLS_ASSERT(count <= size()); @@ -1105,7 +1103,7 @@ template template BSLS_KEYWORD_CONSTEXPR_CPP14 inline bsl::span -bsl::span::last() const BSLS_KEYWORD_NOEXCEPT +bsl::span::last() const { typedef bsl::span ReturnType; BSLMF_ASSERT(COUNT <= EXTENT); @@ -1115,7 +1113,7 @@ bsl::span::last() const BSLS_KEYWORD_NOEXCEPT template BSLS_KEYWORD_CONSTEXPR_CPP14 inline bsl::span -bsl::span::last(size_type count) const BSLS_KEYWORD_NOEXCEPT +bsl::span::last(size_type count) const { typedef bsl::span ReturnType; BSLS_ASSERT(count <= size()); @@ -1134,7 +1132,6 @@ template BSLS_KEYWORD_CONSTEXPR_CPP14 inline bsl::span bsl::span::subspan(size_type offset, size_type count) const - BSLS_KEYWORD_NOEXCEPT { typedef bsl::span ReturnType; BSLS_ASSERT(offset <= size()); @@ -1312,7 +1309,7 @@ inline bsl::span::span( bsl::vector& v, typename bsl::enable_if::value, - void *>::type) + void *>::type) BSLS_KEYWORD_NOEXCEPT : d_data_p(v.data()) , d_size(v.size()) { @@ -1324,7 +1321,7 @@ inline bsl::span::span( const bsl::vector& v, typename bsl::enable_if::value, - void *>::type) + void *>::type) BSLS_KEYWORD_NOEXCEPT : d_data_p(v.data()) , d_size(v.size()) { @@ -1336,7 +1333,7 @@ inline bsl::span::span( bsl::basic_string& s, typename bsl::enable_if::value, - void *>::type) + void *>::type) BSLS_KEYWORD_NOEXCEPT : d_data_p(s.data()) , d_size(s.size()) { @@ -1348,7 +1345,7 @@ inline bsl::span::span( const bsl::basic_string& s, typename bsl::enable_if::value, - void *>::type) + void *>::type) BSLS_KEYWORD_NOEXCEPT : d_data_p(s.data()) , d_size(s.size()) { @@ -1360,7 +1357,7 @@ inline bsl::span::span( const bsl::basic_string_view& sv, typename bsl::enable_if::value, - void *>::type) + void *>::type) BSLS_KEYWORD_NOEXCEPT : d_data_p(sv.data()) , d_size(sv.size()) { @@ -1384,7 +1381,7 @@ bsl::span::span( template BSLS_KEYWORD_CONSTEXPR_CPP14 inline typename bsl::span::reference -bsl::span::back() const BSLS_KEYWORD_NOEXCEPT +bsl::span::back() const { BSLS_ASSERT(size() > 0); return d_data_p[size() - 1]; @@ -1410,7 +1407,7 @@ template template BSLS_KEYWORD_CONSTEXPR_CPP14 inline bsl::span -bsl::span::first() const BSLS_KEYWORD_NOEXCEPT +bsl::span::first() const { typedef bsl::span ReturnType; BSLS_ASSERT(COUNT <= size()); @@ -1421,7 +1418,6 @@ template BSLS_KEYWORD_CONSTEXPR_CPP14 inline bsl::span bsl::span::first(size_type count) const - BSLS_KEYWORD_NOEXCEPT { typedef bsl::span ReturnType; BSLS_ASSERT(count <= size()); @@ -1431,7 +1427,7 @@ bsl::span::first(size_type count) const template BSLS_KEYWORD_CONSTEXPR_CPP14 inline typename bsl::span::reference -bsl::span::front() const BSLS_KEYWORD_NOEXCEPT +bsl::span::front() const { BSLS_ASSERT(size() > 0); return d_data_p[0]; @@ -1441,7 +1437,7 @@ template template BSLS_KEYWORD_CONSTEXPR_CPP14 inline bsl::span -bsl::span::last() const BSLS_KEYWORD_NOEXCEPT +bsl::span::last() const { typedef bsl::span ReturnType; BSLS_ASSERT(COUNT <= size()); @@ -1452,7 +1448,6 @@ template BSLS_KEYWORD_CONSTEXPR_CPP14 inline bsl::span bsl::span::last(size_type count) const - BSLS_KEYWORD_NOEXCEPT { typedef bsl::span ReturnType; BSLS_ASSERT(count <= size()); @@ -1480,7 +1475,7 @@ template template BSLS_KEYWORD_CONSTEXPR_CPP14 inline bsl::span -bsl::span::subspan() const BSLS_KEYWORD_NOEXCEPT +bsl::span::subspan() const { typedef bsl::span ReturnType; BSLS_ASSERT(OFFSET <= size()); @@ -1492,9 +1487,8 @@ bsl::span::subspan() const BSLS_KEYWORD_NOEXCEPT template BSLS_KEYWORD_CONSTEXPR_CPP14 inline bsl::span -bsl::span::subspan( - size_type offset, - size_type count) const BSLS_KEYWORD_NOEXCEPT +bsl::span::subspan(size_type offset, + size_type count) const { typedef bsl::span ReturnType; BSLS_ASSERT(offset <= size()); @@ -1510,7 +1504,6 @@ template BSLS_KEYWORD_CONSTEXPR_CPP14 inline typename bsl::span::reference bsl::span::operator[](size_type index) const - BSLS_KEYWORD_NOEXCEPT { BSLS_ASSERT(index < size()); return d_data_p[index]; diff --git a/groups/bsl/bslstl/bslstl_span.t.cpp b/groups/bsl/bslstl/bslstl_span.t.cpp index e5db23d90e..0ac6b3bef6 100644 --- a/groups/bsl/bslstl/bslstl_span.t.cpp +++ b/groups/bsl/bslstl/bslstl_span.t.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -23,40 +24,40 @@ // TEST PLAN //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -// [ 2] span(); +// [ 2] span() noexcept; // [ 2] span(pointer, size_type); // [ 2] span(pointer, pointer); -// [ 2] span(element_type (&arr)[SIZE]); -// [ 2] span(const span &); -// [ 2] span(span); -// [ 2] operator=(const span &); -// [ 3] span(array&); -// [ 3] span(const array&); -// [ 3] span(std::array&); -// [ 3] span(const std::array&); +// [ 2] span(element_type (&arr)[SIZE]) noexcept; +// [ 2] span(const span &) noexcept; +// [ 2] span(span) noexcept; +// [ 2] operator=(const span &) noexcept; +// [ 3] span(array&) noexcept; +// [ 3] span(const array&) noexcept; +// [ 3] span(std::array&) noexcept; +// [ 3] span(const std::array&) noexcept; // [ 3] span(CONTAINER& c); // [ 3] span(const CONTAINER& c); // [ 4] reference front(); // [ 4] reference back(); // [ 4] reference operator[](size_type); -// [ 4] bool empty(); +// [ 4] bool empty() noexcept; // [ 4] size_type extent; -// [ 4] size_type size(); -// [ 4] size_type size_bytes(); -// [ 4] pointer data(); +// [ 4] size_type size() noexcept; +// [ 4] size_type size_bytes() noexcept; +// [ 4] pointer data() noexcept; // [ 5] template first(); // [ 5] template last(); // [ 5] first(size_t count); // [ 5] last(size_t count); // [ 5] template subspan(); // [ 5] subspan(size_t count, size_t offset); -// [ 6] iterator begin(); -// [ 6] iterator end(); -// [ 6] reverse_iterator rbegin(); -// [ 6] reverse_iterator rend(); -// [ 7] void swap(span a, span b); -// [ 7] span as_bytes(span); -// [ 7] span as_writable_bytes(span); +// [ 6] iterator begin() noexcept; +// [ 6] iterator end() noexcept; +// [ 6] reverse_iterator rbegin() noexcept; +// [ 6] reverse_iterator rend() noexcept; +// [ 7] void swap(span a, span b) noexcept; +// [ 7] span as_bytes(span) noexcept; +// [ 7] span as_writable_bytes(span) noexcept; // ---------------------------------------------------------------------------- // [ 1] BREATHING TEST // [ 8] CLASS TEMPLATE DEDUCTION GUIDES @@ -117,6 +118,22 @@ void aSsErT(bool condition, const char *message, int line) #define ASSERT_OPT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR) #define ASSERT_OPT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR) +// We want to test the negative 'noexcept'-ness of some functions in span, but +// only if we're not using 'std::span', because all three implementations of +// std::span add 'noexcept' to 'front', 'back', 'first', 'last', and 'subspan', +// as well as the '(pointer, pointer)' and '(pointer, size)' constructors. +#ifndef BSLS_LIBRARYFEATURES_HAS_CPP20_BASELINE_LIBRARY + #define NOEXCEPT_TEST_ONLY_BSL_SPAN 1 +#endif + +#ifdef BSLS_COMPILERFEATURES_SUPPORT_NOEXCEPT +#define ASSERT_NOEXCEPT(...) BSLS_ASSERT( noexcept(__VA_ARGS__)) +#define ASSERT_NOT_NOEXCEPT(...) BSLS_ASSERT(!noexcept(__VA_ARGS__)) +#else +#define ASSERT_NOEXCEPT(...) BSLS_ASSERT(true) +#define ASSERT_NOT_NOEXCEPT(...) BSLS_ASSERT(true) +#endif + //============================================================================= // USAGE EXAMPLE //----------------------------------------------------------------------------- @@ -164,16 +181,38 @@ void TestBasicConstructors() { bsl::span defS; bsl::span defD; + + ASSERT_NOEXCEPT(bsl::span()); + ASSERT_NOEXCEPT(bsl::span()); + ASSERT(NULL == defS.data()); ASSERT(0 == defS.size()); ASSERT(NULL == defD.data()); ASSERT(0 == defD.size()); } +// MSVC erroneously reports the two constructors (pointer, size) and (pointer, +// pointer) as noexcept. The trigger appears to be declaring them as +// 'constexpr'. I reported to MS on 10-May-2024. They replied (on 13-May): +// +// The short answer is: compile with /permissive-. +// +// The longer answer: MSVC in permissive mode has an extension that allows the +// compiler to adhere to a language rule prior to DR +// https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1351 and we +// can't change it due to back-compat. + // pointer, size { bsl::span psS(&arr[5], 5); bsl::span psD(&arr[3], 3); + +#if defined(NOEXCEPT_TEST_ONLY_BSL_SPAN) && \ + !(defined(BSLS_PLATFORM_CMP_MSVC) && (BSLS_PLATFORM_CMP_VERSION <= 1999)) + ASSERT_NOT_NOEXCEPT(bsl::span(&arr[5], 5)); + ASSERT_NOT_NOEXCEPT(bsl::span(&arr[5], 5)); +#endif + ASSERT(&arr[5] == psS.data()); ASSERT(5 == psS.size()); ASSERT(&arr[3] == psD.data()); @@ -184,6 +223,13 @@ void TestBasicConstructors() { bsl::span ppS(&arr[5], &arr[10]); bsl::span ppD(&arr[3], &arr[6]); + +#if defined(NOEXCEPT_TEST_ONLY_BSL_SPAN) && \ + !(defined(BSLS_PLATFORM_CMP_MSVC) && (BSLS_PLATFORM_CMP_VERSION <= 1999)) + ASSERT_NOT_NOEXCEPT(bsl::span(&arr[5], &arr[10])); + ASSERT_NOT_NOEXCEPT(bsl::span(&arr[3], &arr[ 6])); +#endif + ASSERT(&arr[5] == ppS.data()); ASSERT(5 == ppS.size()); ASSERT(&arr[3] == ppD.data()); @@ -194,6 +240,10 @@ void TestBasicConstructors() { bsl::span arrS(arr); bsl::span arrD(arr); + + ASSERT_NOEXCEPT(bsl::span(arr)); + ASSERT_NOEXCEPT(bsl::span(arr)); + ASSERT(&arr[0] == arrS.data()); ASSERT(10 == arrS.size()); ASSERT(&arr[0] == arrD.data()); @@ -209,6 +259,11 @@ void TestBasicConstructors() bsl::span sD1b(sS); bsl::span sS2a(sD); + ASSERT_NOEXCEPT(bsl::span(sS)); + ASSERT_NOEXCEPT(bsl::span(sS)); + ASSERT_NOEXCEPT(bsl::span(sD)); + ASSERT_NOEXCEPT(bsl::span(sD)); + ASSERT(&arr[5] == sS1.data()); ASSERT(5 == sS1.size()); ASSERT(&arr[3] == sD1a.data()); @@ -227,6 +282,10 @@ void TestBasicConstructors() bsl::span psD1a(psD); bsl::span psD1b(psS); + ASSERT_NOEXCEPT(bsl::span(psS)); + ASSERT_NOEXCEPT(bsl::span(psS)); + ASSERT_NOEXCEPT(bsl::span(psD)); + ASSERT(&arr[5] == psS1.data()); ASSERT(5 == psS1.size()); ASSERT(&arr[3] == psD1a.data()); @@ -242,6 +301,15 @@ void TestBasicConstructors() psD2a = psD; psD2b = psS; + ASSERT_NOEXCEPT(psS2 = psS); + ASSERT_NOEXCEPT(psD2a = psD); + ASSERT_NOEXCEPT(psD2b = psS); + + ASSERT_NOEXCEPT(bsl::span(psS)); + ASSERT_NOEXCEPT(bsl::span(psD)); + ASSERT_NOEXCEPT(bsl::span(psS)); + ASSERT_NOEXCEPT(bsl::span(psD)); + ASSERT(&arr[5] == psS2.data()); ASSERT(5 == psS2.size()); ASSERT(&arr[3] == psD2a.data()); @@ -267,6 +335,10 @@ void TestContainerConstructors() { bsl::span arrS(arr); bsl::span arrD(arr); + + ASSERT_NOEXCEPT(bsl::span(arr)); + ASSERT_NOEXCEPT(bsl::span (arr)); + ASSERT(arr.data() == arrS.data()); ASSERT(10 == arrS.size()); ASSERT(arr.data() == arrD.data()); @@ -277,6 +349,10 @@ void TestContainerConstructors() { bsl::span carrS(cArr); bsl::span carrD(cArr); + + ASSERT_NOEXCEPT(bsl::span(cArr)); + ASSERT_NOEXCEPT(bsl::span (cArr)); + ASSERT(cArr.data() == carrS.data()); ASSERT(10 == carrS.size()); ASSERT(cArr.data() == carrD.data()); @@ -296,6 +372,10 @@ void TestContainerConstructors() { bsl::span arrS(sArr); bsl::span arrD(sArr); + + ASSERT_NOEXCEPT(bsl::span(sArr)); + ASSERT_NOEXCEPT(bsl::span (sArr)); + ASSERT(sArr.data() == arrS.data()); ASSERT(10 == arrS.size()); ASSERT(sArr.data() == arrD.data()); @@ -306,6 +386,10 @@ void TestContainerConstructors() { bsl::span carrS(cSArr); bsl::span carrD(cSArr); + + ASSERT_NOEXCEPT(bsl::span(cSArr)); + ASSERT_NOEXCEPT(bsl::span (cSArr)); + ASSERT(cSArr.data() == carrS.data()); ASSERT(10 == carrS.size()); ASSERT(cSArr.data() == carrD.data()); @@ -320,6 +404,11 @@ void TestContainerConstructors() // from a bsl::vector (dynamic span only) { bsl::span arrD(vec); + +#if defined(NOEXCEPT_TEST_ONLY_BSL_SPAN) + ASSERT_NOT_NOEXCEPT(bsl::span(vec)); +#endif + ASSERT(vec.data() == arrD.data()); ASSERT(30 == arrD.size()); } @@ -327,6 +416,11 @@ void TestContainerConstructors() // from a const bsl::vector (dynamic span only) { bsl::span carrD(cVec); + +#if defined(NOEXCEPT_TEST_ONLY_BSL_SPAN) + ASSERT_NOT_NOEXCEPT(bsl::span(cVec)); +#endif + ASSERT(cVec.data() == carrD.data()); ASSERT(30 == carrD.size()); } @@ -336,6 +430,12 @@ void TestContainerConstructors() // from a bsl::string (dynamic span only) { bsl::span strD(str); + +#if defined(NOEXCEPT_TEST_ONLY_BSL_SPAN) + ASSERT_NOT_NOEXCEPT(bsl::span(str)); + ASSERT_NOT_NOEXCEPT(bsl::span(str)); +#endif + ASSERT(str.data() == strD.data()); ASSERT(5 == strD.size()); @@ -347,6 +447,11 @@ void TestContainerConstructors() // from a const bsl::string (dynamic span only) { bsl::span cstrD(cStr); + +#if defined(NOEXCEPT_TEST_ONLY_BSL_SPAN) + ASSERT_NOT_NOEXCEPT(bsl::span(cStr)); +#endif + ASSERT(str.data() == cstrD.data()); ASSERT(5 == cstrD.size()); } @@ -355,6 +460,11 @@ void TestContainerConstructors() // from a string_view (dynamic span only) { bsl::span cstrD(sv); + +#if defined(NOEXCEPT_TEST_ONLY_BSL_SPAN) + ASSERT_NOT_NOEXCEPT(bsl::span(sv)); +#endif + ASSERT(sv.data() == cstrD.data()); ASSERT(5 == cstrD.size()); } @@ -385,6 +495,13 @@ void TestAccessors() ASSERT(bsl::dynamic_extent == zdSpan.extent); // size + ASSERT_NOEXCEPT( sSpan.size()); + ASSERT_NOEXCEPT(csSpan.size()); + ASSERT_NOEXCEPT( dSpan.size()); + ASSERT_NOEXCEPT(cdSpan.size()); + ASSERT_NOEXCEPT(zsSpan.size()); + ASSERT_NOEXCEPT(zdSpan.size()); + ASSERT(10 == sSpan.size()); ASSERT(4 == csSpan.size()); ASSERT(10 == dSpan.size()); @@ -393,6 +510,13 @@ void TestAccessors() ASSERT(0 == zdSpan.size()); // size_bytes + ASSERT_NOEXCEPT( sSpan.size_bytes()); + ASSERT_NOEXCEPT(csSpan.size_bytes()); + ASSERT_NOEXCEPT( dSpan.size_bytes()); + ASSERT_NOEXCEPT(cdSpan.size_bytes()); + ASSERT_NOEXCEPT(zsSpan.size_bytes()); + ASSERT_NOEXCEPT(zdSpan.size_bytes()); + ASSERT(10 * sizeof(int) == sSpan.size_bytes()); ASSERT(4 * sizeof(int) == csSpan.size_bytes()); ASSERT(10 * sizeof(int) == dSpan.size_bytes()); @@ -401,6 +525,13 @@ void TestAccessors() ASSERT(0 * sizeof(int) == zdSpan.size_bytes()); // empty + ASSERT_NOEXCEPT( sSpan.empty()); + ASSERT_NOEXCEPT(csSpan.empty()); + ASSERT_NOEXCEPT( dSpan.empty()); + ASSERT_NOEXCEPT(cdSpan.empty()); + ASSERT_NOEXCEPT(zsSpan.empty()); + ASSERT_NOEXCEPT(zdSpan.empty()); + ASSERT(! sSpan.empty()); ASSERT(!csSpan.empty()); ASSERT(! dSpan.empty()); @@ -409,24 +540,52 @@ void TestAccessors() ASSERT( zdSpan.empty()); // data + ASSERT_NOEXCEPT( sSpan.data()); + ASSERT_NOEXCEPT(csSpan.data()); + ASSERT_NOEXCEPT( dSpan.data()); + ASSERT_NOEXCEPT(cdSpan.data()); + ASSERT_NOEXCEPT(zsSpan.data()); + ASSERT_NOEXCEPT(zdSpan.data()); + ASSERT(&arr[0] == sSpan.data()); ASSERT(&arr[5] == csSpan.data()); ASSERT(&arr[0] == dSpan.data()); ASSERT(&arr[5] == cdSpan.data()); // front +#ifdef NOEXCEPT_TEST_ONLY_BSL_SPAN + ASSERT_NOT_NOEXCEPT( sSpan.front()); + ASSERT_NOT_NOEXCEPT(csSpan.front()); + ASSERT_NOT_NOEXCEPT( dSpan.front()); + ASSERT_NOT_NOEXCEPT(cdSpan.front()); +#endif + ASSERT(0 == sSpan.front()); ASSERT(5 == csSpan.front()); ASSERT(0 == dSpan.front()); ASSERT(5 == cdSpan.front()); // back +#ifdef NOEXCEPT_TEST_ONLY_BSL_SPAN + ASSERT_NOT_NOEXCEPT( sSpan.back()); + ASSERT_NOT_NOEXCEPT(csSpan.back()); + ASSERT_NOT_NOEXCEPT( dSpan.back()); + ASSERT_NOT_NOEXCEPT(cdSpan.back()); +#endif + ASSERT(9 == sSpan.back()); ASSERT(8 == csSpan.back()); ASSERT(9 == dSpan.back()); ASSERT(8 == cdSpan.back()); // operator[] +#ifdef NOEXCEPT_TEST_ONLY_BSL_SPAN + ASSERT_NOT_NOEXCEPT( sSpan[0]); + ASSERT_NOT_NOEXCEPT(csSpan[0]); + ASSERT_NOT_NOEXCEPT( dSpan[0]); + ASSERT_NOT_NOEXCEPT(cdSpan[0]); +#endif + ASSERT(7 == sSpan[7]); ASSERT(6 == csSpan[1]); ASSERT(7 == dSpan[7]); @@ -455,6 +614,13 @@ void TestSubspan() bsl::span dFirstA = dSpan.first<4>(); bsl::span cdFirstA = cdSpan.first<2>(); +#ifdef NOEXCEPT_TEST_ONLY_BSL_SPAN + ASSERT_NOT_NOEXCEPT( sSpan.first<4>()); + ASSERT_NOT_NOEXCEPT(csSpan.first<2>()); + ASSERT_NOT_NOEXCEPT( dSpan.first<4>()); + ASSERT_NOT_NOEXCEPT(cdSpan.first<2>()); +#endif + ASSERT(4 == sFirstA.size()); ASSERT(2 == csFirstA.size()); ASSERT(4 == dFirstA.size()); @@ -470,6 +636,13 @@ void TestSubspan() bsl::span dFirstB = dSpan.first(4); bsl::span cdFirstB = cdSpan.first(2); +#ifdef NOEXCEPT_TEST_ONLY_BSL_SPAN + ASSERT_NOT_NOEXCEPT( sSpan.first(4)); + ASSERT_NOT_NOEXCEPT(csSpan.first(2)); + ASSERT_NOT_NOEXCEPT( dSpan.first(4)); + ASSERT_NOT_NOEXCEPT(cdSpan.first(2)); +#endif + ASSERT(4 == sFirstB.size()); ASSERT(2 == csFirstB.size()); ASSERT(4 == dFirstB.size()); @@ -486,6 +659,13 @@ void TestSubspan() bsl::span dLastA = dSpan.last<4>(); bsl::span cdLastA = cdSpan.last<2>(); +#ifdef NOEXCEPT_TEST_ONLY_BSL_SPAN + ASSERT_NOT_NOEXCEPT( sSpan.last<4>()); + ASSERT_NOT_NOEXCEPT(csSpan.last<2>()); + ASSERT_NOT_NOEXCEPT( dSpan.last<4>()); + ASSERT_NOT_NOEXCEPT(cdSpan.last<2>()); +#endif + ASSERT(4 == sLastA.size()); ASSERT(2 == csLastA.size()); ASSERT(4 == dLastA.size()); @@ -501,6 +681,13 @@ void TestSubspan() bsl::span dLastB = dSpan.last(4); bsl::span cdLastB = cdSpan.last(2); +#ifdef NOEXCEPT_TEST_ONLY_BSL_SPAN + ASSERT_NOT_NOEXCEPT( sSpan.last(4)); + ASSERT_NOT_NOEXCEPT(csSpan.last(2)); + ASSERT_NOT_NOEXCEPT( dSpan.last(4)); + ASSERT_NOT_NOEXCEPT(cdSpan.last(2)); +#endif + ASSERT(4 == sLastB.size()); ASSERT(2 == csLastB.size()); ASSERT(4 == dLastB.size()); @@ -522,6 +709,18 @@ void TestSubspan() bsl::span dSubA2 = sSpan.subspan<4, DYN>(); bsl::span cdSubA2 = cdSpan.subspan<2, DYN>(); +#ifdef NOEXCEPT_TEST_ONLY_BSL_SPAN + ASSERT_NOT_NOEXCEPT( sSpan.subspan<2, 4>()); + ASSERT_NOT_NOEXCEPT(csSpan.subspan<1, 2>()); + ASSERT_NOT_NOEXCEPT( dSpan.subspan<2, 4>()); + ASSERT_NOT_NOEXCEPT(cdSpan.subspan<1, 2>()); + + ASSERT_NOT_NOEXCEPT( sSpan.subspan<2, DYN>()); + ASSERT_NOT_NOEXCEPT(csSpan.subspan<1, DYN>()); + ASSERT_NOT_NOEXCEPT( dSpan.subspan<2, DYN>()); + ASSERT_NOT_NOEXCEPT(cdSpan.subspan<1, DYN>()); +#endif + ASSERT(4 == sSubA1.size()); ASSERT(2 == csSubA1.size()); ASSERT(4 == dSubA1.size()); @@ -547,6 +746,13 @@ void TestSubspan() bsl::span dSubB1 = dSpan.subspan(2, 4); bsl::span cdSubB1 = cdSpan.subspan(1, 2); +#ifdef NOEXCEPT_TEST_ONLY_BSL_SPAN + ASSERT_NOT_NOEXCEPT( sSpan.subspan(2, 4)); + ASSERT_NOT_NOEXCEPT(csSpan.subspan(1, 2)); + ASSERT_NOT_NOEXCEPT( dSpan.subspan(2, 4)); + ASSERT_NOT_NOEXCEPT(cdSpan.subspan(1, 2)); +#endif + ASSERT(4 == sSubB1.size()); ASSERT(2 == csSubB1.size()); ASSERT(4 == dSubB1.size()); @@ -562,6 +768,13 @@ void TestSubspan() bsl::span dSubB2 = dSpan.subspan(4, DYN); bsl::span cdSubB2 = cdSpan.subspan(3, DYN); +#ifdef NOEXCEPT_TEST_ONLY_BSL_SPAN + ASSERT_NOT_NOEXCEPT( sSpan.subspan(4, DYN)); + ASSERT_NOT_NOEXCEPT(csSpan.subspan(3, DYN)); + ASSERT_NOT_NOEXCEPT( dSpan.subspan(4, DYN)); + ASSERT_NOT_NOEXCEPT(cdSpan.subspan(3, DYN)); +#endif + ASSERT(6 == sSubB2.size()); ASSERT(1 == csSubB2.size()); ASSERT(6 == dSubB2.size()); @@ -603,6 +816,26 @@ void TestIterators() bsl::span< int> dSpan (&arr[0], 10); bsl::span cdSpan(&arr[5], 4); + ASSERT_NOEXCEPT( sSpan.begin()); + ASSERT_NOEXCEPT(csSpan.begin()); + ASSERT_NOEXCEPT( dSpan.begin()); + ASSERT_NOEXCEPT(cdSpan.begin()); + + ASSERT_NOEXCEPT( sSpan.end()); + ASSERT_NOEXCEPT(csSpan.end()); + ASSERT_NOEXCEPT( dSpan.end()); + ASSERT_NOEXCEPT(cdSpan.end()); + + ASSERT_NOEXCEPT( sSpan.rbegin()); + ASSERT_NOEXCEPT(csSpan.rbegin()); + ASSERT_NOEXCEPT( dSpan.rbegin()); + ASSERT_NOEXCEPT(cdSpan.rbegin()); + + ASSERT_NOEXCEPT( sSpan.rend()); + ASSERT_NOEXCEPT(csSpan.rend()); + ASSERT_NOEXCEPT( dSpan.rend()); + ASSERT_NOEXCEPT(cdSpan.rend()); + // Forward iterators idx = 0; for (bsl::span::iterator iter = sSpan.begin(); @@ -734,6 +967,11 @@ void TestFreeFunctions () auto dBytes1 = bsl::as_bytes(dSpan1); auto dBytes2 = bsl::as_writable_bytes(dSpan2); + ASSERT_NOEXCEPT(bsl::as_bytes(sSpan1)); + ASSERT_NOEXCEPT(bsl::as_writable_bytes(sSpan2)); + ASSERT_NOEXCEPT(bsl::as_bytes(dSpan1)); + ASSERT_NOEXCEPT(bsl::as_writable_bytes(dSpan2)); + BSLMF_ASSERT((bsl::is_same_v>)); BSLMF_ASSERT((bsl::is_same_v as_bytes(span); - // span as_writable_bytes(span); + // void swap(span a, span b) noexcept; + // span as_bytes(span) noexcept; + // span as_writable_bytes(span) noexcept; // -------------------------------------------------------------------- if (verbose) printf("\nFREE FUNCTIONS" @@ -1048,10 +1289,10 @@ int main(int argc, char *argv[]) //: referred to by the span. // // Testing: - // iterator begin(); - // iterator end(); - // reverse_iterator rbegin(); - // reverse_iterator rend(); + // iterator begin() noexcept; + // iterator end() noexcept; + // reverse_iterator rbegin() noexcept; + // reverse_iterator rend() noexcept; // -------------------------------------------------------------------- if (verbose) printf("\nITERATORS" @@ -1113,11 +1354,11 @@ int main(int argc, char *argv[]) // reference front(); // reference back(); // reference operator[](size_type); - // bool empty(); + // bool empty() noexcept; // size_type extent; - // size_type size(); - // size_type size_bytes(); - // pointer data(); + // size_type size() noexcept; + // size_type size_bytes() noexcept; + // pointer data() noexcept; // -------------------------------------------------------------------- if (verbose) printf("\nACCESSORS" @@ -1142,10 +1383,10 @@ int main(int argc, char *argv[]) //: container that they were created from. // // Testing: - // span(array&); - // span(const array&); - // span(std::array&); - // span(const std::array&); + // span(array&) noexcept; + // span(const array&) noexcept; + // span(std::array&) noexcept; + // span(const std::array&) noexcept; // span(CONTAINER& c); // span(const CONTAINER& c); // -------------------------------------------------------------------- @@ -1172,13 +1413,13 @@ int main(int argc, char *argv[]) //: the paramaters passed to the constructor. // // Testing: - // span(); + // span() noexcept; // span(pointer, size_type); // span(pointer, pointer); - // span(element_type (&arr)[SIZE]); - // span(const span &); - // span(span); - // operator=(const span &); + // span(element_type (&arr)[SIZE]) noexcept; + // span(const span &) noexcept; + // span(span) noexcept; + // operator=(const span &) noexcept; // -------------------------------------------------------------------- if (verbose) printf("\nBASIC CONSTRUCTORS"