Cleanup include structure, constexpr and noexcept compiler workarounds.

* Nest "gsl" directory inside a new "include" directory.

* Cleanup the _MSC_VER conditionals a bit; use constexpr on VS2017+.

* Don't #define noexcept on non-Microsoft implementations.

* Workaround VS2017 bug in multi_span. (Also implement == and != for static_bounds_dynamic_range_t because I'm an EoP semantic soundness snob.)

Fixes #441.
This commit is contained in:
Casey Carter 2017-02-07 15:59:37 -08:00 committed by Neil MacIntosh
parent 96eaf274f8
commit 4e8f95b418
14 changed files with 585 additions and 678 deletions

2
.gitignore vendored
View File

@ -11,3 +11,5 @@ tests/*tests.dir
Testing/Temporary/*.* Testing/Temporary/*.*
CMakeCache.txt CMakeCache.txt
*.suo *.suo
.vs/
.vscode/

View File

@ -2,25 +2,10 @@ cmake_minimum_required(VERSION 2.8.7)
project(GSL CXX) project(GSL CXX)
set(GSL_HEADERS install(
"gsl/gsl" DIRECTORY include/gsl
"gsl/gsl_assert" DESTINATION include
"gsl/gsl_byte"
"gsl/gsl_util"
"gsl/multi_span"
"gsl/span"
"gsl/string_span"
"gsl/gsl_algorithm"
)
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
)
install(FILES ${GSL_HEADERS}
DESTINATION include/gsl
) )
enable_testing() enable_testing()
add_subdirectory(tests) add_subdirectory(tests)

View File

@ -19,16 +19,14 @@
#ifndef GSL_GSL_H #ifndef GSL_GSL_H
#define GSL_GSL_H #define GSL_GSL_H
#include "gsl_assert" // Ensures/Expects #include <gsl/gsl_assert> // Ensures/Expects
#include "gsl_util" // finally()/narrow()/narrow_cast()... #include <gsl/gsl_util> // finally()/narrow()/narrow_cast()...
#include "multi_span" // multi_span, strided_span... #include <gsl/multi_span> // multi_span, strided_span...
#include "span" // span #include <gsl/span> // span
#include "string_span" // zstring, string_span, zstring_builder... #include <gsl/string_span> // zstring, string_span, zstring_builder...
#include <memory> #include <memory>
#ifdef _MSC_VER #if defined(_MSC_VER) && _MSC_VER < 1910
// No MSVC does constexpr fully yet
#pragma push_macro("constexpr") #pragma push_macro("constexpr")
#define constexpr /*constexpr*/ #define constexpr /*constexpr*/
@ -41,10 +39,8 @@
// 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 // defined(_MSC_VER) && _MSC_VER < 1910
#endif // _MSC_VER
namespace gsl namespace gsl
{ {
@ -153,20 +149,16 @@ struct hash<gsl::not_null<T>>
} // namespace std } // namespace std
#ifdef _MSC_VER #if defined(_MSC_VER) && _MSC_VER < 1910
#undef constexpr #undef constexpr
#pragma pop_macro("constexpr") #pragma pop_macro("constexpr")
#if _MSC_VER <= 1800 #if _MSC_VER <= 1800
#undef noexcept #undef noexcept
#pragma pop_macro("noexcept") #pragma pop_macro("noexcept")
#pragma warning(pop) #pragma warning(pop)
#endif // _MSC_VER <= 1800 #endif // _MSC_VER <= 1800
#endif // defined(_MSC_VER) && _MSC_VER < 1910
#endif // _MSC_VER
#endif // GSL_GSL_H #endif // GSL_GSL_H

View File

@ -19,11 +19,10 @@
#ifndef GSL_ALGORITHM_H #ifndef GSL_ALGORITHM_H
#define GSL_ALGORITHM_H #define GSL_ALGORITHM_H
#include "span" #include <gsl/span>
#include <algorithm> #include <algorithm>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(push) #pragma warning(push)
// turn off some warnings that are noisy about our Expects statements // turn off some warnings that are noisy about our Expects statements
@ -33,7 +32,6 @@
// so people aren't annoyed by them when running the tool. // so people aren't annoyed by them when running the tool.
// more targeted suppressions will be added in a future update to the GSL // more targeted suppressions will be added in a future update to the GSL
#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495) #pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
#endif // _MSC_VER #endif // _MSC_VER
namespace gsl namespace gsl

View File

@ -30,7 +30,7 @@
// 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) ^ \ #if !(defined(GSL_THROW_ON_CONTRACT_VIOLATION) || defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) || \
defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)) defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION))
#define GSL_TERMINATE_ON_CONTRACT_VIOLATION #define GSL_TERMINATE_ON_CONTRACT_VIOLATION
#endif #endif

View File

@ -22,7 +22,6 @@
#include <type_traits> #include <type_traits>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(push) #pragma warning(push)
// don't warn about function style casts in byte related operators // don't warn about function style casts in byte related operators
@ -30,17 +29,14 @@
// MSVC 2013 workarounds // MSVC 2013 workarounds
#if _MSC_VER <= 1800 #if _MSC_VER <= 1800
// constexpr is not understood // constexpr is not understood
#pragma push_macro("constexpr") #pragma push_macro("constexpr")
#define constexpr /*constexpr*/ #define constexpr inline
// noexcept is not understood // noexcept is not understood
#pragma push_macro("noexcept") #pragma push_macro("noexcept")
#define noexcept /*noexcept*/ #define noexcept /*noexcept*/
#endif // _MSC_VER <= 1800 #endif // _MSC_VER <= 1800
#endif // _MSC_VER #endif // _MSC_VER
namespace gsl namespace gsl
@ -145,19 +141,15 @@ inline constexpr byte to_byte() noexcept
} // namespace gsl } // namespace gsl
#ifdef _MSC_VER #ifdef _MSC_VER
#if _MSC_VER <= 1800 #if _MSC_VER <= 1800
#undef constexpr #undef constexpr
#pragma pop_macro("constexpr") #pragma pop_macro("constexpr")
#undef noexcept #undef noexcept
#pragma pop_macro("noexcept") #pragma pop_macro("noexcept")
#endif // _MSC_VER <= 1800 #endif // _MSC_VER <= 1800
#pragma warning(pop) #pragma warning(pop)
#endif // _MSC_VER #endif // _MSC_VER
#endif // GSL_BYTE_H #endif // GSL_BYTE_H

View File

@ -19,33 +19,28 @@
#ifndef GSL_UTIL_H #ifndef GSL_UTIL_H
#define GSL_UTIL_H #define GSL_UTIL_H
#include "gsl_assert" // Ensures/Expects #include <gsl/gsl_assert> // Ensures/Expects
#include <array> #include <array>
#include <exception> #include <exception>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#ifdef _MSC_VER #if defined(_MSC_VER)
// No MSVC does constexpr fully yet
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
#pragma warning(push) #pragma warning(push)
#pragma warning(disable : 4127) // conditional expression is constant #pragma warning(disable : 4127) // conditional expression is constant
#if _MSC_VER < 1910
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
// MSVC 2013 workarounds // MSVC 2013 workarounds
#if _MSC_VER <= 1800 #if _MSC_VER <= 1800
// noexcept is not understood // noexcept is not understood
#pragma push_macro("noexcept") #pragma push_macro("noexcept")
#define noexcept /*noexcept*/ #define noexcept /*noexcept*/
// turn off some misguided warnings // turn off some misguided warnings
#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 < 1910
#endif // _MSC_VER #endif // _MSC_VER
namespace gsl namespace gsl
@ -135,28 +130,28 @@ 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], std::ptrdiff_t index) inline constexpr T& at(T (&arr)[N], std::ptrdiff_t index)
{ {
Expects(index >= 0 && index < narrow_cast<std::ptrdiff_t>(N)); Expects(index >= 0 && index < narrow_cast<std::ptrdiff_t>(N));
return arr[static_cast<size_t>(index)]; return arr[static_cast<size_t>(index)];
} }
template <class T, size_t N> template <class T, size_t N>
constexpr T& at(std::array<T, N>& arr, std::ptrdiff_t index) inline constexpr T& at(std::array<T, N>& arr, std::ptrdiff_t index)
{ {
Expects(index >= 0 && index < narrow_cast<std::ptrdiff_t>(N)); Expects(index >= 0 && index < narrow_cast<std::ptrdiff_t>(N));
return arr[static_cast<size_t>(index)]; return arr[static_cast<size_t>(index)];
} }
template <class Cont> template <class Cont>
constexpr typename Cont::value_type& at(Cont& cont, std::ptrdiff_t index) inline constexpr typename Cont::value_type& at(Cont& cont, std::ptrdiff_t index)
{ {
Expects(index >= 0 && index < narrow_cast<std::ptrdiff_t>(cont.size())); Expects(index >= 0 && index < narrow_cast<std::ptrdiff_t>(cont.size()));
return cont[static_cast<typename Cont::size_type>(index)]; return cont[static_cast<typename Cont::size_type>(index)];
} }
template <class T> template <class T>
constexpr const T& at(std::initializer_list<T> cont, std::ptrdiff_t index) inline constexpr const T& at(std::initializer_list<T> cont, std::ptrdiff_t index)
{ {
Expects(index >= 0 && index < narrow_cast<std::ptrdiff_t>(cont.size())); Expects(index >= 0 && index < narrow_cast<std::ptrdiff_t>(cont.size()));
return *(cont.begin() + index); return *(cont.begin() + index);
@ -164,22 +159,17 @@ constexpr const T& at(std::initializer_list<T> cont, std::ptrdiff_t index)
} // namespace gsl } // namespace gsl
#ifdef _MSC_VER #if defined(_MSC_VER)
#if _MSC_VER < 1910
#pragma warning(pop)
#undef constexpr #undef constexpr
#pragma pop_macro("constexpr") #pragma pop_macro("constexpr")
#if _MSC_VER <= 1800 #if _MSC_VER <= 1800
#undef noexcept #undef noexcept
#pragma pop_macro("noexcept") #pragma pop_macro("noexcept")
#pragma warning(pop)
#endif // _MSC_VER <= 1800 #endif // _MSC_VER <= 1800
#endif // _MSC_VER < 1910
#pragma warning(pop)
#endif // _MSC_VER #endif // _MSC_VER
#endif // GSL_UTIL_H #endif // GSL_UTIL_H

File diff suppressed because it is too large Load Diff

View File

@ -20,9 +20,9 @@
#ifndef GSL_SPAN_H #ifndef GSL_SPAN_H
#define GSL_SPAN_H #define GSL_SPAN_H
#include "gsl_assert" #include <gsl/gsl_assert>
#include "gsl_byte" #include <gsl/gsl_byte>
#include "gsl_util" #include <gsl/gsl_util>
#include <array> #include <array>
#include <iterator> #include <iterator>
#include <limits> #include <limits>
@ -32,7 +32,6 @@
#include <memory> #include <memory>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(push) #pragma warning(push)
// turn off some warnings that are noisy about our Expects statements // turn off some warnings that are noisy about our Expects statements
@ -43,43 +42,34 @@
// more targeted suppressions will be added in a future update to the GSL // more targeted suppressions will be added in a future update to the GSL
#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495) #pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
// No MSVC does constexpr fully yet #if _MSC_VER < 1910
#pragma push_macro("constexpr") #pragma push_macro("constexpr")
#define constexpr /*constexpr*/ #define constexpr /*constexpr*/
// VS 2013 workarounds // VS 2013 workarounds
#if _MSC_VER <= 1800 #if _MSC_VER <= 1800
#define GSL_MSVC_HAS_VARIADIC_CTOR_BUG #define GSL_MSVC_HAS_VARIADIC_CTOR_BUG
#define GSL_MSVC_NO_DEFAULT_MOVE_CTOR #define GSL_MSVC_NO_DEFAULT_MOVE_CTOR
#define GSL_MSVC_NO_CPP14_STD_EQUAL #define GSL_MSVC_NO_CPP14_STD_EQUAL
// noexcept is not understood // noexcept is not understood
#ifndef GSL_THROW_ON_CONTRACT_VIOLATION
#pragma push_macro("noexcept") #pragma push_macro("noexcept")
#define noexcept /*noexcept*/ #define noexcept /*noexcept*/
#endif
#pragma push_macro("alignof") #pragma push_macro("alignof")
#define alignof __alignof #define alignof __alignof
// turn off some misguided warnings // turn off some misguided warnings
#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
#pragma warning(disable : 4512) // warns that assignment op could not be generated #pragma warning(disable : 4512) // warns that assignment op could not be generated
#endif // _MSC_VER <= 1800 #endif // _MSC_VER <= 1800
#endif // _MSC_VER < 1910
#endif // _MSC_VER #endif // _MSC_VER
#ifdef GSL_THROW_ON_CONTRACT_VIOLATION #ifdef GSL_THROW_ON_CONTRACT_VIOLATION
#define GSL_NOEXCEPT /*noexcept*/
#ifdef _MSC_VER #else
#pragma push_macro("noexcept") #define GSL_NOEXCEPT noexcept
#endif
#define noexcept /*noexcept*/
#endif // GSL_THROW_ON_CONTRACT_VIOLATION #endif // GSL_THROW_ON_CONTRACT_VIOLATION
namespace gsl namespace gsl
@ -150,7 +140,7 @@ namespace details
std::conditional_t<IsConst, const element_type_, element_type_> &; std::conditional_t<IsConst, const element_type_, element_type_> &;
using pointer = std::add_pointer_t<reference>; using pointer = std::add_pointer_t<reference>;
constexpr span_iterator() noexcept : span_iterator(nullptr, 0) {} constexpr span_iterator() GSL_NOEXCEPT : span_iterator(nullptr, 0) {}
constexpr span_iterator(const Span* span, typename Span::index_type index) constexpr span_iterator(const Span* span, typename Span::index_type index)
: span_(span), index_(index) : span_(span), index_(index)
@ -159,12 +149,12 @@ namespace details
} }
friend class span_iterator<Span, true>; friend class span_iterator<Span, true>;
constexpr span_iterator(const span_iterator<Span, false>& other) noexcept constexpr span_iterator(const span_iterator<Span, false>& other) GSL_NOEXCEPT
: span_iterator(other.span_, other.index_) : span_iterator(other.span_, other.index_)
{ {
} }
constexpr span_iterator<Span, IsConst>& operator=(const span_iterator<Span, IsConst>&) noexcept = default; constexpr span_iterator<Span, IsConst>& operator=(const span_iterator<Span, IsConst>&) GSL_NOEXCEPT = default;
constexpr reference operator*() const constexpr reference operator*() const
{ {
@ -185,7 +175,7 @@ namespace details
return *this; return *this;
} }
constexpr span_iterator operator++(int) noexcept constexpr span_iterator operator++(int) GSL_NOEXCEPT
{ {
auto ret = *this; auto ret = *this;
++(*this); ++(*this);
@ -199,14 +189,14 @@ namespace details
return *this; return *this;
} }
constexpr span_iterator operator--(int) noexcept constexpr span_iterator operator--(int) GSL_NOEXCEPT
{ {
auto ret = *this; auto ret = *this;
--(*this); --(*this);
return ret; return ret;
} }
constexpr span_iterator operator+(difference_type n) const noexcept constexpr span_iterator operator+(difference_type n) const GSL_NOEXCEPT
{ {
auto ret = *this; auto ret = *this;
return ret += n; return ret += n;
@ -219,13 +209,13 @@ namespace details
return *this; return *this;
} }
constexpr span_iterator operator-(difference_type n) const noexcept constexpr span_iterator operator-(difference_type n) const GSL_NOEXCEPT
{ {
auto ret = *this; auto ret = *this;
return ret -= n; return ret -= n;
} }
constexpr span_iterator& operator-=(difference_type n) noexcept { return *this += -n; } constexpr span_iterator& operator-=(difference_type n) GSL_NOEXCEPT { return *this += -n; }
constexpr difference_type operator-(const span_iterator& rhs) const constexpr difference_type operator-(const span_iterator& rhs) const
{ {
@ -233,16 +223,16 @@ namespace details
return index_ - rhs.index_; return index_ - rhs.index_;
} }
constexpr reference operator[](difference_type n) const noexcept { return *(*this + n); } constexpr reference operator[](difference_type n) const GSL_NOEXCEPT { return *(*this + n); }
constexpr friend bool operator==(const span_iterator& lhs, constexpr friend bool operator==(const span_iterator& lhs,
const span_iterator& rhs) noexcept const span_iterator& rhs) GSL_NOEXCEPT
{ {
return lhs.span_ == rhs.span_ && lhs.index_ == rhs.index_; return lhs.span_ == rhs.span_ && lhs.index_ == rhs.index_;
} }
constexpr friend bool operator!=(const span_iterator& lhs, constexpr friend bool operator!=(const span_iterator& lhs,
const span_iterator& rhs) noexcept const span_iterator& rhs) GSL_NOEXCEPT
{ {
return !(lhs == rhs); return !(lhs == rhs);
} }
@ -254,23 +244,23 @@ namespace details
} }
constexpr friend bool operator<=(const span_iterator& lhs, constexpr friend bool operator<=(const span_iterator& lhs,
const span_iterator& rhs) noexcept const span_iterator& rhs) GSL_NOEXCEPT
{ {
return !(rhs < lhs); return !(rhs < lhs);
} }
constexpr friend bool operator>(const span_iterator& lhs, const span_iterator& rhs) noexcept constexpr friend bool operator>(const span_iterator& lhs, const span_iterator& rhs) GSL_NOEXCEPT
{ {
return rhs < lhs; return rhs < lhs;
} }
constexpr friend bool operator>=(const span_iterator& lhs, constexpr friend bool operator>=(const span_iterator& lhs,
const span_iterator& rhs) noexcept const span_iterator& rhs) GSL_NOEXCEPT
{ {
return !(rhs > lhs); return !(rhs > lhs);
} }
void swap(span_iterator& rhs) noexcept void swap(span_iterator& rhs) GSL_NOEXCEPT
{ {
std::swap(index_, rhs.index_); std::swap(index_, rhs.index_);
std::swap(span_, rhs.span_); std::swap(span_, rhs.span_);
@ -282,17 +272,17 @@ namespace details
}; };
template <class Span, bool IsConst> template <class Span, bool IsConst>
constexpr span_iterator<Span, IsConst> inline constexpr span_iterator<Span, IsConst>
operator+(typename span_iterator<Span, IsConst>::difference_type n, operator+(typename span_iterator<Span, IsConst>::difference_type n,
const span_iterator<Span, IsConst>& rhs) noexcept const span_iterator<Span, IsConst>& rhs) GSL_NOEXCEPT
{ {
return rhs + n; return rhs + n;
} }
template <class Span, bool IsConst> template <class Span, bool IsConst>
constexpr span_iterator<Span, IsConst> inline constexpr span_iterator<Span, IsConst>
operator-(typename span_iterator<Span, IsConst>::difference_type n, operator-(typename span_iterator<Span, IsConst>::difference_type n,
const span_iterator<Span, IsConst>& rhs) noexcept const span_iterator<Span, IsConst>& rhs) GSL_NOEXCEPT
{ {
return rhs - n; return rhs - n;
} }
@ -305,7 +295,7 @@ namespace details
static_assert(Ext >= 0, "A fixed-size span must be >= 0 in size."); static_assert(Ext >= 0, "A fixed-size span must be >= 0 in size.");
constexpr extent_type() noexcept {} constexpr extent_type() GSL_NOEXCEPT {}
template <index_type Other> template <index_type Other>
constexpr extent_type(extent_type<Other> ext) constexpr extent_type(extent_type<Other> ext)
@ -317,7 +307,7 @@ namespace details
constexpr extent_type(index_type size) { Expects(size == Ext); } constexpr extent_type(index_type size) { Expects(size == Ext); }
constexpr inline index_type size() const noexcept { return Ext; } constexpr index_type size() const GSL_NOEXCEPT { return Ext; }
}; };
template <> template <>
@ -333,7 +323,7 @@ namespace details
explicit constexpr extent_type(index_type size) : size_(size) { Expects(size >= 0); } explicit constexpr extent_type(index_type size) : size_(size) { Expects(size >= 0); }
constexpr inline index_type size() const noexcept { return size_; } constexpr index_type size() const GSL_NOEXCEPT { return size_; }
private: private:
index_type size_; index_type size_;
@ -363,9 +353,9 @@ public:
// "Dependent" is needed to make "std::enable_if_t<Dependent || Extent <= 0>" SFINAE, // "Dependent" is needed to make "std::enable_if_t<Dependent || Extent <= 0>" SFINAE,
// since "std::enable_if_t<Extent <= 0>" is ill-formed when Extent is greater than 0. // since "std::enable_if_t<Extent <= 0>" is ill-formed when Extent is greater than 0.
class = std::enable_if_t<(Dependent || Extent <= 0)>> class = std::enable_if_t<(Dependent || Extent <= 0)>>
constexpr span() noexcept : storage_(nullptr, details::extent_type<0>()) {} constexpr span() GSL_NOEXCEPT : storage_(nullptr, details::extent_type<0>()) {}
constexpr span(std::nullptr_t) noexcept : span() {} constexpr span(std::nullptr_t) GSL_NOEXCEPT : span() {}
constexpr span(pointer ptr, index_type count) : storage_(ptr, count) {} constexpr span(pointer ptr, index_type count) : storage_(ptr, count) {}
@ -375,18 +365,18 @@ public:
} }
template <size_t N> template <size_t N>
constexpr span(element_type (&arr)[N]) noexcept : storage_(&arr[0], details::extent_type<N>()) constexpr span(element_type (&arr)[N]) GSL_NOEXCEPT : storage_(&arr[0], details::extent_type<N>())
{ {
} }
template <size_t N, class ArrayElementType = std::remove_const_t<element_type>> template <size_t N, class ArrayElementType = std::remove_const_t<element_type>>
constexpr span(std::array<ArrayElementType, N>& arr) noexcept constexpr span(std::array<ArrayElementType, N>& arr) GSL_NOEXCEPT
: storage_(&arr[0], details::extent_type<N>()) : storage_(&arr[0], details::extent_type<N>())
{ {
} }
template <size_t N> template <size_t N>
constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) noexcept constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) GSL_NOEXCEPT
: storage_(&arr[0], details::extent_type<N>()) : storage_(&arr[0], details::extent_type<N>())
{ {
} }
@ -419,11 +409,11 @@ public:
{ {
} }
constexpr span(const span& other) noexcept = default; constexpr span(const span& other) GSL_NOEXCEPT = default;
#ifndef GSL_MSVC_NO_DEFAULT_MOVE_CTOR #ifndef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
constexpr span(span&& other) noexcept = default; constexpr span(span&& other) GSL_NOEXCEPT = default;
#else #else
constexpr span(span&& other) noexcept : storage_(std::move(other.storage_)) {} constexpr span(span&& other) GSL_NOEXCEPT : storage_(std::move(other.storage_)) {}
#endif #endif
template < template <
@ -446,13 +436,13 @@ public:
{ {
} }
~span() noexcept = default; ~span() GSL_NOEXCEPT = default;
constexpr span& operator=(const span& other) noexcept = default; constexpr span& operator=(const span& other) GSL_NOEXCEPT = default;
#ifndef GSL_MSVC_NO_DEFAULT_MOVE_CTOR #ifndef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
constexpr span& operator=(span&& other) noexcept = default; constexpr span& operator=(span&& other) GSL_NOEXCEPT = default;
#else #else
constexpr span& operator=(span&& other) noexcept constexpr span& operator=(span&& other) GSL_NOEXCEPT
{ {
storage_ = std::move(other.storage_); storage_ = std::move(other.storage_);
return *this; return *this;
@ -502,11 +492,11 @@ public:
} }
// [span.obs], span observers // [span.obs], span observers
constexpr index_type length() const noexcept { return size(); } constexpr index_type length() const GSL_NOEXCEPT { return size(); }
constexpr index_type size() const noexcept { return storage_.size(); } constexpr index_type size() const GSL_NOEXCEPT { return storage_.size(); }
constexpr index_type length_bytes() const noexcept { return size_bytes(); } constexpr index_type length_bytes() const GSL_NOEXCEPT { return size_bytes(); }
constexpr index_type size_bytes() const noexcept { return size() * narrow_cast<index_type>(sizeof(element_type)); } constexpr index_type size_bytes() const GSL_NOEXCEPT { return size() * narrow_cast<index_type>(sizeof(element_type)); }
constexpr bool empty() const noexcept { return size() == 0; } constexpr bool empty() const GSL_NOEXCEPT { return size() == 0; }
// [span.elem], span element access // [span.elem], span element access
constexpr reference operator[](index_type idx) const constexpr reference operator[](index_type idx) const
@ -517,20 +507,20 @@ public:
constexpr reference at(index_type idx) const { return this->operator[](idx); } constexpr reference at(index_type idx) const { return this->operator[](idx); }
constexpr reference operator()(index_type idx) const { return this->operator[](idx); } constexpr reference operator()(index_type idx) const { return this->operator[](idx); }
constexpr pointer data() const noexcept { return storage_.data(); } constexpr pointer data() const GSL_NOEXCEPT { return storage_.data(); }
// [span.iter], span iterator support // [span.iter], span iterator support
iterator begin() const noexcept { return {this, 0}; } iterator begin() const GSL_NOEXCEPT { return {this, 0}; }
iterator end() const noexcept { return {this, length()}; } iterator end() const GSL_NOEXCEPT { return {this, length()}; }
const_iterator cbegin() const noexcept { return {this, 0}; } const_iterator cbegin() const GSL_NOEXCEPT { return {this, 0}; }
const_iterator cend() const noexcept { return {this, length()}; } const_iterator cend() const GSL_NOEXCEPT { return {this, length()}; }
reverse_iterator rbegin() const noexcept { return reverse_iterator{end()}; } reverse_iterator rbegin() const GSL_NOEXCEPT { return reverse_iterator{end()}; }
reverse_iterator rend() const noexcept { return reverse_iterator{begin()}; } reverse_iterator rend() const GSL_NOEXCEPT { return reverse_iterator{begin()}; }
const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator{cend()}; } const_reverse_iterator crbegin() const GSL_NOEXCEPT { return const_reverse_iterator{cend()}; }
const_reverse_iterator crend() const noexcept { return const_reverse_iterator{cbegin()}; } const_reverse_iterator crend() const GSL_NOEXCEPT { return const_reverse_iterator{cbegin()}; }
private: private:
// this implementation detail class lets us take advantage of the // this implementation detail class lets us take advantage of the
@ -546,7 +536,7 @@ private:
Expects((!data && ExtentType::size() == 0) || (data && ExtentType::size() >= 0)); Expects((!data && ExtentType::size() == 0) || (data && ExtentType::size() >= 0));
} }
constexpr inline pointer data() const noexcept { return data_; } constexpr pointer data() const GSL_NOEXCEPT { return data_; }
private: private:
pointer data_; pointer data_;
@ -557,7 +547,7 @@ private:
// [span.comparison], span comparison operators // [span.comparison], span comparison operators
template <class ElementType, std::ptrdiff_t FirstExtent, std::ptrdiff_t SecondExtent> template <class ElementType, std::ptrdiff_t FirstExtent, std::ptrdiff_t SecondExtent>
constexpr bool operator==(const span<ElementType, FirstExtent>& l, inline constexpr bool operator==(const span<ElementType, FirstExtent>& l,
const span<ElementType, SecondExtent>& r) const span<ElementType, SecondExtent>& r)
{ {
#ifdef GSL_MSVC_NO_CPP14_STD_EQUAL #ifdef GSL_MSVC_NO_CPP14_STD_EQUAL
@ -568,31 +558,31 @@ constexpr bool operator==(const span<ElementType, FirstExtent>& l,
} }
template <class ElementType, std::ptrdiff_t Extent> template <class ElementType, std::ptrdiff_t Extent>
constexpr bool operator!=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) inline constexpr bool operator!=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r)
{ {
return !(l == r); return !(l == r);
} }
template <class ElementType, std::ptrdiff_t Extent> template <class ElementType, std::ptrdiff_t Extent>
constexpr bool operator<(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) inline constexpr bool operator<(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r)
{ {
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end()); return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
} }
template <class ElementType, std::ptrdiff_t Extent> template <class ElementType, std::ptrdiff_t Extent>
constexpr bool operator<=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) inline constexpr bool operator<=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r)
{ {
return !(l > r); return !(l > r);
} }
template <class ElementType, std::ptrdiff_t Extent> template <class ElementType, std::ptrdiff_t Extent>
constexpr bool operator>(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) inline constexpr bool operator>(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r)
{ {
return r < l; return r < l;
} }
template <class ElementType, std::ptrdiff_t Extent> template <class ElementType, std::ptrdiff_t Extent>
constexpr bool operator>=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r) inline constexpr bool operator>=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r)
{ {
return !(l < r); return !(l < r);
} }
@ -623,7 +613,7 @@ namespace details
// [span.objectrep], views of object representation // [span.objectrep], views of object representation
template <class ElementType, std::ptrdiff_t Extent> template <class ElementType, std::ptrdiff_t Extent>
span<const byte, details::calculate_byte_size<ElementType, Extent>::value> span<const byte, details::calculate_byte_size<ElementType, Extent>::value>
as_bytes(span<ElementType, Extent> s) noexcept as_bytes(span<ElementType, Extent> s) GSL_NOEXCEPT
{ {
return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()}; return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
} }
@ -631,7 +621,7 @@ as_bytes(span<ElementType, Extent> s) noexcept
template <class ElementType, std::ptrdiff_t Extent, template <class ElementType, std::ptrdiff_t Extent,
class = std::enable_if_t<!std::is_const<ElementType>::value>> class = std::enable_if_t<!std::is_const<ElementType>::value>>
span<byte, details::calculate_byte_size<ElementType, Extent>::value> span<byte, details::calculate_byte_size<ElementType, Extent>::value>
as_writeable_bytes(span<ElementType, Extent> s) noexcept as_writeable_bytes(span<ElementType, Extent> s) GSL_NOEXCEPT
{ {
return {reinterpret_cast<byte*>(s.data()), s.size_bytes()}; return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
} }
@ -677,7 +667,7 @@ make_span(Ptr& cont)
// Specialization of gsl::at for span // Specialization of gsl::at for span
template <class ElementType, std::ptrdiff_t Extent> template <class ElementType, std::ptrdiff_t Extent>
constexpr ElementType& at(const span<ElementType, Extent>& s, std::ptrdiff_t index) inline constexpr ElementType& at(const span<ElementType, Extent>& s, std::ptrdiff_t index)
{ {
// No bounds checking here because it is done in span::operator[] called below // No bounds checking here because it is done in span::operator[] called below
return s[index]; return s[index];
@ -685,39 +675,27 @@ constexpr ElementType& at(const span<ElementType, Extent>& s, std::ptrdiff_t ind
} // namespace gsl } // namespace gsl
#ifdef _MSC_VER #undef GSL_NOEXCEPT
#ifdef _MSC_VER
#if _MSC_VER < 1910
#undef constexpr #undef constexpr
#pragma pop_macro("constexpr") #pragma pop_macro("constexpr")
#if _MSC_VER <= 1800 #if _MSC_VER <= 1800
#pragma warning(pop)
#ifndef GSL_THROW_ON_CONTRACT_VIOLATION
#undef noexcept #undef noexcept
#pragma pop_macro("noexcept") #pragma pop_macro("noexcept")
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
#undef alignof
#pragma pop_macro("alignof") #pragma pop_macro("alignof")
#undef GSL_MSVC_HAS_VARIADIC_CTOR_BUG #undef GSL_MSVC_HAS_VARIADIC_CTOR_BUG
#undef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
#undef GSL_MSVC_NO_CPP14_STD_EQUAL
#endif // _MSC_VER <= 1800 #endif // _MSC_VER <= 1800
#endif // _MSC_VER < 1910
#pragma warning(pop)
#endif // _MSC_VER #endif // _MSC_VER
#if defined(GSL_THROW_ON_CONTRACT_VIOLATION)
#undef noexcept
#ifdef _MSC_VER
#pragma pop_macro("noexcept")
#endif
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif // GSL_SPAN_H #endif // GSL_SPAN_H

View File

@ -19,19 +19,14 @@
#ifndef GSL_STRING_SPAN_H #ifndef GSL_STRING_SPAN_H
#define GSL_STRING_SPAN_H #define GSL_STRING_SPAN_H
#include "gsl_assert" #include <gsl/gsl_assert>
#include "gsl_util" #include <gsl/gsl_util>
#include "span" #include <gsl/span>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <string> #include <string>
#ifdef _MSC_VER #ifdef _MSC_VER
// No MSVC does constexpr fully yet
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
#pragma warning(push) #pragma warning(push)
// blanket turn off warnings from CppCoreCheck for now // blanket turn off warnings from CppCoreCheck for now
@ -39,32 +34,29 @@
// more targeted suppressions will be added in a future update to the GSL // more targeted suppressions will be added in a future update to the GSL
#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495) #pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
#if _MSC_VER < 1910
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
// VS 2013 workarounds // VS 2013 workarounds
#if _MSC_VER <= 1800 #if _MSC_VER <= 1800
#define GSL_MSVC_HAS_TYPE_DEDUCTION_BUG #define GSL_MSVC_HAS_TYPE_DEDUCTION_BUG
#define GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE #define GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE
#define GSL_MSVC_NO_CPP14_STD_EQUAL #define GSL_MSVC_NO_CPP14_STD_EQUAL
#define GSL_MSVC_NO_DEFAULT_MOVE_CTOR #define GSL_MSVC_NO_DEFAULT_MOVE_CTOR
// noexcept is not understood // noexcept is not understood
#ifndef GSL_THROW_ON_CONTRACT_VIOLATION
#pragma push_macro("noexcept") #pragma push_macro("noexcept")
#define noexcept /*noexcept*/ #define noexcept /*noexcept*/
#endif
#endif // _MSC_VER <= 1800 #endif // _MSC_VER <= 1800
#endif // _MSC_VER < 1910
#endif // _MSC_VER #endif // _MSC_VER
// In order to test the library, we need it to throw exceptions that we can catch // In order to test the library, we need it to throw exceptions that we can catch
#ifdef GSL_THROW_ON_CONTRACT_VIOLATION #ifdef GSL_THROW_ON_CONTRACT_VIOLATION
#define GSL_NOEXCEPT /*noexcept*/
#ifdef _MSC_VER #else
#pragma push_macro("noexcept") #define GSL_NOEXCEPT noexcept
#endif
#define noexcept /*noexcept*/
#endif // GSL_THROW_ON_CONTRACT_VIOLATION #endif // GSL_THROW_ON_CONTRACT_VIOLATION
namespace gsl namespace gsl
@ -72,7 +64,7 @@ namespace gsl
// //
// czstring and wzstring // czstring and wzstring
// //
// These are "tag" typedef's for C-style strings (i.e. null-terminated character arrays) // These are "tag" typedefs for C-style strings (i.e. null-terminated character arrays)
// that allow static analysis to help find bugs. // that allow static analysis to help find bugs.
// //
// There are no additional features/semantics that we can find a way to add inside the // There are no additional features/semantics that we can find a way to add inside the
@ -225,7 +217,7 @@ namespace details
template <> template <>
struct length_func<char> struct length_func<char>
{ {
std::ptrdiff_t operator()(char* const ptr, std::ptrdiff_t length) noexcept std::ptrdiff_t operator()(char* const ptr, std::ptrdiff_t length) GSL_NOEXCEPT
{ {
return details::string_length(ptr, length); return details::string_length(ptr, length);
} }
@ -234,7 +226,7 @@ namespace details
template <> template <>
struct length_func<wchar_t> struct length_func<wchar_t>
{ {
std::ptrdiff_t operator()(wchar_t* const ptr, std::ptrdiff_t length) noexcept std::ptrdiff_t operator()(wchar_t* const ptr, std::ptrdiff_t length) GSL_NOEXCEPT
{ {
return details::wstring_length(ptr, length); return details::wstring_length(ptr, length);
} }
@ -243,7 +235,7 @@ namespace details
template <> template <>
struct length_func<const char> struct length_func<const char>
{ {
std::ptrdiff_t operator()(const char* const ptr, std::ptrdiff_t length) noexcept std::ptrdiff_t operator()(const char* const ptr, std::ptrdiff_t length) GSL_NOEXCEPT
{ {
return details::string_length(ptr, length); return details::string_length(ptr, length);
} }
@ -252,7 +244,7 @@ namespace details
template <> template <>
struct length_func<const wchar_t> struct length_func<const wchar_t>
{ {
std::ptrdiff_t operator()(const wchar_t* const ptr, std::ptrdiff_t length) noexcept std::ptrdiff_t operator()(const wchar_t* const ptr, std::ptrdiff_t length) GSL_NOEXCEPT
{ {
return details::wstring_length(ptr, length); return details::wstring_length(ptr, length);
} }
@ -279,26 +271,26 @@ public:
using const_reverse_iterator = typename impl_type::const_reverse_iterator; using const_reverse_iterator = typename impl_type::const_reverse_iterator;
// default (empty) // default (empty)
constexpr basic_string_span() noexcept = default; constexpr basic_string_span() GSL_NOEXCEPT = default;
// copy // copy
constexpr basic_string_span(const basic_string_span& other) noexcept = default; constexpr basic_string_span(const basic_string_span& other) GSL_NOEXCEPT = default;
// move // move
#ifndef GSL_MSVC_NO_DEFAULT_MOVE_CTOR #ifndef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
constexpr basic_string_span(basic_string_span&& other) noexcept = default; constexpr basic_string_span(basic_string_span&& other) GSL_NOEXCEPT = default;
#else #else
constexpr basic_string_span(basic_string_span&& other) : span_(std::move(other.span_)) {} constexpr basic_string_span(basic_string_span&& other) : span_(std::move(other.span_)) {}
#endif #endif
// assign // assign
constexpr basic_string_span& operator=(const basic_string_span& other) noexcept = default; constexpr basic_string_span& operator=(const basic_string_span& other) GSL_NOEXCEPT = default;
// move assign // move assign
#ifndef GSL_MSVC_NO_DEFAULT_MOVE_CTOR #ifndef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
constexpr basic_string_span& operator=(basic_string_span&& other) noexcept = default; constexpr basic_string_span& operator=(basic_string_span&& other) GSL_NOEXCEPT = default;
#else #else
constexpr basic_string_span& operator=(basic_string_span&& other) noexcept constexpr basic_string_span& operator=(basic_string_span&& other) GSL_NOEXCEPT
{ {
span_ = std::move(other.span_); span_ = std::move(other.span_);
return *this; return *this;
@ -306,7 +298,7 @@ public:
#endif #endif
// from nullptr // from nullptr
constexpr basic_string_span(std::nullptr_t ptr) noexcept : span_(ptr) {} constexpr basic_string_span(std::nullptr_t ptr) GSL_NOEXCEPT : span_(ptr) {}
constexpr basic_string_span(pointer ptr, index_type length) : span_(ptr, length) {} constexpr basic_string_span(pointer ptr, index_type length) : span_(ptr, length) {}
constexpr basic_string_span(pointer firstElem, pointer lastElem) : span_(firstElem, lastElem) {} constexpr basic_string_span(pointer firstElem, pointer lastElem) : span_(firstElem, lastElem) {}
@ -319,12 +311,12 @@ public:
} }
template <size_t N, class ArrayElementType = std::remove_const_t<element_type>> template <size_t N, class ArrayElementType = std::remove_const_t<element_type>>
constexpr basic_string_span(std::array<ArrayElementType, N>& arr) noexcept : span_(arr) constexpr basic_string_span(std::array<ArrayElementType, N>& arr) GSL_NOEXCEPT : span_(arr)
{ {
} }
template <size_t N, class ArrayElementType = std::remove_const_t<element_type>> template <size_t N, class ArrayElementType = std::remove_const_t<element_type>>
constexpr basic_string_span(const std::array<ArrayElementType, N>& arr) noexcept : span_(arr) constexpr basic_string_span(const std::array<ArrayElementType, N>& arr) GSL_NOEXCEPT : span_(arr)
{ {
} }
@ -411,23 +403,23 @@ public:
constexpr pointer data() const { return span_.data(); } constexpr pointer data() const { return span_.data(); }
constexpr index_type length() const noexcept { return span_.size(); } constexpr index_type length() const GSL_NOEXCEPT { return span_.size(); }
constexpr index_type size() const noexcept { return span_.size(); } constexpr index_type size() const GSL_NOEXCEPT { return span_.size(); }
constexpr index_type size_bytes() const noexcept { return span_.size_bytes(); } constexpr index_type size_bytes() const GSL_NOEXCEPT { return span_.size_bytes(); }
constexpr index_type length_bytes() const noexcept { return span_.length_bytes(); } constexpr index_type length_bytes() const GSL_NOEXCEPT { return span_.length_bytes(); }
constexpr bool empty() const noexcept { return size() == 0; } constexpr bool empty() const GSL_NOEXCEPT { return size() == 0; }
constexpr iterator begin() const noexcept { return span_.begin(); } constexpr iterator begin() const GSL_NOEXCEPT { return span_.begin(); }
constexpr iterator end() const noexcept { return span_.end(); } constexpr iterator end() const GSL_NOEXCEPT { return span_.end(); }
constexpr const_iterator cbegin() const noexcept { return span_.cbegin(); } constexpr const_iterator cbegin() const GSL_NOEXCEPT { return span_.cbegin(); }
constexpr const_iterator cend() const noexcept { return span_.cend(); } constexpr const_iterator cend() const GSL_NOEXCEPT { return span_.cend(); }
constexpr reverse_iterator rbegin() const noexcept { return span_.rbegin(); } constexpr reverse_iterator rbegin() const GSL_NOEXCEPT { return span_.rbegin(); }
constexpr reverse_iterator rend() const noexcept { return span_.rend(); } constexpr reverse_iterator rend() const GSL_NOEXCEPT { return span_.rend(); }
constexpr const_reverse_iterator crbegin() const noexcept { return span_.crbegin(); } constexpr const_reverse_iterator crbegin() const GSL_NOEXCEPT { return span_.crbegin(); }
constexpr const_reverse_iterator crend() const noexcept { return span_.crend(); } constexpr const_reverse_iterator crend() const GSL_NOEXCEPT { return span_.crend(); }
private: private:
static impl_type remove_z(pointer const& sz, std::ptrdiff_t max) static impl_type remove_z(pointer const& sz, std::ptrdiff_t max)
@ -520,7 +512,7 @@ public:
using impl_type = span<value_type, Extent>; using impl_type = span<value_type, Extent>;
using string_span_type = basic_string_span<value_type, Extent>; using string_span_type = basic_string_span<value_type, Extent>;
constexpr basic_zstring_span(impl_type s) noexcept : span_(s) constexpr basic_zstring_span(impl_type s) GSL_NOEXCEPT : span_(s)
{ {
// expects a zero-terminated span // expects a zero-terminated span
Expects(s[s.size() - 1] == '\0'); Expects(s[s.size() - 1] == '\0');
@ -550,17 +542,17 @@ public:
} }
#endif #endif
constexpr bool empty() const noexcept { return span_.size() == 0; } constexpr bool empty() const GSL_NOEXCEPT { return span_.size() == 0; }
constexpr string_span_type as_string_span() const noexcept constexpr string_span_type as_string_span() const GSL_NOEXCEPT
{ {
auto sz = span_.size(); auto sz = span_.size();
return span_.first(sz <= 0 ? 0 : sz - 1); return span_.first(sz <= 0 ? 0 : sz - 1);
} }
constexpr string_span_type ensure_z() const noexcept { return gsl::ensure_z(span_); } constexpr string_span_type ensure_z() const GSL_NOEXCEPT { return gsl::ensure_z(span_); }
constexpr const_zstring_type assume_z() const noexcept { return span_.data(); } constexpr const_zstring_type assume_z() const GSL_NOEXCEPT { return span_.data(); }
private: private:
impl_type span_; impl_type span_;
@ -583,7 +575,7 @@ template <class CharT, std::ptrdiff_t Extent, class T,
class = std::enable_if_t< class = std::enable_if_t<
details::is_basic_string_span<T>::value || details::is_basic_string_span<T>::value ||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>> std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>>
bool operator==(const gsl::basic_string_span<CharT, Extent>& one, const T& other) noexcept bool operator==(const gsl::basic_string_span<CharT, Extent>& one, const T& other) GSL_NOEXCEPT
{ {
gsl::basic_string_span<std::add_const_t<CharT>> tmp(other); gsl::basic_string_span<std::add_const_t<CharT>> tmp(other);
#ifdef GSL_MSVC_NO_CPP14_STD_EQUAL #ifdef GSL_MSVC_NO_CPP14_STD_EQUAL
@ -597,7 +589,7 @@ template <class CharT, std::ptrdiff_t Extent, class T,
class = std::enable_if_t< class = std::enable_if_t<
!details::is_basic_string_span<T>::value && !details::is_basic_string_span<T>::value &&
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>> std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>>
bool operator==(const T& one, const gsl::basic_string_span<CharT, Extent>& other) noexcept bool operator==(const T& one, const gsl::basic_string_span<CharT, Extent>& other) GSL_NOEXCEPT
{ {
gsl::basic_string_span<std::add_const_t<CharT>> tmp(one); gsl::basic_string_span<std::add_const_t<CharT>> tmp(one);
#ifdef GSL_MSVC_NO_CPP14_STD_EQUAL #ifdef GSL_MSVC_NO_CPP14_STD_EQUAL
@ -611,7 +603,7 @@ bool operator==(const T& one, const gsl::basic_string_span<CharT, Extent>& other
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
typename = std::enable_if_t<std::is_convertible< typename = std::enable_if_t<std::is_convertible<
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>> T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
bool operator!=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept bool operator!=(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
{ {
return !(one == other); return !(one == other);
} }
@ -621,7 +613,7 @@ template <
typename Dummy = std::enable_if_t< typename Dummy = std::enable_if_t<
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value && std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
!gsl::details::is_basic_string_span<T>::value>> !gsl::details::is_basic_string_span<T>::value>>
bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
{ {
return !(one == other); return !(one == other);
} }
@ -630,7 +622,7 @@ bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
typename = std::enable_if_t<std::is_convertible< typename = std::enable_if_t<std::is_convertible<
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>> T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
{ {
gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(other); gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(other);
return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end()); return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end());
@ -641,7 +633,7 @@ template <
typename Dummy = std::enable_if_t< typename Dummy = std::enable_if_t<
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value && std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
!gsl::details::is_basic_string_span<T>::value>> !gsl::details::is_basic_string_span<T>::value>>
bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
{ {
gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one); gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one);
return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end()); return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end());
@ -660,7 +652,7 @@ template <
std::is_convertible<DataType*, CharT*>::value && std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>> DataType>::value>>
bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
{ {
gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(other); gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(other);
return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end()); return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end());
@ -674,7 +666,7 @@ template <
std::is_convertible<DataType*, CharT*>::value && std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>> DataType>::value>>
bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
{ {
gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one); gsl::basic_string_span<std::add_const_t<CharT>, Extent> tmp(one);
return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end()); return std::lexicographical_compare(tmp.begin(), tmp.end(), other.begin(), other.end());
@ -685,7 +677,7 @@ bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other) noexce
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
typename = std::enable_if_t<std::is_convertible< typename = std::enable_if_t<std::is_convertible<
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>> T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
{ {
return !(other < one); return !(other < one);
} }
@ -695,7 +687,7 @@ template <
typename Dummy = std::enable_if_t< typename Dummy = std::enable_if_t<
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value && std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
!gsl::details::is_basic_string_span<T>::value>> !gsl::details::is_basic_string_span<T>::value>>
bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
{ {
return !(other < one); return !(other < one);
} }
@ -713,7 +705,7 @@ template <
std::is_convertible<DataType*, CharT*>::value && std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>> DataType>::value>>
bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
{ {
return !(other < one); return !(other < one);
} }
@ -726,7 +718,7 @@ template <
std::is_convertible<DataType*, CharT*>::value && std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>> DataType>::value>>
bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
{ {
return !(other < one); return !(other < one);
} }
@ -736,7 +728,7 @@ bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexc
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
typename = std::enable_if_t<std::is_convertible< typename = std::enable_if_t<std::is_convertible<
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>> T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
{ {
return other < one; return other < one;
} }
@ -746,7 +738,7 @@ template <
typename Dummy = std::enable_if_t< typename Dummy = std::enable_if_t<
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value && std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
!gsl::details::is_basic_string_span<T>::value>> !gsl::details::is_basic_string_span<T>::value>>
bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
{ {
return other < one; return other < one;
} }
@ -764,7 +756,7 @@ template <
std::is_convertible<DataType*, CharT*>::value && std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>> DataType>::value>>
bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
{ {
return other < one; return other < one;
} }
@ -777,7 +769,7 @@ template <
std::is_convertible<DataType*, CharT*>::value && std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>> DataType>::value>>
bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
{ {
return other < one; return other < one;
} }
@ -787,7 +779,7 @@ bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other) noexce
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T,
typename = std::enable_if_t<std::is_convertible< typename = std::enable_if_t<std::is_convertible<
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>> T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
{ {
return !(one < other); return !(one < other);
} }
@ -797,7 +789,7 @@ template <
typename Dummy = std::enable_if_t< typename Dummy = std::enable_if_t<
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value && std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value &&
!gsl::details::is_basic_string_span<T>::value>> !gsl::details::is_basic_string_span<T>::value>>
bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
{ {
return !(one < other); return !(one < other);
} }
@ -815,7 +807,7 @@ template <
std::is_convertible<DataType*, CharT*>::value && std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>> DataType>::value>>
bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other) noexcept bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other) GSL_NOEXCEPT
{ {
return !(one < other); return !(one < other);
} }
@ -828,43 +820,33 @@ template <
std::is_convertible<DataType*, CharT*>::value && std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>, std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
DataType>::value>> DataType>::value>>
bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) noexcept bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_NOEXCEPT
{ {
return !(one < other); return !(one < other);
} }
#endif #endif
} // namespace GSL } // namespace GSL
#ifdef _MSC_VER #undef GSL_NOEXCEPT
#ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)
#if _MSC_VER < 1910
#undef constexpr #undef constexpr
#pragma pop_macro("constexpr") #pragma pop_macro("constexpr")
// VS 2013 workarounds // VS 2013 workarounds
#if _MSC_VER <= 1800 #if _MSC_VER <= 1800
#ifndef GSL_THROW_ON_CONTRACT_VIOLATION
#undef noexcept #undef noexcept
#pragma pop_macro("noexcept") #pragma pop_macro("noexcept")
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
#undef GSL_MSVC_HAS_TYPE_DEDUCTION_BUG #undef GSL_MSVC_HAS_TYPE_DEDUCTION_BUG
#undef GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE #undef GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE
#undef GSL_MSVC_NO_CPP14_STD_EQUAL #undef GSL_MSVC_NO_CPP14_STD_EQUAL
#undef GSL_MSVC_NO_DEFAULT_MOVE_CTOR #undef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
#endif // _MSC_VER <= 1800 #endif // _MSC_VER <= 1800
#endif // _MSC_VER < 1910
#endif // _MSC_VER #endif // _MSC_VER
#if defined(GSL_THROW_ON_CONTRACT_VIOLATION)
#undef noexcept
#ifdef _MSC_VER
#pragma pop_macro("noexcept")
#endif
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
#endif // GSL_STRING_SPAN_H #endif // GSL_STRING_SPAN_H

View File

@ -9,7 +9,7 @@ endif()
add_subdirectory(unittest-cpp) add_subdirectory(unittest-cpp)
include_directories( include_directories(
.. ../include
./unittest-cpp ./unittest-cpp
) )
@ -33,7 +33,7 @@ else()
endif() endif()
function(add_gsl_test name) function(add_gsl_test name)
add_executable(${name} ${name}.cpp ../gsl/gsl ../gsl/gsl_assert ../gsl/gsl_util ../gsl/multi_span ../gsl/span ../gsl/string_span) add_executable(${name} ${name}.cpp)
target_link_libraries(${name} UnitTest++) target_link_libraries(${name} UnitTest++)
add_test( add_test(
${name} ${name}
@ -53,4 +53,3 @@ add_gsl_test(utils_tests)
add_gsl_test(owner_tests) add_gsl_test(owner_tests)
add_gsl_test(byte_tests) add_gsl_test(byte_tests)
add_gsl_test(algorithm_tests) add_gsl_test(algorithm_tests)

View File

@ -1148,7 +1148,7 @@ SUITE(multi_span_tests)
auto width = 5, height = 20; auto width = 5, height = 20;
auto imgSize = width * height; auto imgSize = width * height;
auto image_ptr = new int[imgSize][3]; auto image_ptr = new int[static_cast<std::size_t>(imgSize)][3];
// size check will be done // size check will be done
auto image_view = auto image_view =
@ -1496,7 +1496,7 @@ SUITE(multi_span_tests)
auto height = 4, width = 2; auto height = 4, width = 2;
auto size = height * width; auto size = height * width;
auto arr = new int[size]; auto arr = new int[static_cast<std::size_t>(size)];
for (auto i = 0; i < size; ++i) { for (auto i = 0; i < size; ++i) {
arr[i] = i; arr[i] = i;
} }

View File

@ -663,7 +663,7 @@ SUITE(strided_span_tests)
auto height = 12, width = 2; auto height = 12, width = 2;
auto size = height * width; auto size = height * width;
auto arr = new int[size]; auto arr = new int[static_cast<std::size_t>(size)];
for (auto i = 0; i < size; ++i) for (auto i = 0; i < size; ++i)
{ {
arr[i] = i; arr[i] = i;

View File

@ -759,7 +759,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_extent> s) {} void use(basic_string_span<T, gsl::dynamic_extent>) {}
TEST(MoveConstructors) TEST(MoveConstructors)
{ {