Merge branch 'master' of https://github.com/neilmacintosh/GSL into dev/neilmac/fix_mismatched_pragma

This commit is contained in:
Neil MacIntosh 2016-08-02 18:10:07 -07:00
commit db9d3da029
17 changed files with 5742 additions and 3569 deletions

View File

@ -16,6 +16,6 @@ AllowShortLoopsOnASingleLine: true
PointerAlignment: Left PointerAlignment: Left
AlignConsecutiveAssignments: false AlignConsecutiveAssignments: false
AlignTrailingComments: false AlignTrailingComments: true
SpaceAfterCStyleCast: true SpaceAfterCStyleCast: true

View File

@ -14,6 +14,9 @@ it is simplest to just include [gsl.h](./include/gsl.h) and gain access to the e
> NOTE: We encourage contributions that improve or refine any of the types in this library as well as ports to > NOTE: We encourage contributions that improve or refine any of the types in this library as well as ports to
other platforms. Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for more information about contributing. other platforms. Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for more information about contributing.
# Project Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
# Quick Start # Quick Start
## Supported Platforms ## Supported Platforms
The test suite that exercises GSL has been built and passes successfully on the following platforms: The test suite that exercises GSL has been built and passes successfully on the following platforms:

View File

@ -21,7 +21,8 @@
#include "gsl_assert.h" // Ensures/Expects #include "gsl_assert.h" // Ensures/Expects
#include "gsl_util.h" // finally()/narrow()/narrow_cast()... #include "gsl_util.h" // finally()/narrow()/narrow_cast()...
#include "span.h" // span, strided_span... #include "multi_span.h" // multi_span, strided_span...
#include "span.h" // span
#include "string_span.h" // zstring, string_span, zstring_builder... #include "string_span.h" // zstring, string_span, zstring_builder...
#include <memory> #include <memory>
@ -39,13 +40,12 @@
// turn off some misguided warnings // turn off some misguided warnings
#pragma warning(push) #pragma warning(push)
#pragma warning(disable: 4351) // warns about newly introduced aggregate initializer behavior #pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
#endif // _MSC_VER <= 1800 #endif // _MSC_VER <= 1800
#endif // _MSC_VER #endif // _MSC_VER
namespace gsl namespace gsl
{ {
@ -58,7 +58,6 @@ using std::shared_ptr;
template <class T> template <class T>
using owner = T; using owner = T;
// //
// not_null // not_null
// //
@ -73,25 +72,31 @@ using owner = T;
// - ensure construction from U* fails with nullptr // - ensure construction from U* fails with nullptr
// - allow implicit conversion to U* // - allow implicit conversion to U*
// //
template<class T> template <class T>
class not_null class not_null
{ {
static_assert(std::is_assignable<T&, std::nullptr_t>::value, "T cannot be assigned nullptr."); static_assert(std::is_assignable<T&, std::nullptr_t>::value, "T cannot be assigned nullptr.");
public: public:
not_null(T t) : ptr_(t) { ensure_invariant(); } not_null(T t) : ptr_(t) { ensure_invariant(); }
not_null& operator=(const T& t) { ptr_ = t; ensure_invariant(); return *this; } not_null& operator=(const T& t)
{
ptr_ = t;
ensure_invariant();
return *this;
}
not_null(const not_null &other) = default; not_null(const not_null& other) = default;
not_null& operator=(const not_null &other) = default; not_null& operator=(const not_null& other) = default;
template <typename U, typename Dummy = std::enable_if_t<std::is_convertible<U, T>::value>> template <typename U, typename Dummy = std::enable_if_t<std::is_convertible<U, T>::value>>
not_null(const not_null<U> &other) not_null(const not_null<U>& other)
{ {
*this = other; *this = other;
} }
template <typename U, typename Dummy = std::enable_if_t<std::is_convertible<U, T>::value>> template <typename U, typename Dummy = std::enable_if_t<std::is_convertible<U, T>::value>>
not_null& operator=(const not_null<U> &other) not_null& operator=(const not_null<U>& other)
{ {
ptr_ = other.get(); ptr_ = other.get();
return *this; return *this;
@ -103,7 +108,8 @@ public:
not_null<T>& operator=(std::nullptr_t) = delete; not_null<T>& operator=(std::nullptr_t) = delete;
not_null<T>& operator=(int) = delete; not_null<T>& operator=(int) = delete;
T get() const { T get() const
{
#ifdef _MSC_VER #ifdef _MSC_VER
__assume(ptr_ != nullptr); __assume(ptr_ != nullptr);
#endif #endif
@ -118,7 +124,8 @@ public:
private: private:
T ptr_; T ptr_;
// we assume that the compiler can hoist/prove away most of the checks inlined from this function // we assume that the compiler can hoist/prove away most of the checks inlined from this
// function
// if not, we could make them optional via conditional compilation // if not, we could make them optional via conditional compilation
void ensure_invariant() const { Expects(ptr_ != nullptr); } void ensure_invariant() const { Expects(ptr_ != nullptr); }
@ -138,14 +145,11 @@ private:
namespace std namespace std
{ {
template<class T> template <class T>
struct hash<gsl::not_null<T>> struct hash<gsl::not_null<T>>
{ {
size_t operator()(const gsl::not_null<T> & value) const size_t operator()(const gsl::not_null<T>& value) const { return hash<T>{}(value); }
{ };
return hash<T>{}(value);
}
};
} // namespace std } // namespace std

View File

@ -30,15 +30,14 @@
// 2. GSL_THROW_ON_CONTRACT_VIOLATION: a gsl::fail_fast exception will be thrown // 2. GSL_THROW_ON_CONTRACT_VIOLATION: a gsl::fail_fast exception will be thrown
// 3. GSL_UNENFORCED_ON_CONTRACT_VIOLATION: nothing happens // 3. GSL_UNENFORCED_ON_CONTRACT_VIOLATION: nothing happens
// //
#if !(defined(GSL_THROW_ON_CONTRACT_VIOLATION) ^ defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) ^ defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)) #if !(defined(GSL_THROW_ON_CONTRACT_VIOLATION) ^ defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) ^ \
defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION))
#define GSL_TERMINATE_ON_CONTRACT_VIOLATION #define GSL_TERMINATE_ON_CONTRACT_VIOLATION
#endif #endif
#define GSL_STRINGIFY_DETAIL(x) #x #define GSL_STRINGIFY_DETAIL(x) #x
#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x) #define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x)
// //
// GSL.assert: assertions // GSL.assert: assertions
// //
@ -53,18 +52,20 @@ struct fail_fast : public std::runtime_error
#if defined(GSL_THROW_ON_CONTRACT_VIOLATION) #if defined(GSL_THROW_ON_CONTRACT_VIOLATION)
#define Expects(cond) if (!(cond)) \ #define Expects(cond) \
if (!(cond)) \
throw gsl::fail_fast("GSL: Precondition failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__)); throw gsl::fail_fast("GSL: Precondition failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__));
#define Ensures(cond) if (!(cond)) \ #define Ensures(cond) \
throw gsl::fail_fast("GSL: Postcondition failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__)); if (!(cond)) \
throw gsl::fail_fast("GSL: Postcondition failure at " __FILE__ \
": " GSL_STRINGIFY(__LINE__));
#elif defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) #elif defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
#define Expects(cond) \
#define Expects(cond) if (!(cond)) std::terminate(); if (!(cond)) std::terminate();
#define Ensures(cond) if (!(cond)) std::terminate(); #define Ensures(cond) \
if (!(cond)) std::terminate();
#elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION) #elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)
@ -73,5 +74,4 @@ struct fail_fast : public std::runtime_error
#endif #endif
#endif // GSL_CONTRACTS_H #endif // GSL_CONTRACTS_H

125
include/gsl_byte.h Normal file
View File

@ -0,0 +1,125 @@
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
///////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef GSL_BYTE_H
#define GSL_BYTE_H
#ifdef _MSC_VER
// MSVC 2013 workarounds
#if _MSC_VER <= 1800
// constexpr is not understood
#pragma push_macro("constexpr")
#define constexpr
// noexcept is not understood
#pragma push_macro("noexcept")
#define noexcept
#endif // _MSC_VER <= 1800
#endif // _MSC_VER
namespace gsl
{
// This is a simple definition for now that allows
// use of byte within span<> to be standards-compliant
enum class byte : unsigned char
{
};
template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept
{
return b = byte(static_cast<unsigned char>(b) << shift);
}
template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
constexpr byte operator<<(byte b, IntegerType shift) noexcept
{
return byte(static_cast<unsigned char>(b) << shift);
}
template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
constexpr byte& operator>>=(byte& b, IntegerType shift) noexcept
{
return b = byte(static_cast<unsigned char>(b) >> shift);
}
template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
constexpr byte operator>>(byte b, IntegerType shift) noexcept
{
return byte(static_cast<unsigned char>(b) >> shift);
}
constexpr byte& operator|=(byte& l, byte r) noexcept
{
return l = byte(static_cast<unsigned char>(l) | static_cast<unsigned char>(r));
}
constexpr byte operator|(byte l, byte r) noexcept
{
return byte(static_cast<unsigned char>(l) + static_cast<unsigned char>(r));
}
constexpr byte& operator&=(byte& l, byte r) noexcept
{
return l = byte(static_cast<unsigned char>(l) & static_cast<unsigned char>(r));
}
constexpr byte operator&(byte l, byte r) noexcept
{
return byte(static_cast<unsigned char>(l) & static_cast<unsigned char>(r));
}
constexpr byte& operator^=(byte& l, byte r) noexcept
{
return l = byte(static_cast<unsigned char>(l) ^ static_cast<unsigned char>(r));
}
constexpr byte operator^(byte l, byte r) noexcept
{
return byte(static_cast<unsigned char>(l) ^ static_cast<unsigned char>(r));
}
constexpr byte operator~(byte b) noexcept { return byte(~static_cast<unsigned char>(b)); }
template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
constexpr IntegerType to_integer(byte b) noexcept
{
return {b};
}
} // namespace gsl
#ifdef _MSC_VER
#if _MSC_VER <= 1800
#undef constexpr
#pragma pop_macro("constexpr")
#undef noexcept
#pragma pop_macro("noexcept")
#endif // _MSC_VER <= 1800
#endif // _MSC_VER
#endif // GSL_BYTE_H

View File

@ -21,9 +21,9 @@
#include "gsl_assert.h" // Ensures/Expects #include "gsl_assert.h" // Ensures/Expects
#include <array> #include <array>
#include <utility>
#include <type_traits>
#include <exception> #include <exception>
#include <type_traits>
#include <utility>
#ifdef _MSC_VER #ifdef _MSC_VER
@ -32,7 +32,7 @@
#define constexpr #define constexpr
#pragma warning(push) #pragma warning(push)
#pragma warning(disable: 4127) // conditional expression is constant #pragma warning(disable : 4127) // conditional expression is constant
// MSVC 2013 workarounds // MSVC 2013 workarounds
#if _MSC_VER <= 1800 #if _MSC_VER <= 1800
@ -42,13 +42,12 @@
// turn off some misguided warnings // turn off some misguided warnings
#pragma warning(push) #pragma warning(push)
#pragma warning(disable: 4351) // warns about newly introduced aggregate initializer behavior #pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
#endif // _MSC_VER <= 1800 #endif // _MSC_VER <= 1800
#endif // _MSC_VER #endif // _MSC_VER
namespace gsl namespace gsl
{ {
// //
@ -60,18 +59,20 @@ template <class F>
class final_act class final_act
{ {
public: public:
explicit final_act(F f) noexcept explicit final_act(F f) noexcept : f_(std::move(f)), invoke_(true) {}
: f_(std::move(f)), invoke_(true)
{}
final_act(final_act&& other) noexcept final_act(final_act&& other) noexcept : f_(std::move(other.f_)), invoke_(other.invoke_)
: f_(std::move(other.f_)), invoke_(other.invoke_) {
{ other.invoke_ = false; } other.invoke_ = false;
}
final_act(const final_act&) = delete; final_act(const final_act&) = delete;
final_act& operator=(const final_act&) = delete; final_act& operator=(const final_act&) = delete;
~final_act() noexcept { if (invoke_) f_(); } ~final_act() noexcept
{
if (invoke_) f_();
}
private: private:
F f_; F f_;
@ -80,34 +81,43 @@ private:
// finally() - convenience function to generate a final_act // finally() - convenience function to generate a final_act
template <class F> template <class F>
inline final_act<F> finally(const F &f) inline final_act<F> finally(const F& f) noexcept
noexcept { return final_act<F>(f); } {
return final_act<F>(f);
}
template <class F> template <class F>
inline final_act<F> finally(F &&f) noexcept inline final_act<F> finally(F&& f) noexcept
{ return final_act<F>(std::forward<F>(f)); } {
return final_act<F>(std::forward<F>(f));
}
// narrow_cast(): a searchable way to do narrowing casts of values // narrow_cast(): a searchable way to do narrowing casts of values
template<class T, class U> template <class T, class U>
inline constexpr T narrow_cast(U u) noexcept inline constexpr T narrow_cast(U u) noexcept
{ return static_cast<T>(u); } {
return static_cast<T>(u);
}
struct narrowing_error : public std::exception {}; struct narrowing_error : public std::exception
{
};
namespace details namespace details
{ {
template<class T, class U> template <class T, class U>
struct is_same_signedness : public std::integral_constant<bool, std::is_signed<T>::value == std::is_signed<U>::value> struct is_same_signedness
{}; : public std::integral_constant<bool, std::is_signed<T>::value == std::is_signed<U>::value>
{
};
} }
// narrow() : a checked version of narrow_cast() that throws if the cast changed the value // narrow() : a checked version of narrow_cast() that throws if the cast changed the value
template<class T, class U> template <class T, class U>
inline T narrow(U u) inline T narrow(U u)
{ {
T t = narrow_cast<T>(u); T t = narrow_cast<T>(u);
if (static_cast<U>(t) != u) if (static_cast<U>(t) != u) throw narrowing_error();
throw narrowing_error();
if (!details::is_same_signedness<T, U>::value && ((t < T{}) != (u < U{}))) if (!details::is_same_signedness<T, U>::value && ((t < T{}) != (u < U{})))
throw narrowing_error(); throw narrowing_error();
return t; return t;
@ -117,24 +127,35 @@ inline T narrow(U u)
// at() - Bounds-checked way of accessing static arrays, std::array, std::vector // at() - Bounds-checked way of accessing static arrays, std::array, std::vector
// //
template <class T, size_t N> template <class T, size_t N>
constexpr T& at(T(&arr)[N], size_t index) constexpr T& at(T (&arr)[N], size_t index)
{ Expects(index < N); return arr[index]; } {
Expects(index < N);
return arr[index];
}
template <class T, size_t N> template <class T, size_t N>
constexpr T& at(std::array<T, N>& arr, size_t index) constexpr T& at(std::array<T, N>& arr, size_t index)
{ Expects(index < N); return arr[index]; } {
Expects(index < N);
return arr[index];
}
template <class Cont> template <class Cont>
constexpr typename Cont::value_type& at(Cont& cont, size_t index) constexpr typename Cont::value_type& at(Cont& cont, size_t index)
{ Expects(index < cont.size()); return cont[index]; } {
Expects(index < cont.size());
return cont[index];
}
template <class T> template <class T>
constexpr const T& at(std::initializer_list<T> cont, size_t index) constexpr const T& at(std::initializer_list<T> cont, size_t index)
{ Expects(index < cont.size()); return *(cont.begin() + index); } {
Expects(index < cont.size());
return *(cont.begin() + index);
}
} // namespace gsl } // namespace gsl
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)

2229
include/multi_span.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,7 @@ else()
endif() endif()
function(add_gsl_test name) function(add_gsl_test name)
add_executable(${name} ${name}.cpp ../include/gsl.h ../include/gsl_assert.h ../include/gsl_util.h ../include/span.h ../include/string_span.h) add_executable(${name} ${name}.cpp ../include/gsl.h ../include/gsl_assert.h ../include/gsl_util.h ../include/multi_span.h ../include/span.h ../include/string_span.h)
target_link_libraries(${name} UnitTest++) target_link_libraries(${name} UnitTest++)
install(TARGETS ${name} install(TARGETS ${name}
RUNTIME DESTINATION bin RUNTIME DESTINATION bin
@ -45,6 +45,7 @@ function(add_gsl_test name)
endfunction() endfunction()
add_gsl_test(span_tests) add_gsl_test(span_tests)
add_gsl_test(multi_span_tests)
add_gsl_test(strided_span_tests) add_gsl_test(strided_span_tests)
add_gsl_test(string_span_tests) add_gsl_test(string_span_tests)
add_gsl_test(at_tests) add_gsl_test(at_tests)
@ -53,3 +54,4 @@ add_gsl_test(notnull_tests)
add_gsl_test(assertion_tests) add_gsl_test(assertion_tests)
add_gsl_test(utils_tests) add_gsl_test(utils_tests)
add_gsl_test(owner_tests) add_gsl_test(owner_tests)
add_gsl_test(byte_tests)

View File

@ -15,7 +15,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#include <UnitTest++/UnitTest++.h> #include <UnitTest++/UnitTest++.h>
#include <span.h> #include <multi_span.h>
#include <vector> #include <vector>
using namespace std; using namespace std;
@ -58,7 +58,7 @@ SUITE(bounds_test)
auto itr = bounds.begin(); auto itr = bounds.begin();
(void)itr; (void)itr;
#ifdef CONFIRM_COMPILATION_ERRORS #ifdef CONFIRM_COMPILATION_ERRORS
span<int, 4, dynamic_range, 2> av(nullptr, bounds); multi_span<int, 4, dynamic_range, 2> av(nullptr, bounds);
auto itr2 = av.cbegin(); auto itr2 = av.cbegin();

93
tests/byte_tests.cpp Normal file
View File

@ -0,0 +1,93 @@
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
///////////////////////////////////////////////////////////////////////////////
#include <UnitTest++/UnitTest++.h>
#include <gsl_byte.h>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <string>
#include <vector>
using namespace std;
using namespace gsl;
namespace
{
SUITE(byte_tests)
{
TEST(construction)
{
{
byte b = static_cast<byte>(4);
CHECK(static_cast<unsigned char>(b) == 4);
}
{
byte b = byte(12);
CHECK(static_cast<unsigned char>(b) == 12);
}
// waiting for C++17 enum class direct initializer support
//{
// byte b { 14 };
// CHECK(static_cast<unsigned char>(b) == 14);
//}
}
TEST(bitwise_operations)
{
byte b = byte(0xFF);
byte a = byte(0x00);
CHECK((b | a) == byte(0xFF));
CHECK(a == byte(0x00));
a |= b;
CHECK(a == byte(0xFF));
a = byte(0x01);
CHECK((b & a) == byte(0x01));
a &= b;
CHECK(a == byte(0x01));
CHECK((b ^ a) == byte(0xFE));
CHECK(a == byte(0x01));
a ^= b;
CHECK(a == byte(0xFE));
a = byte(0x01);
CHECK(~a == byte(0xFE));
a = byte(0xFF);
CHECK((a << 4) == byte(0xF0));
CHECK((a >> 4) == byte(0x0F));
a <<= 4;
CHECK(a == byte(0xF0));
a >>= 4;
CHECK(a == byte(0x0F));
}
}
}
int main(int, const char* []) { return UnitTest::RunAllTests(); }

1679
tests/multi_span_tests.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#include <UnitTest++/UnitTest++.h> #include <UnitTest++/UnitTest++.h>
#include <span.h> #include <multi_span.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -39,7 +39,7 @@ SUITE(strided_span_tests)
{ {
int a[30][4][5]; int a[30][4][5];
auto av = as_span(a); auto av = as_multi_span(a);
auto sub = av.section({15, 0, 0}, gsl::index<3>{2, 2, 2}); auto sub = av.section({15, 0, 0}, gsl::index<3>{2, 2, 2});
auto subsub = sub.section({1, 0, 0}, gsl::index<3>{1, 1, 1}); auto subsub = sub.section({1, 0, 0}, gsl::index<3>{1, 1, 1});
(void)subsub; (void)subsub;
@ -49,7 +49,7 @@ SUITE(strided_span_tests)
{ {
std::vector<int> data(5 * 10); std::vector<int> data(5 * 10);
std::iota(begin(data), end(data), 0); std::iota(begin(data), end(data), 0);
const span<int, 5, 10> av = as_span(span<int>{data}, dim<5>(), dim<10>()); const multi_span<int, 5, 10> av = as_multi_span(multi_span<int>{data}, dim<5>(), dim<10>());
strided_span<int, 2> av_section_1 = av.section({ 1, 2 }, { 3, 4 }); strided_span<int, 2> av_section_1 = av.section({ 1, 2 }, { 3, 4 });
CHECK((av_section_1[{0, 0}] == 12)); CHECK((av_section_1[{0, 0}] == 12));
@ -87,13 +87,13 @@ SUITE(strided_span_tests)
CHECK((sav3[{0, 0}] == 1 && sav3[{0, 1}] == 3 && sav3[{1, 0}] == 7)); CHECK((sav3[{0, 0}] == 1 && sav3[{0, 1}] == 3 && sav3[{1, 0}] == 7));
} }
// Check span constructor // Check multi_span constructor
{ {
int arr[] = { 1, 2 }; int arr[] = { 1, 2 };
// From non-cv-qualified source // From non-cv-qualified source
{ {
const span<int> src = arr; const multi_span<int> src = arr;
strided_span<int, 1> sav{ src, {2, 1} }; strided_span<int, 1> sav{ src, {2, 1} };
CHECK(sav.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
@ -102,9 +102,9 @@ SUITE(strided_span_tests)
#if _MSC_VER > 1800 #if _MSC_VER > 1800
//strided_span<const int, 1> sav_c{ {src}, {2, 1} }; //strided_span<const int, 1> sav_c{ {src}, {2, 1} };
strided_span<const int, 1> sav_c{ span<const int>{src}, strided_bounds<1>{2, 1} }; strided_span<const int, 1> sav_c{ multi_span<const int>{src}, strided_bounds<1>{2, 1} };
#else #else
strided_span<const int, 1> sav_c{ span<const int>{src}, strided_bounds<1>{2, 1} }; strided_span<const int, 1> sav_c{ multi_span<const int>{src}, strided_bounds<1>{2, 1} };
#endif #endif
CHECK(sav_c.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_c.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav_c.bounds().strides() == index<1>{ 1 }); CHECK(sav_c.bounds().strides() == index<1>{ 1 });
@ -113,7 +113,7 @@ SUITE(strided_span_tests)
#if _MSC_VER > 1800 #if _MSC_VER > 1800
strided_span<volatile int, 1> sav_v{ src, {2, 1} }; strided_span<volatile int, 1> sav_v{ src, {2, 1} };
#else #else
strided_span<volatile int, 1> sav_v{ span<volatile int>{src}, strided_bounds<1>{2, 1} }; strided_span<volatile int, 1> sav_v{ multi_span<volatile int>{src}, strided_bounds<1>{2, 1} };
#endif #endif
CHECK(sav_v.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_v.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav_v.bounds().strides() == index<1>{ 1 }); CHECK(sav_v.bounds().strides() == index<1>{ 1 });
@ -122,7 +122,7 @@ SUITE(strided_span_tests)
#if _MSC_VER > 1800 #if _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{ src, {2, 1} }; strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
#else #else
strided_span<const volatile int, 1> sav_cv{ span<const volatile int>{src}, strided_bounds<1>{2, 1} }; strided_span<const volatile int, 1> sav_cv{ multi_span<const volatile int>{src}, strided_bounds<1>{2, 1} };
#endif #endif
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav_cv.bounds().strides() == index<1>{ 1 }); CHECK(sav_cv.bounds().strides() == index<1>{ 1 });
@ -131,7 +131,7 @@ SUITE(strided_span_tests)
// From const-qualified source // From const-qualified source
{ {
const span<const int> src{ arr }; const multi_span<const int> src{ arr };
strided_span<const int, 1> sav_c{ src, {2, 1} }; strided_span<const int, 1> sav_c{ src, {2, 1} };
CHECK(sav_c.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_c.bounds().index_bounds() == index<1>{ 2 });
@ -141,7 +141,7 @@ SUITE(strided_span_tests)
#if _MSC_VER > 1800 #if _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{ src, {2, 1} }; strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
#else #else
strided_span<const volatile int, 1> sav_cv{ span<const volatile int>{src}, strided_bounds<1>{2, 1} }; strided_span<const volatile int, 1> sav_cv{ multi_span<const volatile int>{src}, strided_bounds<1>{2, 1} };
#endif #endif
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
@ -151,7 +151,7 @@ SUITE(strided_span_tests)
// From volatile-qualified source // From volatile-qualified source
{ {
const span<volatile int> src{ arr }; const multi_span<volatile int> src{ arr };
strided_span<volatile int, 1> sav_v{ src, {2, 1} }; strided_span<volatile int, 1> sav_v{ src, {2, 1} };
CHECK(sav_v.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_v.bounds().index_bounds() == index<1>{ 2 });
@ -161,7 +161,7 @@ SUITE(strided_span_tests)
#if _MSC_VER > 1800 #if _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{ src, {2, 1} }; strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
#else #else
strided_span<const volatile int, 1> sav_cv{ span<const volatile int>{src}, strided_bounds<1>{2, 1} }; strided_span<const volatile int, 1> sav_cv{ multi_span<const volatile int>{src}, strided_bounds<1>{2, 1} };
#endif #endif
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav_cv.bounds().strides() == index<1>{ 1 }); CHECK(sav_cv.bounds().strides() == index<1>{ 1 });
@ -170,7 +170,7 @@ SUITE(strided_span_tests)
// From cv-qualified source // From cv-qualified source
{ {
const span<const volatile int> src{ arr }; const multi_span<const volatile int> src{ arr };
strided_span<const volatile int, 1> sav_cv{ src, {2, 1} }; strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 }); CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
@ -183,11 +183,11 @@ SUITE(strided_span_tests)
{ {
int arr[2] = { 4, 5 }; int arr[2] = { 4, 5 };
const span<int, 2> av(arr, 2); const multi_span<int, 2> av(arr, 2);
span<const int, 2> av2{ av }; multi_span<const int, 2> av2{ av };
CHECK(av2[1] == 5); CHECK(av2[1] == 5);
static_assert(std::is_convertible<const span<int, 2>, span<const int, 2>>::value, "ctor is not implicit!"); static_assert(std::is_convertible<const multi_span<int, 2>, multi_span<const int, 2>>::value, "ctor is not implicit!");
const strided_span<int, 1> src{ arr, {2, 1} }; const strided_span<int, 1> src{ arr, {2, 1} };
strided_span<const int, 1> sav{ src }; strided_span<const int, 1> sav{ src };
@ -258,13 +258,13 @@ SUITE(strided_span_tests)
{ {
std::vector<int> data(5 * 10); std::vector<int> data(5 * 10);
std::iota(begin(data), end(data), 0); std::iota(begin(data), end(data), 0);
const span<int, 5, 10> src = as_span(span<int>{data}, dim<5>(), dim<10>()); const multi_span<int, 5, 10> src = as_multi_span(multi_span<int>{data}, dim<5>(), dim<10>());
const strided_span<int, 2> sav{ src, {{5, 10}, {10, 1}} }; const strided_span<int, 2> sav{ src, {{5, 10}, {10, 1}} };
#ifdef CONFIRM_COMPILATION_ERRORS #ifdef CONFIRM_COMPILATION_ERRORS
const strided_span<const int, 2> csav{ {src},{ { 5, 10 },{ 10, 1 } } }; const strided_span<const int, 2> csav{ {src},{ { 5, 10 },{ 10, 1 } } };
#endif #endif
const strided_span<const int, 2> csav{ span<const int, 5, 10>{ src }, { { 5, 10 },{ 10, 1 } } }; const strided_span<const int, 2> csav{ multi_span<const int, 5, 10>{ src }, { { 5, 10 },{ 10, 1 } } };
strided_span<int, 1> sav_sl = sav[2]; strided_span<int, 1> sav_sl = sav[2];
CHECK(sav_sl[0] == 20); CHECK(sav_sl[0] == 20);
@ -317,7 +317,7 @@ SUITE(strided_span_tests)
TEST(strided_span_bounds) TEST(strided_span_bounds)
{ {
int arr[] = { 0, 1, 2, 3 }; int arr[] = { 0, 1, 2, 3 };
span<int> av(arr); multi_span<int> av(arr);
{ {
// incorrect sections // incorrect sections
@ -413,18 +413,18 @@ SUITE(strided_span_tests)
strided_span<int, 1> sav2{ arr, { 1,1,1 } }; strided_span<int, 1> sav2{ arr, { 1,1,1 } };
strided_span<int, 1> sav3{ av, { 1 } }; strided_span<int, 1> sav3{ av, { 1 } };
strided_span<int, 1> sav4{ av, { 1,1,1 } }; strided_span<int, 1> sav4{ av, { 1,1,1 } };
strided_span<int, 2> sav5{ av.as_span(dim<2>(), dim<2>()), { 1 } }; strided_span<int, 2> sav5{ av.as_multi_span(dim<2>(), dim<2>()), { 1 } };
strided_span<int, 2> sav6{ av.as_span(dim<2>(), dim<2>()), { 1,1,1 } }; strided_span<int, 2> sav6{ av.as_multi_span(dim<2>(), dim<2>()), { 1,1,1 } };
strided_span<int, 2> sav7{ av.as_span(dim<2>(), dim<2>()), { { 1,1 },{ 1,1 },{ 1,1 } } }; strided_span<int, 2> sav7{ av.as_multi_span(dim<2>(), dim<2>()), { { 1,1 },{ 1,1 },{ 1,1 } } };
index<1> index{ 0, 1 }; index<1> index{ 0, 1 };
strided_span<int, 1> sav8{ arr,{ 1,{ 1,1 } } }; strided_span<int, 1> sav8{ arr,{ 1,{ 1,1 } } };
strided_span<int, 1> sav9{ arr,{ { 1,1 },{ 1,1 } } }; strided_span<int, 1> sav9{ arr,{ { 1,1 },{ 1,1 } } };
strided_span<int, 1> sav10{ av,{ 1,{ 1,1 } } }; strided_span<int, 1> sav10{ av,{ 1,{ 1,1 } } };
strided_span<int, 1> sav11{ av,{ { 1,1 },{ 1,1 } } }; strided_span<int, 1> sav11{ av,{ { 1,1 },{ 1,1 } } };
strided_span<int, 2> sav12{ av.as_span(dim<2>(), dim<2>()),{ { 1 },{ 1 } } }; strided_span<int, 2> sav12{ av.as_multi_span(dim<2>(), dim<2>()),{ { 1 },{ 1 } } };
strided_span<int, 2> sav13{ av.as_span(dim<2>(), dim<2>()),{ { 1 },{ 1,1,1 } } }; strided_span<int, 2> sav13{ av.as_multi_span(dim<2>(), dim<2>()),{ { 1 },{ 1,1,1 } } };
strided_span<int, 2> sav14{ av.as_span(dim<2>(), dim<2>()),{ { 1,1,1 },{ 1 } } }; strided_span<int, 2> sav14{ av.as_multi_span(dim<2>(), dim<2>()),{ { 1,1,1 },{ 1 } } };
} }
#endif #endif
} }
@ -432,7 +432,7 @@ SUITE(strided_span_tests)
TEST(strided_span_type_conversion) TEST(strided_span_type_conversion)
{ {
int arr[] = { 0, 1, 2, 3 }; int arr[] = { 0, 1, 2, 3 };
span<int> av(arr); multi_span<int> av(arr);
{ {
strided_span<int, 1> sav{ av.data(), av.size(), { av.size() / 2, 2 } }; strided_span<int, 1> sav{ av.data(), av.size(), { av.size() / 2, 2 } };
@ -447,7 +447,7 @@ SUITE(strided_span_tests)
#endif #endif
} }
span<const byte, dynamic_range> bytes = as_bytes(av); multi_span<const byte, dynamic_range> bytes = as_bytes(av);
// retype strided array with regular strides - from raw data // retype strided array with regular strides - from raw data
{ {
@ -460,10 +460,10 @@ SUITE(strided_span_tests)
CHECK_THROW(sav3[0][1], fail_fast); CHECK_THROW(sav3[0][1], fail_fast);
} }
// retype strided array with regular strides - from span // retype strided array with regular strides - from multi_span
{ {
strided_bounds<2> bounds{ { 2, bytes.size() / 4 }, { bytes.size() / 2, 1 } }; strided_bounds<2> bounds{ { 2, bytes.size() / 4 }, { bytes.size() / 2, 1 } };
span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2)); multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim<>(bytes.size() / 2));
strided_span<const byte, 2> sav2{ bytes2, bounds }; strided_span<const byte, 2> sav2{ bytes2, bounds };
strided_span<int, 2> sav3 = sav2.as_strided_span<int>(); strided_span<int, 2> sav3 = sav2.as_strided_span<int>();
CHECK(sav3[0][0] == 0); CHECK(sav3[0][0] == 0);
@ -475,7 +475,7 @@ SUITE(strided_span_tests)
// retype strided array with not enough elements - last dimension of the array is too small // retype strided array with not enough elements - last dimension of the array is too small
{ {
strided_bounds<2> bounds{ { 4,2 },{ 4, 1 } }; strided_bounds<2> bounds{ { 4,2 },{ 4, 1 } };
span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2)); multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim<>(bytes.size() / 2));
strided_span<const byte, 2> sav2{ bytes2, bounds }; strided_span<const byte, 2> sav2{ bytes2, bounds };
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast); CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
} }
@ -483,7 +483,7 @@ SUITE(strided_span_tests)
// retype strided array with not enough elements - strides are too small // retype strided array with not enough elements - strides are too small
{ {
strided_bounds<2> bounds{ { 4,2 },{ 2, 1 } }; strided_bounds<2> bounds{ { 4,2 },{ 2, 1 } };
span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2)); multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim<>(bytes.size() / 2));
strided_span<const byte, 2> sav2{ bytes2, bounds }; strided_span<const byte, 2> sav2{ bytes2, bounds };
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast); CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
} }
@ -491,7 +491,7 @@ SUITE(strided_span_tests)
// retype strided array with not enough elements - last dimension does not divide by the new typesize // retype strided array with not enough elements - last dimension does not divide by the new typesize
{ {
strided_bounds<2> bounds{ { 2,6 },{ 4, 1 } }; strided_bounds<2> bounds{ { 2,6 },{ 4, 1 } };
span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2)); multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim<>(bytes.size() / 2));
strided_span<const byte, 2> sav2{ bytes2, bounds }; strided_span<const byte, 2> sav2{ bytes2, bounds };
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast); CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
} }
@ -499,7 +499,7 @@ SUITE(strided_span_tests)
// retype strided array with not enough elements - strides does not divide by the new typesize // retype strided array with not enough elements - strides does not divide by the new typesize
{ {
strided_bounds<2> bounds{ { 2, 1 },{ 6, 1 } }; strided_bounds<2> bounds{ { 2, 1 },{ 6, 1 } };
span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2)); multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim<>(bytes.size() / 2));
strided_span<const byte, 2> sav2{ bytes2, bounds }; strided_span<const byte, 2> sav2{ bytes2, bounds };
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast); CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
} }
@ -511,7 +511,7 @@ SUITE(strided_span_tests)
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast); CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
} }
// retype strided array with irregular strides - from span // retype strided array with irregular strides - from multi_span
{ {
strided_bounds<1> bounds{ bytes.size() / 2, 2 }; strided_bounds<1> bounds{ bytes.size() / 2, 2 };
strided_span<const byte, 1> sav2{ bytes, bounds }; strided_span<const byte, 1> sav2{ bytes, bounds };
@ -522,7 +522,7 @@ SUITE(strided_span_tests)
TEST(empty_strided_spans) TEST(empty_strided_spans)
{ {
{ {
span<int, 0> empty_av(nullptr); multi_span<int, 0> empty_av(nullptr);
strided_span<int, 1> empty_sav{ empty_av, { 0, 1 } }; strided_span<int, 1> empty_sav{ empty_av, { 0, 1 } };
CHECK(empty_sav.bounds().index_bounds() == index<1>{ 0 }); CHECK(empty_sav.bounds().index_bounds() == index<1>{ 0 });
@ -553,7 +553,7 @@ SUITE(strided_span_tests)
} }
} }
void iterate_every_other_element(span<int, dynamic_range> av) void iterate_every_other_element(multi_span<int, dynamic_range> av)
{ {
// pick every other element // pick every other element
@ -586,13 +586,13 @@ SUITE(strided_span_tests)
// static bounds // static bounds
{ {
span<int, 8> av(arr, 8); multi_span<int, 8> av(arr, 8);
iterate_every_other_element(av); iterate_every_other_element(av);
} }
// dynamic bounds // dynamic bounds
{ {
span<int, dynamic_range> av(arr, 8); multi_span<int, dynamic_range> av(arr, 8);
iterate_every_other_element(av); iterate_every_other_element(av);
} }
} }
@ -606,13 +606,13 @@ SUITE(strided_span_tests)
arr[2 * i + 1] = i; arr[2 * i + 1] = i;
} }
auto av = as_span(arr, 8); auto av = as_multi_span(arr, 8);
iterate_every_other_element(av); iterate_every_other_element(av);
delete[] arr; delete[] arr;
} }
void iterate_second_slice(span<int, dynamic_range, dynamic_range, dynamic_range> av) void iterate_second_slice(multi_span<int, dynamic_range, dynamic_range, dynamic_range> av)
{ {
int expected[6] = {2,3,10,11,18,19}; int expected[6] = {2,3,10,11,18,19};
auto section = av.section({0,1,0}, {3,1,2}); auto section = av.section({0,1,0}, {3,1,2});
@ -653,7 +653,7 @@ SUITE(strided_span_tests)
} }
{ {
span<int, 3, 4, 2> av = arr; multi_span<int, 3, 4, 2> av = arr;
iterate_second_slice(av); iterate_second_slice(av);
} }
} }
@ -670,22 +670,22 @@ SUITE(strided_span_tests)
} }
{ {
auto av = as_span(as_span(arr, 24), dim<3>(), dim<4>(), dim<2>()); auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<4>(), dim<2>());
iterate_second_slice(av); iterate_second_slice(av);
} }
{ {
auto av = as_span(as_span(arr, 24), dim<>(3), dim<4>(), dim<2>()); auto av = as_multi_span(as_multi_span(arr, 24), dim<>(3), dim<4>(), dim<2>());
iterate_second_slice(av); iterate_second_slice(av);
} }
{ {
auto av = as_span(as_span(arr, 24), dim<3>(), dim<>(4), dim<2>()); auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<>(4), dim<2>());
iterate_second_slice(av); iterate_second_slice(av);
} }
{ {
auto av = as_span(as_span(arr, 24), dim<3>(), dim<4>(), dim<>(2)); auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<4>(), dim<>(2));
iterate_second_slice(av); iterate_second_slice(av);
} }
delete[] arr; delete[] arr;
@ -693,7 +693,7 @@ SUITE(strided_span_tests)
TEST(strided_span_conversion) TEST(strided_span_conversion)
{ {
// get an span of 'c' values from the list of X's // get an multi_span of 'c' values from the list of X's
struct X { int a; int b; int c; }; struct X { int a; int b; int c; };
@ -704,7 +704,7 @@ SUITE(strided_span_tests)
auto d1 = sizeof(int) * 12 / d2; auto d1 = sizeof(int) * 12 / d2;
// convert to 4x12 array of bytes // convert to 4x12 array of bytes
auto av = as_span(as_bytes(as_span(arr, 4)), dim<>(d1), dim<>(d2)); auto av = as_multi_span(as_bytes(as_multi_span(arr, 4)), dim<>(d1), dim<>(d2));
CHECK(av.bounds().index_bounds()[0] == 4); CHECK(av.bounds().index_bounds()[0] == 4);
CHECK(av.bounds().index_bounds()[1] == 12); CHECK(av.bounds().index_bounds()[1] == 12);

View File

@ -40,14 +40,14 @@ SUITE(string_span_tests)
{ {
std::string s = "Hello there world"; std::string s = "Hello there world";
cstring_span<> v = s; cstring_span<> v = s;
CHECK(v.length() == static_cast<cstring_span<>::size_type>(s.length())); CHECK(v.length() == static_cast<cstring_span<>::index_type>(s.length()));
} }
TEST(TestConstructFromStdVector) TEST(TestConstructFromStdVector)
{ {
std::vector<char> vec(5, 'h'); std::vector<char> vec(5, 'h');
string_span<> v = vec; string_span<> v {vec};
CHECK(v.length() == static_cast<string_span<>::size_type>(vec.size())); CHECK(v.length() == static_cast<string_span<>::index_type>(vec.size()));
} }
TEST(TestStackArrayConstruction) TEST(TestStackArrayConstruction)
@ -109,7 +109,7 @@ SUITE(string_span_tests)
char stack_string[] = "Hello"; char stack_string[] = "Hello";
cstring_span<> v = ensure_z(stack_string); cstring_span<> v = ensure_z(stack_string);
auto s2 = gsl::to_string(v); auto s2 = gsl::to_string(v);
CHECK(static_cast<cstring_span<>::size_type>(s2.length()) == v.length()); CHECK(static_cast<cstring_span<>::index_type>(s2.length()) == v.length());
CHECK(s2.length() == 5); CHECK(s2.length() == 5);
} }
@ -746,7 +746,7 @@ SUITE(string_span_tests)
T create() { return T{}; } T create() { return T{}; }
template <class T> template <class T>
void use(basic_string_span<T, gsl::dynamic_range> s) {} void use(basic_string_span<T, gsl::dynamic_extent> s) {}
TEST(MoveConstructors) TEST(MoveConstructors)
{ {

View File

@ -103,7 +103,7 @@ SUITE(utils_tests)
CHECK(narrow<uint32_t>(int32_t(0)) == 0); CHECK(narrow<uint32_t>(int32_t(0)) == 0);
CHECK(narrow<uint32_t>(int32_t(1)) == 1); CHECK(narrow<uint32_t>(int32_t(1)) == 1);
CHECK(narrow<uint32_t>(int32_max) == int32_max); CHECK(narrow<uint32_t>(int32_max) == static_cast<uint32_t>(int32_max));
CHECK_THROW(narrow<uint32_t>(int32_t(-1)), narrowing_error); CHECK_THROW(narrow<uint32_t>(int32_t(-1)), narrowing_error);
CHECK_THROW(narrow<uint32_t>(int32_min), narrowing_error); CHECK_THROW(narrow<uint32_t>(int32_min), narrowing_error);