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/*.*
CMakeCache.txt
*.suo
.vs/
.vscode/

View File

@ -2,25 +2,10 @@ cmake_minimum_required(VERSION 2.8.7)
project(GSL CXX)
set(GSL_HEADERS
"gsl/gsl"
"gsl/gsl_assert"
"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
install(
DIRECTORY include/gsl
DESTINATION include
)
enable_testing()
add_subdirectory(tests)

View File

@ -19,32 +19,28 @@
#ifndef GSL_GSL_H
#define GSL_GSL_H
#include "gsl_assert" // Ensures/Expects
#include "gsl_util" // finally()/narrow()/narrow_cast()...
#include "multi_span" // multi_span, strided_span...
#include "span" // span
#include "string_span" // zstring, string_span, zstring_builder...
#include <gsl/gsl_assert> // Ensures/Expects
#include <gsl/gsl_util> // finally()/narrow()/narrow_cast()...
#include <gsl/multi_span> // multi_span, strided_span...
#include <gsl/span> // span
#include <gsl/string_span> // zstring, string_span, zstring_builder...
#include <memory>
#ifdef _MSC_VER
#if defined(_MSC_VER) && _MSC_VER < 1910
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
// No MSVC does constexpr fully yet
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
// MSVC 2013 workarounds
#if _MSC_VER <= 1800
// noexcept is not understood
#pragma push_macro("noexcept")
#define noexcept /*noexcept*/
// MSVC 2013 workarounds
#if _MSC_VER <= 1800
// noexcept is not understood
#pragma push_macro("noexcept")
#define noexcept /*noexcept*/
// turn off some misguided warnings
#pragma warning(push)
#pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
#endif // _MSC_VER <= 1800
#endif // _MSC_VER
// turn off some misguided warnings
#pragma warning(push)
#pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
#endif // _MSC_VER <= 1800
#endif // defined(_MSC_VER) && _MSC_VER < 1910
namespace gsl
{
@ -153,20 +149,16 @@ struct hash<gsl::not_null<T>>
} // namespace std
#ifdef _MSC_VER
#if defined(_MSC_VER) && _MSC_VER < 1910
#undef constexpr
#pragma pop_macro("constexpr")
#undef constexpr
#pragma pop_macro("constexpr")
#if _MSC_VER <= 1800
#undef noexcept
#pragma pop_macro("noexcept")
#if _MSC_VER <= 1800
#undef noexcept
#pragma pop_macro("noexcept")
#pragma warning(pop)
#endif // _MSC_VER <= 1800
#endif // _MSC_VER
#pragma warning(pop)
#endif // _MSC_VER <= 1800
#endif // defined(_MSC_VER) && _MSC_VER < 1910
#endif // GSL_GSL_H

View File

@ -19,21 +19,19 @@
#ifndef GSL_ALGORITHM_H
#define GSL_ALGORITHM_H
#include "span"
#include <gsl/span>
#include <algorithm>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(push)
// turn off some warnings that are noisy about our Expects statements
#pragma warning(disable : 4127) // conditional expression is constant
// blanket turn off warnings from CppCoreCheck for now
// so people aren't annoyed by them when running the tool.
// 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)
// turn off some warnings that are noisy about our Expects statements
#pragma warning(disable : 4127) // conditional expression is constant
// blanket turn off warnings from CppCoreCheck for now
// so people aren't annoyed by them when running the tool.
// 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)
#endif // _MSC_VER
namespace gsl
@ -55,7 +53,7 @@ void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent>
} // namespace gsl
#ifdef _MSC_VER
#pragma warning(pop)
#pragma warning(pop)
#endif // _MSC_VER
#endif // GSL_ALGORITHM_H

View File

@ -30,7 +30,7 @@
// 2. GSL_THROW_ON_CONTRACT_VIOLATION: a gsl::fail_fast exception will be thrown
// 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))
#define GSL_TERMINATE_ON_CONTRACT_VIOLATION
#endif

View File

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

View File

@ -19,33 +19,28 @@
#ifndef GSL_UTIL_H
#define GSL_UTIL_H
#include "gsl_assert" // Ensures/Expects
#include <gsl/gsl_assert> // Ensures/Expects
#include <array>
#include <exception>
#include <type_traits>
#include <utility>
#ifdef _MSC_VER
// No MSVC does constexpr fully yet
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
#pragma warning(push)
#pragma warning(disable : 4127) // conditional expression is constant
// MSVC 2013 workarounds
#if _MSC_VER <= 1800
// noexcept is not understood
#pragma push_macro("noexcept")
#define noexcept /*noexcept*/
// turn off some misguided warnings
#pragma warning(push)
#pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
#endif // _MSC_VER <= 1800
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4127) // conditional expression is constant
#if _MSC_VER < 1910
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
// MSVC 2013 workarounds
#if _MSC_VER <= 1800
// noexcept is not understood
#pragma push_macro("noexcept")
#define noexcept /*noexcept*/
// turn off some misguided warnings
#pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
#endif // _MSC_VER <= 1800
#endif // _MSC_VER < 1910
#endif // _MSC_VER
namespace gsl
@ -135,28 +130,28 @@ inline T narrow(U u)
// at() - Bounds-checked way of accessing static arrays, std::array, std::vector
//
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));
return arr[static_cast<size_t>(index)];
}
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));
return arr[static_cast<size_t>(index)];
}
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()));
return cont[static_cast<typename Cont::size_type>(index)];
}
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()));
return *(cont.begin() + index);
@ -164,22 +159,17 @@ constexpr const T& at(std::initializer_list<T> cont, std::ptrdiff_t index)
} // namespace gsl
#ifdef _MSC_VER
#pragma warning(pop)
#undef constexpr
#pragma pop_macro("constexpr")
#if _MSC_VER <= 1800
#undef noexcept
#pragma pop_macro("noexcept")
#pragma warning(pop)
#endif // _MSC_VER <= 1800
#if defined(_MSC_VER)
#if _MSC_VER < 1910
#undef constexpr
#pragma pop_macro("constexpr")
#if _MSC_VER <= 1800
#undef noexcept
#pragma pop_macro("noexcept")
#endif // _MSC_VER <= 1800
#endif // _MSC_VER < 1910
#pragma warning(pop)
#endif // _MSC_VER
#endif // GSL_UTIL_H

File diff suppressed because it is too large Load Diff

View File

@ -20,9 +20,9 @@
#ifndef GSL_SPAN_H
#define GSL_SPAN_H
#include "gsl_assert"
#include "gsl_byte"
#include "gsl_util"
#include <gsl/gsl_assert>
#include <gsl/gsl_byte>
#include <gsl/gsl_util>
#include <array>
#include <iterator>
#include <limits>
@ -32,54 +32,44 @@
#include <memory>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(push)
// turn off some warnings that are noisy about our Expects statements
#pragma warning(disable : 4127) // conditional expression is constant
// turn off some warnings that are noisy about our Expects statements
#pragma warning(disable : 4127) // conditional expression is constant
// blanket turn off warnings from CppCoreCheck for now
// so people aren't annoyed by them when running the tool.
// 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)
// blanket turn off warnings from CppCoreCheck for now
// so people aren't annoyed by them when running the tool.
// 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)
#if _MSC_VER < 1910
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
// No MSVC does constexpr fully yet
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
// VS 2013 workarounds
#if _MSC_VER <= 1800
#define GSL_MSVC_HAS_VARIADIC_CTOR_BUG
#define GSL_MSVC_NO_DEFAULT_MOVE_CTOR
#define GSL_MSVC_NO_CPP14_STD_EQUAL
// VS 2013 workarounds
#if _MSC_VER <= 1800
// noexcept is not understood
#pragma push_macro("noexcept")
#define noexcept /*noexcept*/
#define GSL_MSVC_HAS_VARIADIC_CTOR_BUG
#define GSL_MSVC_NO_DEFAULT_MOVE_CTOR
#define GSL_MSVC_NO_CPP14_STD_EQUAL
// noexcept is not understood
#ifndef GSL_THROW_ON_CONTRACT_VIOLATION
#pragma push_macro("noexcept")
#define noexcept /*noexcept*/
#endif
#pragma push_macro("alignof")
#define alignof __alignof
// turn off some misguided warnings
#pragma warning(push)
#pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
#pragma warning(disable : 4512) // warns that assignment op could not be generated
#endif // _MSC_VER <= 1800
#pragma push_macro("alignof")
#define alignof __alignof
// turn off some misguided warnings
#pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
#pragma warning(disable : 4512) // warns that assignment op could not be generated
#endif // _MSC_VER <= 1800
#endif // _MSC_VER < 1910
#endif // _MSC_VER
#ifdef GSL_THROW_ON_CONTRACT_VIOLATION
#ifdef _MSC_VER
#pragma push_macro("noexcept")
#endif
#define noexcept /*noexcept*/
#define GSL_NOEXCEPT /*noexcept*/
#else
#define GSL_NOEXCEPT noexcept
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
namespace gsl
@ -150,7 +140,7 @@ namespace details
std::conditional_t<IsConst, const element_type_, element_type_> &;
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)
: span_(span), index_(index)
@ -159,12 +149,12 @@ namespace details
}
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_)
{
}
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
{
@ -185,7 +175,7 @@ namespace details
return *this;
}
constexpr span_iterator operator++(int) noexcept
constexpr span_iterator operator++(int) GSL_NOEXCEPT
{
auto ret = *this;
++(*this);
@ -199,14 +189,14 @@ namespace details
return *this;
}
constexpr span_iterator operator--(int) noexcept
constexpr span_iterator operator--(int) GSL_NOEXCEPT
{
auto ret = *this;
--(*this);
return ret;
}
constexpr span_iterator operator+(difference_type n) const noexcept
constexpr span_iterator operator+(difference_type n) const GSL_NOEXCEPT
{
auto ret = *this;
return ret += n;
@ -219,13 +209,13 @@ namespace details
return *this;
}
constexpr span_iterator operator-(difference_type n) const noexcept
constexpr span_iterator operator-(difference_type n) const GSL_NOEXCEPT
{
auto ret = *this;
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
{
@ -233,16 +223,16 @@ namespace details
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,
const span_iterator& rhs) noexcept
const span_iterator& rhs) GSL_NOEXCEPT
{
return lhs.span_ == rhs.span_ && lhs.index_ == rhs.index_;
}
constexpr friend bool operator!=(const span_iterator& lhs,
const span_iterator& rhs) noexcept
const span_iterator& rhs) GSL_NOEXCEPT
{
return !(lhs == rhs);
}
@ -254,23 +244,23 @@ namespace details
}
constexpr friend bool operator<=(const span_iterator& lhs,
const span_iterator& rhs) noexcept
const span_iterator& rhs) GSL_NOEXCEPT
{
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;
}
constexpr friend bool operator>=(const span_iterator& lhs,
const span_iterator& rhs) noexcept
const span_iterator& rhs) GSL_NOEXCEPT
{
return !(rhs > lhs);
}
void swap(span_iterator& rhs) noexcept
void swap(span_iterator& rhs) GSL_NOEXCEPT
{
std::swap(index_, rhs.index_);
std::swap(span_, rhs.span_);
@ -282,17 +272,17 @@ namespace details
};
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,
const span_iterator<Span, IsConst>& rhs) noexcept
const span_iterator<Span, IsConst>& rhs) GSL_NOEXCEPT
{
return rhs + n;
}
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,
const span_iterator<Span, IsConst>& rhs) noexcept
const span_iterator<Span, IsConst>& rhs) GSL_NOEXCEPT
{
return rhs - n;
}
@ -305,7 +295,7 @@ namespace details
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>
constexpr extent_type(extent_type<Other> ext)
@ -317,7 +307,7 @@ namespace details
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 <>
@ -333,7 +323,7 @@ namespace details
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:
index_type size_;
@ -363,9 +353,9 @@ public:
// "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.
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) {}
@ -375,18 +365,18 @@ public:
}
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>>
constexpr span(std::array<ArrayElementType, N>& arr) noexcept
constexpr span(std::array<ArrayElementType, N>& arr) GSL_NOEXCEPT
: storage_(&arr[0], details::extent_type<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>())
{
}
@ -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
constexpr span(span&& other) noexcept = default;
constexpr span(span&& other) GSL_NOEXCEPT = default;
#else
constexpr span(span&& other) noexcept : storage_(std::move(other.storage_)) {}
constexpr span(span&& other) GSL_NOEXCEPT : storage_(std::move(other.storage_)) {}
#endif
template <
@ -446,13 +436,13 @@ public:
{
}
~span() noexcept = default;
constexpr span& operator=(const span& other) noexcept = default;
~span() GSL_NOEXCEPT = default;
constexpr span& operator=(const span& other) GSL_NOEXCEPT = default;
#ifndef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
constexpr span& operator=(span&& other) noexcept = default;
constexpr span& operator=(span&& other) GSL_NOEXCEPT = default;
#else
constexpr span& operator=(span&& other) noexcept
constexpr span& operator=(span&& other) GSL_NOEXCEPT
{
storage_ = std::move(other.storage_);
return *this;
@ -502,11 +492,11 @@ public:
}
// [span.obs], span observers
constexpr index_type length() const noexcept { return size(); }
constexpr index_type size() const noexcept { return storage_.size(); }
constexpr index_type length_bytes() const noexcept { return size_bytes(); }
constexpr index_type size_bytes() const noexcept { return size() * narrow_cast<index_type>(sizeof(element_type)); }
constexpr bool empty() const noexcept { return size() == 0; }
constexpr index_type length() const GSL_NOEXCEPT { return size(); }
constexpr index_type size() const GSL_NOEXCEPT { return storage_.size(); }
constexpr index_type length_bytes() const GSL_NOEXCEPT { return size_bytes(); }
constexpr index_type size_bytes() const GSL_NOEXCEPT { return size() * narrow_cast<index_type>(sizeof(element_type)); }
constexpr bool empty() const GSL_NOEXCEPT { return size() == 0; }
// [span.elem], span element access
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 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
iterator begin() const noexcept { return {this, 0}; }
iterator end() const noexcept { return {this, length()}; }
iterator begin() const GSL_NOEXCEPT { return {this, 0}; }
iterator end() const GSL_NOEXCEPT { return {this, length()}; }
const_iterator cbegin() const noexcept { return {this, 0}; }
const_iterator cend() const noexcept { return {this, length()}; }
const_iterator cbegin() const GSL_NOEXCEPT { return {this, 0}; }
const_iterator cend() const GSL_NOEXCEPT { return {this, length()}; }
reverse_iterator rbegin() const noexcept { return reverse_iterator{end()}; }
reverse_iterator rend() const noexcept { return reverse_iterator{begin()}; }
reverse_iterator rbegin() const GSL_NOEXCEPT { return reverse_iterator{end()}; }
reverse_iterator rend() const GSL_NOEXCEPT { return reverse_iterator{begin()}; }
const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator{cend()}; }
const_reverse_iterator crend() const noexcept { return const_reverse_iterator{cbegin()}; }
const_reverse_iterator crbegin() const GSL_NOEXCEPT { return const_reverse_iterator{cend()}; }
const_reverse_iterator crend() const GSL_NOEXCEPT { return const_reverse_iterator{cbegin()}; }
private:
// this implementation detail class lets us take advantage of the
@ -546,7 +536,7 @@ private:
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:
pointer data_;
@ -557,7 +547,7 @@ private:
// [span.comparison], span comparison operators
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)
{
#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>
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);
}
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());
}
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);
}
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;
}
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);
}
@ -623,7 +613,7 @@ namespace details
// [span.objectrep], views of object representation
template <class ElementType, std::ptrdiff_t Extent>
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()};
}
@ -631,7 +621,7 @@ as_bytes(span<ElementType, Extent> s) noexcept
template <class ElementType, std::ptrdiff_t Extent,
class = std::enable_if_t<!std::is_const<ElementType>::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()};
}
@ -677,7 +667,7 @@ make_span(Ptr& cont)
// Specialization of gsl::at for span
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
return s[index];
@ -685,39 +675,27 @@ constexpr ElementType& at(const span<ElementType, Extent>& s, std::ptrdiff_t ind
} // namespace gsl
#undef GSL_NOEXCEPT
#ifdef _MSC_VER
#if _MSC_VER < 1910
#undef constexpr
#pragma pop_macro("constexpr")
#undef constexpr
#pragma pop_macro("constexpr")
#if _MSC_VER <= 1800
#undef noexcept
#pragma pop_macro("noexcept")
#if _MSC_VER <= 1800
#pragma warning(pop)
#undef alignof
#pragma pop_macro("alignof")
#ifndef GSL_THROW_ON_CONTRACT_VIOLATION
#undef noexcept
#pragma pop_macro("noexcept")
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
#pragma pop_macro("alignof")
#undef GSL_MSVC_HAS_VARIADIC_CTOR_BUG
#endif // _MSC_VER <= 1800
#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 < 1910
#pragma warning(pop)
#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

View File

@ -19,52 +19,44 @@
#ifndef GSL_STRING_SPAN_H
#define GSL_STRING_SPAN_H
#include "gsl_assert"
#include "gsl_util"
#include "span"
#include <gsl/gsl_assert>
#include <gsl/gsl_util>
#include <gsl/span>
#include <cstdint>
#include <cstring>
#include <string>
#ifdef _MSC_VER
#pragma warning(push)
// No MSVC does constexpr fully yet
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
// blanket turn off warnings from CppCoreCheck for now
// so people aren't annoyed by them when running the tool.
// 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(push)
#if _MSC_VER < 1910
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
// blanket turn off warnings from CppCoreCheck for now
// so people aren't annoyed by them when running the tool.
// 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)
// VS 2013 workarounds
#if _MSC_VER <= 1800
#define GSL_MSVC_HAS_TYPE_DEDUCTION_BUG
#define GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE
#define GSL_MSVC_NO_CPP14_STD_EQUAL
#define GSL_MSVC_NO_DEFAULT_MOVE_CTOR
// VS 2013 workarounds
#if _MSC_VER <= 1800
#define GSL_MSVC_HAS_TYPE_DEDUCTION_BUG
#define GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE
#define GSL_MSVC_NO_CPP14_STD_EQUAL
#define GSL_MSVC_NO_DEFAULT_MOVE_CTOR
// noexcept is not understood
#ifndef GSL_THROW_ON_CONTRACT_VIOLATION
#pragma push_macro("noexcept")
#define noexcept /*noexcept*/
#endif
#endif // _MSC_VER <= 1800
// noexcept is not understood
#pragma push_macro("noexcept")
#define noexcept /*noexcept*/
#endif // _MSC_VER <= 1800
#endif // _MSC_VER < 1910
#endif // _MSC_VER
// In order to test the library, we need it to throw exceptions that we can catch
#ifdef GSL_THROW_ON_CONTRACT_VIOLATION
#ifdef _MSC_VER
#pragma push_macro("noexcept")
#endif
#define noexcept /*noexcept*/
#define GSL_NOEXCEPT /*noexcept*/
#else
#define GSL_NOEXCEPT noexcept
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
namespace gsl
@ -72,7 +64,7 @@ namespace gsl
//
// 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.
//
// There are no additional features/semantics that we can find a way to add inside the
@ -225,7 +217,7 @@ namespace details
template <>
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);
}
@ -234,7 +226,7 @@ namespace details
template <>
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);
}
@ -243,7 +235,7 @@ namespace details
template <>
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);
}
@ -252,7 +244,7 @@ namespace details
template <>
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);
}
@ -279,26 +271,26 @@ public:
using const_reverse_iterator = typename impl_type::const_reverse_iterator;
// default (empty)
constexpr basic_string_span() noexcept = default;
constexpr basic_string_span() GSL_NOEXCEPT = default;
// 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
#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
constexpr basic_string_span(basic_string_span&& other) : span_(std::move(other.span_)) {}
#endif
// 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
#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
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_);
return *this;
@ -306,7 +298,7 @@ public:
#endif
// 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 firstElem, pointer lastElem) : span_(firstElem, lastElem) {}
@ -319,12 +311,12 @@ public:
}
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>>
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 index_type length() const noexcept { return span_.size(); }
constexpr index_type size() const noexcept { return span_.size(); }
constexpr index_type size_bytes() const noexcept { return span_.size_bytes(); }
constexpr index_type length_bytes() const noexcept { return span_.length_bytes(); }
constexpr bool empty() const noexcept { return size() == 0; }
constexpr index_type length() const GSL_NOEXCEPT { return span_.size(); }
constexpr index_type size() const GSL_NOEXCEPT { return span_.size(); }
constexpr index_type size_bytes() const GSL_NOEXCEPT { return span_.size_bytes(); }
constexpr index_type length_bytes() const GSL_NOEXCEPT { return span_.length_bytes(); }
constexpr bool empty() const GSL_NOEXCEPT { return size() == 0; }
constexpr iterator begin() const noexcept { return span_.begin(); }
constexpr iterator end() const noexcept { return span_.end(); }
constexpr iterator begin() const GSL_NOEXCEPT { return span_.begin(); }
constexpr iterator end() const GSL_NOEXCEPT { return span_.end(); }
constexpr const_iterator cbegin() const noexcept { return span_.cbegin(); }
constexpr const_iterator cend() const noexcept { return span_.cend(); }
constexpr const_iterator cbegin() const GSL_NOEXCEPT { return span_.cbegin(); }
constexpr const_iterator cend() const GSL_NOEXCEPT { return span_.cend(); }
constexpr reverse_iterator rbegin() const noexcept { return span_.rbegin(); }
constexpr reverse_iterator rend() const noexcept { return span_.rend(); }
constexpr reverse_iterator rbegin() const GSL_NOEXCEPT { return span_.rbegin(); }
constexpr reverse_iterator rend() const GSL_NOEXCEPT { return span_.rend(); }
constexpr const_reverse_iterator crbegin() const noexcept { return span_.crbegin(); }
constexpr const_reverse_iterator crend() const noexcept { return span_.crend(); }
constexpr const_reverse_iterator crbegin() const GSL_NOEXCEPT { return span_.crbegin(); }
constexpr const_reverse_iterator crend() const GSL_NOEXCEPT { return span_.crend(); }
private:
static impl_type remove_z(pointer const& sz, std::ptrdiff_t max)
@ -501,7 +493,7 @@ std::basic_string<CharT, Traits, Allocator> to_basic_string(basic_string_span<gC
{
return {view.data(), static_cast<size_t>(view.length())};
}
// zero-terminated string span, used to convert
// zero-terminated spans to legacy strings
template <typename CharT, std::ptrdiff_t Extent = dynamic_extent>
@ -520,7 +512,7 @@ public:
using impl_type = 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(s[s.size() - 1] == '\0');
@ -550,17 +542,17 @@ public:
}
#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();
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:
impl_type span_;
@ -583,7 +575,7 @@ template <class CharT, std::ptrdiff_t Extent, class T,
class = std::enable_if_t<
details::is_basic_string_span<T>::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);
#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<
!details::is_basic_string_span<T>::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);
#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,
typename = std::enable_if_t<std::is_convertible<
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);
}
@ -621,7 +613,7 @@ template <
typename Dummy = std::enable_if_t<
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::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);
}
@ -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,
typename = std::enable_if_t<std::is_convertible<
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);
return std::lexicographical_compare(one.begin(), one.end(), tmp.begin(), tmp.end());
@ -641,7 +633,7 @@ template <
typename Dummy = std::enable_if_t<
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::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);
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_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
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);
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_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
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);
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,
typename = std::enable_if_t<std::is_convertible<
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);
}
@ -695,7 +687,7 @@ template <
typename Dummy = std::enable_if_t<
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::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);
}
@ -713,7 +705,7 @@ template <
std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
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);
}
@ -726,7 +718,7 @@ template <
std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
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);
}
@ -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,
typename = std::enable_if_t<std::is_convertible<
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;
}
@ -746,7 +738,7 @@ template <
typename Dummy = std::enable_if_t<
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::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;
}
@ -764,7 +756,7 @@ template <
std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
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;
}
@ -777,7 +769,7 @@ template <
std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
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;
}
@ -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,
typename = std::enable_if_t<std::is_convertible<
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);
}
@ -797,7 +789,7 @@ template <
typename Dummy = std::enable_if_t<
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::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);
}
@ -815,7 +807,7 @@ template <
std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
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);
}
@ -828,43 +820,33 @@ template <
std::is_convertible<DataType*, CharT*>::value &&
std::is_same<std::decay_t<decltype(std::declval<T>().size(), *std::declval<T>().data())>,
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);
}
#endif
} // namespace GSL
#undef GSL_NOEXCEPT
#ifdef _MSC_VER
#pragma warning(pop)
#pragma warning(pop)
#if _MSC_VER < 1910
#undef constexpr
#pragma pop_macro("constexpr")
#undef constexpr
#pragma pop_macro("constexpr")
// VS 2013 workarounds
#if _MSC_VER <= 1800
#undef noexcept
#pragma pop_macro("noexcept")
// VS 2013 workarounds
#if _MSC_VER <= 1800
#ifndef GSL_THROW_ON_CONTRACT_VIOLATION
#undef noexcept
#pragma pop_macro("noexcept")
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
#undef GSL_MSVC_HAS_TYPE_DEDUCTION_BUG
#undef GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE
#undef GSL_MSVC_NO_CPP14_STD_EQUAL
#undef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
#endif // _MSC_VER <= 1800
#undef GSL_MSVC_HAS_TYPE_DEDUCTION_BUG
#undef GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE
#undef GSL_MSVC_NO_CPP14_STD_EQUAL
#undef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
#endif // _MSC_VER <= 1800
#endif // _MSC_VER < 1910
#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

View File

@ -9,7 +9,7 @@ endif()
add_subdirectory(unittest-cpp)
include_directories(
..
../include
./unittest-cpp
)
@ -33,7 +33,7 @@ else()
endif()
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++)
add_test(
${name}
@ -53,4 +53,3 @@ add_gsl_test(utils_tests)
add_gsl_test(owner_tests)
add_gsl_test(byte_tests)
add_gsl_test(algorithm_tests)

View File

@ -1148,7 +1148,7 @@ SUITE(multi_span_tests)
auto width = 5, height = 20;
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
auto image_view =
@ -1496,7 +1496,7 @@ SUITE(multi_span_tests)
auto height = 4, width = 2;
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) {
arr[i] = i;
}

View File

@ -1,20 +1,20 @@
///////////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////
//
// 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 <UnitTest++/UnitTest++.h>
#include <gsl/multi_span>
#include <string>
@ -27,7 +27,7 @@
using namespace std;
using namespace gsl;
namespace
namespace
{
struct BaseClass {};
struct DerivedClass : BaseClass {};
@ -38,7 +38,7 @@ SUITE(strided_span_tests)
TEST (span_section_test)
{
int a[30][4][5];
auto av = as_multi_span(a);
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});
@ -143,7 +143,7 @@ SUITE(strided_span_tests)
#else
strided_span<const volatile int, 1> sav_cv{ multi_span<const volatile int>{src}, strided_bounds<1>{2, 1} };
#endif
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav_cv.bounds().strides() == index<1>{ 1 });
CHECK(sav_cv[1] == 2);
@ -188,13 +188,13 @@ SUITE(strided_span_tests)
CHECK(av2[1] == 5);
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} };
strided_span<const int, 1> sav{ src };
CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav.bounds().stride() == 1);
CHECK(sav[1] == 5);
static_assert(std::is_convertible<const strided_span<int, 1>, strided_span<const int, 1>>::value, "ctor is not implicit!");
}
@ -203,7 +203,7 @@ SUITE(strided_span_tests)
int arr1[2] = { 3, 4 };
const strided_span<int, 1> src1{ arr1, {2, 1} };
strided_span<int, 1> sav1{ src1 };
CHECK(sav1.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav1.bounds().stride() == 1);
CHECK(sav1[0] == 3);
@ -229,7 +229,7 @@ SUITE(strided_span_tests)
CHECK(sav[0] == 1);
CHECK(&sav_ref == &sav);
}
// Check copy assignment operator
{
int arr1[2] = { 3, 4 };
@ -304,7 +304,7 @@ SUITE(strided_span_tests)
CHECK(cm_sl[1] == 11);
CHECK(cm_sl[2] == 12);
// Section
// Section
strided_span<int, 2> cm_sec = cm_sav.section( { 2, 1 }, { 3, 2 });
CHECK((cm_sec.bounds().index_bounds() == index<2>{3, 2}));
@ -321,11 +321,11 @@ SUITE(strided_span_tests)
{
// incorrect sections
CHECK_THROW(av.section(0, 0)[0], fail_fast);
CHECK_THROW(av.section(1, 0)[0], fail_fast);
CHECK_THROW(av.section(1, 1)[1], fail_fast);
CHECK_THROW(av.section(2, 5), fail_fast);
CHECK_THROW(av.section(5, 2), fail_fast);
CHECK_THROW(av.section(5, 0), fail_fast);
@ -354,7 +354,7 @@ SUITE(strided_span_tests)
}
{
// strided array ctor with matching strided bounds
// strided array ctor with matching strided bounds
strided_span<int, 1> sav{ arr,{ 4, 1 } };
CHECK(sav.bounds().index_bounds() == index<1>{ 4 });
CHECK(sav[3] == 3);
@ -362,7 +362,7 @@ SUITE(strided_span_tests)
}
{
// strided array ctor with smaller strided bounds
// strided array ctor with smaller strided bounds
strided_span<int, 1> sav{ arr,{ 2, 1 } };
CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav[1] == 1);
@ -370,7 +370,7 @@ SUITE(strided_span_tests)
}
{
// strided array ctor with fitting irregular bounds
// strided array ctor with fitting irregular bounds
strided_span<int, 1> sav{ arr,{ 2, 3 } };
CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav[0] == 0);
@ -663,7 +663,7 @@ SUITE(strided_span_tests)
auto height = 12, width = 2;
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)
{
arr[i] = i;
@ -713,12 +713,12 @@ SUITE(strided_span_tests)
auto section = av.section({0, 2 * s}, {4, s}); // { { arr[0].c[0], arr[0].c[1], arr[0].c[2], arr[0].c[3] } , { arr[1].c[0], ... } , ... }
// convert to array 4x1 array of integers
auto cs = section.as_strided_span<int>(); // { { arr[0].c }, {arr[1].c } , ... }
auto cs = section.as_strided_span<int>(); // { { arr[0].c }, {arr[1].c } , ... }
CHECK(cs.bounds().index_bounds()[0] == 4);
CHECK(cs.bounds().index_bounds()[1] == 1);
// transpose to 1x4 array
// transpose to 1x4 array
strided_bounds<2> reverse_bounds{
{cs.bounds().index_bounds()[1] , cs.bounds().index_bounds()[0]},
{cs.bounds().strides()[1], cs.bounds().strides()[0]}

View File

@ -125,7 +125,7 @@ SUITE(string_span_tests)
CHECK(static_cast<cstring_span<>::index_type>(s2.length()) == v.length());
CHECK(s2.length() == 5);
}
TEST(EqualityAndImplicitConstructors)
{
{
@ -134,7 +134,7 @@ SUITE(string_span_tests)
// comparison to empty span
CHECK(span1 != span);
CHECK(span != span1);
CHECK(span != span1);
}
{
@ -291,7 +291,7 @@ SUITE(string_span_tests)
string_span<> _span{ _ptr, 5 };
// non-const span, non-const other type
CHECK(_span == _ar);
CHECK(_span == _ar1);
CHECK(_span == _ar2);
@ -759,7 +759,7 @@ SUITE(string_span_tests)
T create() { return 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)
{