Merge branch 'master' into TravisCI

This commit is contained in:
Roelf-Jilling 2020-03-26 16:24:19 +01:00
commit 30c068781f
25 changed files with 2249 additions and 1223 deletions

View File

@ -5,6 +5,9 @@ project(GSL CXX)
include(ExternalProject) include(ExternalProject)
find_package(Git) find_package(Git)
# Use GNUInstallDirs to provide the right locations on all platforms
include(GNUInstallDirs)
# creates a library GSL which is an interface (header files only) # creates a library GSL which is an interface (header files only)
add_library(GSL INTERFACE) add_library(GSL INTERFACE)
@ -54,15 +57,13 @@ target_compile_definitions(GSL INTERFACE
# the SYSTEM keyword suppresses warnings for users of the library # the SYSTEM keyword suppresses warnings for users of the library
if(GSL_STANDALONE_PROJECT) if(GSL_STANDALONE_PROJECT)
target_include_directories(GSL INTERFACE target_include_directories(GSL INTERFACE
$<BUILD_INTERFACE: $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
${CMAKE_CURRENT_SOURCE_DIR}/include $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
>
) )
else() else()
target_include_directories(GSL SYSTEM INTERFACE target_include_directories(GSL SYSTEM INTERFACE
$<BUILD_INTERFACE: $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
${CMAKE_CURRENT_SOURCE_DIR}/include $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
>
) )
endif() endif()
@ -77,15 +78,23 @@ if (CMAKE_VERSION VERSION_GREATER 3.7.8)
# add natvis file to the library so it will automatically be loaded into Visual Studio # add natvis file to the library so it will automatically be loaded into Visual Studio
if(VS_ADD_NATIVE_VISUALIZERS) if(VS_ADD_NATIVE_VISUALIZERS)
target_sources(GSL INTERFACE target_sources(GSL INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/GSL.natvis $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GSL.natvis>
) )
endif() endif()
endif() endif()
install(TARGETS GSL EXPORT Microsoft.GSLConfig)
install( install(
DIRECTORY include/gsl DIRECTORY include/gsl
DESTINATION include DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
) )
# Make library importable by other projects
install(EXPORT Microsoft.GSLConfig NAMESPACE Microsoft.GSL:: DESTINATION share/Microsoft.GSL/cmake)
export(TARGETS GSL NAMESPACE Microsoft.GSL:: FILE Microsoft.GSLConfig.cmake)
# Add Microsoft.GSL::GSL alias for GSL so that dependents can be agnostic about
# whether GSL was added via `add_subdirectory` or `find_package`
add_library(Microsoft.GSL::GSL ALIAS GSL)
option(GSL_TEST "Generate tests." ${GSL_STANDALONE_PROJECT}) option(GSL_TEST "Generate tests." ${GSL_STANDALONE_PROJECT})
if (GSL_TEST) if (GSL_TEST)

View File

@ -77,6 +77,18 @@ These steps assume the source code of this repository has been cloned into a dir
All tests should pass - indicating your platform is fully supported and you are ready to use the GSL types! All tests should pass - indicating your platform is fully supported and you are ready to use the GSL types!
## Building GSL - Using vcpkg
You can download and install GSL using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
vcpkg install ms-gsl
The GSL port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
## Using the libraries ## Using the libraries
As the types are entirely implemented inline in headers, there are no linking requirements. As the types are entirely implemented inline in headers, there are no linking requirements.
@ -97,5 +109,14 @@ Include the library using:
#include <gsl/gsl> #include <gsl/gsl>
## Usage in CMake
The library provides a Config file for CMake, once installed it can be found via
find_package(Microsoft.GSL CONFIG)
Which, when successful, will add library target called `Microsoft.GSL::GSL` which you can use via the usual
`target_link_libraries` mechanism.
## Debugging visualization support ## Debugging visualization support
For Visual Studio users, the file [GSL.natvis](./GSL.natvis) in the root directory of the repository can be added to your project if you would like more helpful visualization of GSL types in the Visual Studio debugger than would be offered by default. For Visual Studio users, the file [GSL.natvis](./GSL.natvis) in the root directory of the repository can be added to your project if you would like more helpful visualization of GSL types in the Visual Studio debugger than would be offered by default.

View File

@ -37,8 +37,8 @@ namespace gsl
{ {
// Note: this will generate faster code than std::copy using span iterator in older msvc+stl // Note: this will generate faster code than std::copy using span iterator in older msvc+stl
// not necessary for msvc since VS2017 15.8 (_MSC_VER >= 1915) // not necessary for msvc since VS2017 15.8 (_MSC_VER >= 1915)
template <class SrcElementType, std::ptrdiff_t SrcExtent, class DestElementType, template <class SrcElementType, std::size_t SrcExtent, class DestElementType,
std::ptrdiff_t DestExtent> std::size_t DestExtent>
void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent> dest) void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent> dest)
{ {
static_assert(std::is_assignable<decltype(*dest.data()), decltype(*src.data())>::value, static_assert(std::is_assignable<decltype(*dest.data()), decltype(*src.data())>::value,

View File

@ -17,8 +17,27 @@
#ifndef GSL_CONTRACTS_H #ifndef GSL_CONTRACTS_H
#define GSL_CONTRACTS_H #define GSL_CONTRACTS_H
//
// Temporary until MSVC STL supports no-exceptions mode.
// Currently terminate is a no-op in this mode, so we add termination behavior back
//
#if defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS))
#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND
#include <intrin.h>
#define RANGE_CHECKS_FAILURE 0
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winvalid-noreturn"
#endif // defined(__clang__)
#else // defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS))
#include <exception> #include <exception>
#endif // defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS))
// //
// make suppress attributes parse for some compilers // make suppress attributes parse for some compilers
// Hopefully temporary until suppression standardization occurs // Hopefully temporary until suppression standardization occurs
@ -33,32 +52,18 @@
#endif // _MSC_VER #endif // _MSC_VER
#endif // __clang__ #endif // __clang__
//
// Temporary until MSVC STL supports no-exceptions mode.
// Currently terminate is a no-op in this mode, so we add termination behavior back
//
#if defined(_MSC_VER) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS
#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND
#include <intrin.h>
#define RANGE_CHECKS_FAILURE 0
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winvalid-noreturn"
#endif
#endif
#define GSL_STRINGIFY_DETAIL(x) #x #define GSL_STRINGIFY_DETAIL(x) #x
#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x) #define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x)
#if defined(__clang__) || defined(__GNUC__) #if defined(__clang__) || defined(__GNUC__)
#define GSL_LIKELY(x) __builtin_expect(!!(x), 1) #define GSL_LIKELY(x) __builtin_expect(!!(x), 1)
#define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0) #define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0)
#else #else
#define GSL_LIKELY(x) (!!(x)) #define GSL_LIKELY(x) (!!(x))
#define GSL_UNLIKELY(x) (!!(x)) #define GSL_UNLIKELY(x) (!!(x))
#endif #endif // defined(__clang__) || defined(__GNUC__)
// //
// GSL_ASSUME(cond) // GSL_ASSUME(cond)
@ -85,9 +90,11 @@ namespace details
{ {
#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) #if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
typedef void (__cdecl *terminate_handler)(); typedef void(__cdecl* terminate_handler)();
// clang-format off
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute GSL_SUPPRESS(f.6) // NO-FORMAT: attribute
// clang-format on
[[noreturn]] inline void __cdecl default_terminate_handler() [[noreturn]] inline void __cdecl default_terminate_handler()
{ {
__fastfail(RANGE_CHECKS_FAILURE); __fastfail(RANGE_CHECKS_FAILURE);
@ -99,7 +106,7 @@ namespace details
return handler; return handler;
} }
#endif #endif // defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
[[noreturn]] inline void terminate() noexcept [[noreturn]] inline void terminate() noexcept
{ {
@ -107,21 +114,12 @@ namespace details
(*gsl::details::get_terminate_handler())(); (*gsl::details::get_terminate_handler())();
#else #else
std::terminate(); std::terminate();
#endif #endif // defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
} }
template <typename Exception>
[[deprecated("GSL no longer supports throwing for contract violations. Use gsl::details::terminate() instead.")]]
[[noreturn]] void throw_exception(Exception&&) noexcept
{
gsl::details::terminate();
}
} // namespace details } // namespace details
} // namespace gsl } // namespace gsl
#define GSL_CONTRACT_CHECK(type, cond) \ #define GSL_CONTRACT_CHECK(type, cond) \
(GSL_LIKELY(cond) ? static_cast<void>(0) : gsl::details::terminate()) (GSL_LIKELY(cond) ? static_cast<void>(0) : gsl::details::terminate())

View File

@ -88,7 +88,6 @@ public:
{ {
} }
not_null(not_null&& other) = default;
not_null(const not_null& other) = default; not_null(const not_null& other) = default;
not_null& operator=(const not_null& other) = default; not_null& operator=(const not_null& other) = default;

File diff suppressed because it is too large Load Diff

198
include/gsl/span_ext Normal file
View File

@ -0,0 +1,198 @@
///////////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef GSL_SPAN_EXT_H
#define GSL_SPAN_EXT_H
///////////////////////////////////////////////////////////////////////////////
//
// File: span_ext
// Purpose: continue offering features that have been cut from the official
// implementation of span.
// While modernizing gsl::span a number of features needed to be removed to
// be compliant with the design of std::span
//
///////////////////////////////////////////////////////////////////////////////
#include <gsl/gsl_util> // for narrow_cast, narrow
#include <gsl/span> // for span
#include <algorithm> // for lexicographical_compare
#include <cstddef> // for ptrdiff_t, size_t
#include <utility>
namespace gsl
{
// [span.comparison], span comparison operators
template <class ElementType, std::size_t FirstExtent, std::size_t SecondExtent>
constexpr bool operator==(span<ElementType, FirstExtent> l, span<ElementType, SecondExtent> r)
{
return std::equal(l.begin(), l.end(), r.begin(), r.end());
}
template <class ElementType, std::size_t Extent>
constexpr bool operator!=(span<ElementType, Extent> l, span<ElementType, Extent> r)
{
return !(l == r);
}
template <class ElementType, std::size_t Extent>
constexpr bool operator<(span<ElementType, Extent> l, span<ElementType, Extent> r)
{
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
}
template <class ElementType, std::size_t Extent>
constexpr bool operator<=(span<ElementType, Extent> l, span<ElementType, Extent> r)
{
return !(l > r);
}
template <class ElementType, std::size_t Extent>
constexpr bool operator>(span<ElementType, Extent> l, span<ElementType, Extent> r)
{
return r < l;
}
template <class ElementType, std::size_t Extent>
constexpr bool operator>=(span<ElementType, Extent> l, span<ElementType, Extent> r)
{
return !(l < r);
}
//
// make_span() - Utility functions for creating spans
//
template <class ElementType>
constexpr span<ElementType> make_span(ElementType* ptr, typename span<ElementType>::size_type count)
{
return span<ElementType>(ptr, count);
}
template <class ElementType>
constexpr span<ElementType> make_span(ElementType* firstElem, ElementType* lastElem)
{
return span<ElementType>(firstElem, lastElem);
}
template <class ElementType, std::size_t N>
constexpr span<ElementType, N> make_span(ElementType (&arr)[N]) noexcept
{
return span<ElementType, N>(arr);
}
template <class Container>
constexpr span<typename Container::value_type> make_span(Container& cont)
{
return span<typename Container::value_type>(cont);
}
template <class Container>
constexpr span<const typename Container::value_type> make_span(const Container& cont)
{
return span<const typename Container::value_type>(cont);
}
template <class Ptr>
constexpr span<typename Ptr::element_type> make_span(Ptr& cont, std::size_t count)
{
return span<typename Ptr::element_type>(cont, count);
}
template <class Ptr>
constexpr span<typename Ptr::element_type> make_span(Ptr& cont)
{
return span<typename Ptr::element_type>(cont);
}
// Specialization of gsl::at for span
template <class ElementType, std::size_t Extent>
constexpr ElementType& at(span<ElementType, Extent> s, index i)
{
// No bounds checking here because it is done in span::operator[] called below
Ensures(i >= 0);
return s[narrow_cast<std::size_t>(i)];
}
// [span.obs] Free observer functions
template <class ElementType, std::size_t Extent>
constexpr std::ptrdiff_t ssize(const span<ElementType, Extent>& s) noexcept
{
return static_cast<std::ptrdiff_t>(s.size());
}
// [span.iter] Free functions for begin/end functions
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::iterator
begin(const span<ElementType, Extent>& s) noexcept
{
return s.begin();
}
template <class ElementType, std::size_t Extent = dynamic_extent>
constexpr typename span<ElementType, Extent>::iterator
end(const span<ElementType, Extent>& s) noexcept
{
return s.end();
}
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::const_iterator
cbegin(const span<ElementType, Extent>& s) noexcept
{
return s.cbegin();
}
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::const_iterator
cend(const span<ElementType, Extent>& s) noexcept
{
return s.cend();
}
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::reverse_iterator
rbegin(const span<ElementType, Extent>& s) noexcept
{
return s.rbegin();
}
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::reverse_iterator
rend(const span<ElementType, Extent>& s) noexcept
{
return s.rend();
}
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::const_reverse_iterator
crbegin(const span<ElementType, Extent>& s) noexcept
{
return s.crbegin();
}
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::const_reverse_iterator
crend(const span<ElementType, Extent>& s) noexcept
{
return s.crend();
}
} // namespace gsl
#endif // GSL_SPAN_EXT_H

View File

@ -19,14 +19,14 @@
#include <gsl/gsl_assert> // for Ensures, Expects #include <gsl/gsl_assert> // for Ensures, Expects
#include <gsl/gsl_util> // for narrow_cast #include <gsl/gsl_util> // for narrow_cast
#include <gsl/span> // for operator!=, operator==, dynamic_extent #include <gsl/span_ext> // for operator!=, operator==, dynamic_extent
#include <algorithm> // for equal, lexicographical_compare #include <algorithm> // for equal, lexicographical_compare
#include <array> // for array #include <array> // for array
#include <cstddef> // for ptrdiff_t, size_t, nullptr_t #include <cstddef> // for size_t, nullptr_t
#include <cstdint> // for PTRDIFF_MAX #include <cstdint> // for PTRDIFF_MAX
#include <cstring> #include <cstring>
#include <string> // for basic_string, allocator, char_traits #include <string> // for basic_string, allocator, char_traits
#include <type_traits> // for declval, is_convertible, enable_if_t, add_... #include <type_traits> // for declval, is_convertible, enable_if_t, add_...
#if defined(_MSC_VER) && !defined(__clang__) #if defined(_MSC_VER) && !defined(__clang__)
@ -56,43 +56,43 @@ namespace gsl
// (sometimes needlessly) break existing programs when introduced. // (sometimes needlessly) break existing programs when introduced.
// //
template <typename CharT, std::ptrdiff_t Extent = dynamic_extent> template <typename CharT, std::size_t Extent = dynamic_extent>
using basic_zstring = CharT*; using basic_zstring = CharT*;
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using czstring = basic_zstring<const char, Extent>; using czstring = basic_zstring<const char, Extent>;
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using cwzstring = basic_zstring<const wchar_t, Extent>; using cwzstring = basic_zstring<const wchar_t, Extent>;
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using cu16zstring = basic_zstring<const char16_t, Extent>; using cu16zstring = basic_zstring<const char16_t, Extent>;
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using cu32zstring = basic_zstring<const char32_t, Extent>; using cu32zstring = basic_zstring<const char32_t, Extent>;
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using zstring = basic_zstring<char, Extent>; using zstring = basic_zstring<char, Extent>;
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using wzstring = basic_zstring<wchar_t, Extent>; using wzstring = basic_zstring<wchar_t, Extent>;
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using u16zstring = basic_zstring<char16_t, Extent>; using u16zstring = basic_zstring<char16_t, Extent>;
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using u32zstring = basic_zstring<char32_t, Extent>; using u32zstring = basic_zstring<char32_t, Extent>;
namespace details namespace details
{ {
template <class CharT> template <class CharT>
std::ptrdiff_t string_length(const CharT* str, std::ptrdiff_t n) std::size_t string_length(const CharT* str, std::size_t n)
{ {
if (str == nullptr || n <= 0) return 0; if (str == nullptr || n == dynamic_extent) return 0;
const span<const CharT> str_span{str, n}; const span<const CharT> str_span{str, n};
std::ptrdiff_t len = 0; std::size_t len = 0;
while (len < n && str_span[len]) len++; while (len < n && str_span[len]) len++;
return len; return len;
@ -108,18 +108,20 @@ namespace details
// Will fail-fast if sentinel cannot be found before max elements are examined. // Will fail-fast if sentinel cannot be found before max elements are examined.
// //
template <typename T, const T Sentinel> template <typename T, const T Sentinel>
span<T, dynamic_extent> ensure_sentinel(T* seq, std::ptrdiff_t max = PTRDIFF_MAX) span<T, dynamic_extent> ensure_sentinel(T* seq,
std::size_t max = static_cast<std::size_t>(-1))
{ {
Ensures(seq != nullptr); Ensures(seq != nullptr);
GSL_SUPPRESS(f.23) // NO-FORMAT: attribute // TODO: false positive // TODO: suppress does not work GSL_SUPPRESS(
f.23) // NO-FORMAT: attribute // TODO: false positive // TODO: suppress does not work
auto cur = seq; auto cur = seq;
Ensures(cur != nullptr); // workaround for removing the warning Ensures(cur != nullptr); // workaround for removing the warning
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute // TODO: suppress does not work GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute // TODO: suppress does not work
while ((cur - seq) < max && *cur != Sentinel) ++cur; while (static_cast<std::size_t>(cur - seq) < max && *cur != Sentinel) ++cur;
Ensures(*cur == Sentinel); Ensures(*cur == Sentinel);
return {seq, cur - seq}; return {seq, static_cast<std::size_t>(cur - seq)};
} }
// //
@ -128,7 +130,8 @@ span<T, dynamic_extent> ensure_sentinel(T* seq, std::ptrdiff_t max = PTRDIFF_MAX
// the limit of size_type. // the limit of size_type.
// //
template <typename CharT> template <typename CharT>
span<CharT, dynamic_extent> ensure_z(CharT* const& sz, std::ptrdiff_t max = PTRDIFF_MAX) span<CharT, dynamic_extent> ensure_z(CharT* const& sz,
std::size_t max = static_cast<std::size_t>(-1))
{ {
return ensure_sentinel<CharT, CharT(0)>(sz, max); return ensure_sentinel<CharT, CharT(0)>(sz, max);
} }
@ -136,26 +139,27 @@ span<CharT, dynamic_extent> ensure_z(CharT* const& sz, std::ptrdiff_t max = PTRD
template <typename CharT, std::size_t N> template <typename CharT, std::size_t N>
span<CharT, dynamic_extent> ensure_z(CharT (&sz)[N]) span<CharT, dynamic_extent> ensure_z(CharT (&sz)[N])
{ {
return ensure_z(&sz[0], narrow_cast<std::ptrdiff_t>(N)); return ensure_z(&sz[0], N);
} }
template <class Cont> template <class Cont>
span<typename std::remove_pointer<typename Cont::pointer>::type, dynamic_extent> span<typename std::remove_pointer<typename Cont::pointer>::type, dynamic_extent>
ensure_z(Cont& cont) ensure_z(Cont& cont)
{ {
return ensure_z(cont.data(), narrow_cast<std::ptrdiff_t>(cont.size())); return ensure_z(cont.data(), cont.size());
} }
template <typename CharT, std::ptrdiff_t> template <typename CharT, std::size_t>
class basic_string_span; class basic_string_span;
namespace details { namespace details
{
template <typename T> template <typename T>
struct is_basic_string_span_oracle : std::false_type struct is_basic_string_span_oracle : std::false_type
{ {
}; };
template <typename CharT, std::ptrdiff_t Extent> template <typename CharT, std::size_t Extent>
struct is_basic_string_span_oracle<basic_string_span<CharT, Extent>> : std::true_type struct is_basic_string_span_oracle<basic_string_span<CharT, Extent>> : std::true_type
{ {
}; };
@ -169,7 +173,7 @@ namespace details {
// //
// string_span and relatives // string_span and relatives
// //
template <typename CharT, std::ptrdiff_t Extent = dynamic_extent> template <typename CharT, std::size_t Extent = dynamic_extent>
class basic_string_span class basic_string_span
{ {
public: public:
@ -180,14 +184,12 @@ public:
using const_reference = std::add_lvalue_reference_t<std::add_const_t<element_type>>; using const_reference = std::add_lvalue_reference_t<std::add_const_t<element_type>>;
using impl_type = span<element_type, Extent>; using impl_type = span<element_type, Extent>;
using index_type = typename impl_type::index_type; using size_type = typename impl_type::size_type;
using iterator = typename impl_type::iterator; using iterator = typename impl_type::iterator;
using const_iterator = typename impl_type::const_iterator; using const_iterator = typename impl_type::const_iterator;
using reverse_iterator = typename impl_type::reverse_iterator; using reverse_iterator = typename impl_type::reverse_iterator;
using const_reverse_iterator = typename impl_type::const_reverse_iterator; using const_reverse_iterator = typename impl_type::const_reverse_iterator;
using size_type = index_type;
// default (empty) // default (empty)
constexpr basic_string_span() noexcept = default; constexpr basic_string_span() noexcept = default;
@ -197,7 +199,7 @@ public:
// assign // assign
constexpr basic_string_span& operator=(const basic_string_span& other) noexcept = default; constexpr basic_string_span& operator=(const basic_string_span& other) noexcept = default;
constexpr basic_string_span(pointer ptr, index_type length) : span_(ptr, length) {} constexpr basic_string_span(pointer ptr, size_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) {}
// From static arrays - if 0-terminated, remove 0 from the view // From static arrays - if 0-terminated, remove 0 from the view
@ -218,7 +220,7 @@ public:
template <class Traits, class Allocator> template <class Traits, class Allocator>
// GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug // GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug
constexpr basic_string_span(std::basic_string<element_type, Traits, Allocator>& str) constexpr basic_string_span(std::basic_string<element_type, Traits, Allocator>& str)
: span_(&str[0], narrow_cast<std::ptrdiff_t>(str.length())) : span_(&str[0], str.length())
{} {}
template <class Traits, class Allocator> template <class Traits, class Allocator>
@ -247,56 +249,56 @@ public:
// from string_span // from string_span
template < template <
class OtherValueType, std::ptrdiff_t OtherExtent, class OtherValueType, std::size_t OtherExtent,
class = std::enable_if_t<std::is_convertible< class = std::enable_if_t<std::is_convertible<
typename basic_string_span<OtherValueType, OtherExtent>::impl_type, impl_type>::value>> typename basic_string_span<OtherValueType, OtherExtent>::impl_type, impl_type>::value>>
constexpr basic_string_span(basic_string_span<OtherValueType, OtherExtent> other) constexpr basic_string_span(basic_string_span<OtherValueType, OtherExtent> other)
: span_(other.data(), other.length()) : span_(other.data(), other.length())
{} {}
template <index_type Count> template <size_type Count>
constexpr basic_string_span<element_type, Count> first() const constexpr basic_string_span<element_type, Count> first() const
{ {
return {span_.template first<Count>()}; return {span_.template first<Count>()};
} }
constexpr basic_string_span<element_type, dynamic_extent> first(index_type count) const constexpr basic_string_span<element_type, dynamic_extent> first(size_type count) const
{ {
return {span_.first(count)}; return {span_.first(count)};
} }
template <index_type Count> template <size_type Count>
constexpr basic_string_span<element_type, Count> last() const constexpr basic_string_span<element_type, Count> last() const
{ {
return {span_.template last<Count>()}; return {span_.template last<Count>()};
} }
constexpr basic_string_span<element_type, dynamic_extent> last(index_type count) const constexpr basic_string_span<element_type, dynamic_extent> last(size_type count) const
{ {
return {span_.last(count)}; return {span_.last(count)};
} }
template <index_type Offset, index_type Count> template <size_type Offset, size_type Count>
constexpr basic_string_span<element_type, Count> subspan() const constexpr basic_string_span<element_type, Count> subspan() const
{ {
return {span_.template subspan<Offset, Count>()}; return {span_.template subspan<Offset, Count>()};
} }
constexpr basic_string_span<element_type, dynamic_extent> constexpr basic_string_span<element_type, dynamic_extent>
subspan(index_type offset, index_type count = dynamic_extent) const subspan(size_type offset, size_type count = dynamic_extent) const
{ {
return {span_.subspan(offset, count)}; return {span_.subspan(offset, count)};
} }
constexpr reference operator[](index_type idx) const { return span_[idx]; } constexpr reference operator[](size_type idx) const { return span_[idx]; }
constexpr reference operator()(index_type idx) const { return span_[idx]; } constexpr reference operator()(size_type idx) const { return span_[idx]; }
constexpr pointer data() const { return span_.data(); } constexpr pointer data() const { return span_.data(); }
constexpr index_type length() const noexcept { return span_.size(); } constexpr size_type length() const noexcept { return span_.size(); }
constexpr index_type size() const noexcept { return span_.size(); } constexpr size_type size() const noexcept { return span_.size(); }
constexpr index_type size_bytes() const noexcept { return span_.size_bytes(); } constexpr size_type size_bytes() const noexcept { return span_.size_bytes(); }
constexpr index_type length_bytes() const noexcept { return span_.length_bytes(); } constexpr size_type length_bytes() const noexcept { return span_.length_bytes(); }
constexpr bool empty() const noexcept { return size() == 0; } constexpr bool empty() const noexcept { return size() == 0; }
constexpr iterator begin() const noexcept { return span_.begin(); } constexpr iterator begin() const noexcept { return span_.begin(); }
@ -312,7 +314,7 @@ public:
constexpr const_reverse_iterator crend() const noexcept { return span_.crend(); } constexpr const_reverse_iterator crend() const 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::size_t max)
{ {
return {sz, details::string_length(sz, max)}; return {sz, details::string_length(sz, max)};
} }
@ -320,41 +322,41 @@ private:
template <std::size_t N> template <std::size_t N>
static impl_type remove_z(element_type (&sz)[N]) static impl_type remove_z(element_type (&sz)[N])
{ {
return remove_z(&sz[0], narrow_cast<std::ptrdiff_t>(N)); return remove_z(&sz[0], N);
} }
impl_type span_; impl_type span_;
}; };
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using string_span = basic_string_span<char, Extent>; using string_span = basic_string_span<char, Extent>;
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using cstring_span = basic_string_span<const char, Extent>; using cstring_span = basic_string_span<const char, Extent>;
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using wstring_span = basic_string_span<wchar_t, Extent>; using wstring_span = basic_string_span<wchar_t, Extent>;
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using cwstring_span = basic_string_span<const wchar_t, Extent>; using cwstring_span = basic_string_span<const wchar_t, Extent>;
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using u16string_span = basic_string_span<char16_t, Extent>; using u16string_span = basic_string_span<char16_t, Extent>;
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using cu16string_span = basic_string_span<const char16_t, Extent>; using cu16string_span = basic_string_span<const char16_t, Extent>;
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using u32string_span = basic_string_span<char32_t, Extent>; using u32string_span = basic_string_span<char32_t, Extent>;
template <std::ptrdiff_t Extent = dynamic_extent> template <std::size_t Extent = dynamic_extent>
using cu32string_span = basic_string_span<const char32_t, Extent>; using cu32string_span = basic_string_span<const char32_t, Extent>;
// //
// to_string() allow (explicit) conversions from string_span to string // to_string() allow (explicit) conversions from string_span to string
// //
template <typename CharT, std::ptrdiff_t Extent> template <typename CharT, std::size_t Extent>
std::basic_string<typename std::remove_const<CharT>::type> std::basic_string<typename std::remove_const<CharT>::type>
to_string(basic_string_span<CharT, Extent> view) to_string(basic_string_span<CharT, Extent> view)
{ {
@ -362,13 +364,13 @@ to_string(basic_string_span<CharT, Extent> view)
} }
template <typename CharT, typename Traits = typename std::char_traits<CharT>, template <typename CharT, typename Traits = typename std::char_traits<CharT>,
typename Allocator = std::allocator<CharT>, typename gCharT, std::ptrdiff_t Extent> typename Allocator = std::allocator<CharT>, typename gCharT, std::size_t Extent>
std::basic_string<CharT, Traits, Allocator> to_basic_string(basic_string_span<gCharT, Extent> view) std::basic_string<CharT, Traits, Allocator> to_basic_string(basic_string_span<gCharT, Extent> view)
{ {
return {view.data(), narrow_cast<std::size_t>(view.length())}; return {view.data(), narrow_cast<std::size_t>(view.length())};
} }
template <class ElementType, std::ptrdiff_t Extent> template <class ElementType, std::size_t Extent>
basic_string_span<const byte, details::calculate_byte_size<ElementType, Extent>::value> basic_string_span<const byte, details::calculate_byte_size<ElementType, Extent>::value>
as_bytes(basic_string_span<ElementType, Extent> s) noexcept as_bytes(basic_string_span<ElementType, Extent> s) noexcept
{ {
@ -376,10 +378,10 @@ as_bytes(basic_string_span<ElementType, Extent> s) noexcept
return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()}; return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
} }
template <class ElementType, std::ptrdiff_t Extent, template <class ElementType, std::size_t Extent,
class = std::enable_if_t<!std::is_const<ElementType>::value>> class = std::enable_if_t<!std::is_const<ElementType>::value>>
basic_string_span<byte, details::calculate_byte_size<ElementType, Extent>::value> basic_string_span<byte, details::calculate_byte_size<ElementType, Extent>::value>
as_writeable_bytes(basic_string_span<ElementType, Extent> s) noexcept as_writable_bytes(basic_string_span<ElementType, Extent> s) noexcept
{ {
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
return {reinterpret_cast<byte*>(s.data()), s.size_bytes()}; return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
@ -387,8 +389,9 @@ as_writeable_bytes(basic_string_span<ElementType, Extent> s) noexcept
// zero-terminated string span, used to convert // zero-terminated string span, used to convert
// zero-terminated spans to legacy strings // zero-terminated spans to legacy strings
template <typename CharT, std::ptrdiff_t Extent = dynamic_extent> template <typename CharT, std::size_t Extent = dynamic_extent>
class basic_zstring_span { class basic_zstring_span
{
public: public:
using value_type = CharT; using value_type = CharT;
using const_value_type = std::add_const_t<CharT>; using const_value_type = std::add_const_t<CharT>;
@ -435,32 +438,32 @@ private:
impl_type span_; impl_type span_;
}; };
template <std::ptrdiff_t Max = dynamic_extent> template <std::size_t Max = dynamic_extent>
using zstring_span = basic_zstring_span<char, Max>; using zstring_span = basic_zstring_span<char, Max>;
template <std::ptrdiff_t Max = dynamic_extent> template <std::size_t Max = dynamic_extent>
using wzstring_span = basic_zstring_span<wchar_t, Max>; using wzstring_span = basic_zstring_span<wchar_t, Max>;
template <std::ptrdiff_t Max = dynamic_extent> template <std::size_t Max = dynamic_extent>
using u16zstring_span = basic_zstring_span<char16_t, Max>; using u16zstring_span = basic_zstring_span<char16_t, Max>;
template <std::ptrdiff_t Max = dynamic_extent> template <std::size_t Max = dynamic_extent>
using u32zstring_span = basic_zstring_span<char32_t, Max>; using u32zstring_span = basic_zstring_span<char32_t, Max>;
template <std::ptrdiff_t Max = dynamic_extent> template <std::size_t Max = dynamic_extent>
using czstring_span = basic_zstring_span<const char, Max>; using czstring_span = basic_zstring_span<const char, Max>;
template <std::ptrdiff_t Max = dynamic_extent> template <std::size_t Max = dynamic_extent>
using cwzstring_span = basic_zstring_span<const wchar_t, Max>; using cwzstring_span = basic_zstring_span<const wchar_t, Max>;
template <std::ptrdiff_t Max = dynamic_extent> template <std::size_t Max = dynamic_extent>
using cu16zstring_span = basic_zstring_span<const char16_t, Max>; using cu16zstring_span = basic_zstring_span<const char16_t, Max>;
template <std::ptrdiff_t Max = dynamic_extent> template <std::size_t Max = dynamic_extent>
using cu32zstring_span = basic_zstring_span<const char32_t, Max>; using cu32zstring_span = basic_zstring_span<const char32_t, Max>;
// operator == // operator ==
template <class CharT, std::ptrdiff_t Extent, class T, template <class CharT, std::size_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>>
@ -470,7 +473,7 @@ bool operator==(const gsl::basic_string_span<CharT, Extent>& one, const T& other
return std::equal(one.begin(), one.end(), tmp.begin(), tmp.end()); return std::equal(one.begin(), one.end(), tmp.begin(), tmp.end());
} }
template <class CharT, std::ptrdiff_t Extent, class T, template <class CharT, std::size_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>>
@ -481,7 +484,7 @@ bool operator==(const T& one, const gsl::basic_string_span<CharT, Extent>& other
} }
// operator != // operator !=
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, template <typename CharT, std::size_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) bool operator!=(gsl::basic_string_span<CharT, Extent> one, const T& other)
@ -490,7 +493,7 @@ bool operator!=(gsl::basic_string_span<CharT, Extent> one, const T& other)
} }
template < template <
typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename CharT, std::size_t Extent = gsl::dynamic_extent, typename T,
typename = std::enable_if_t< typename = 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>>
@ -500,7 +503,7 @@ bool operator!=(const T& one, gsl::basic_string_span<CharT, Extent> other)
} }
// operator< // operator<
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, template <typename CharT, std::size_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) bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other)
@ -510,7 +513,7 @@ bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other)
} }
template < template <
typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename CharT, std::size_t Extent = gsl::dynamic_extent, typename T,
typename = std::enable_if_t< typename = 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>>
@ -526,7 +529,7 @@ bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other)
// so the cases below are already covered by the previous operators // so the cases below are already covered by the previous operators
template < template <
typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename CharT, std::size_t Extent = gsl::dynamic_extent, typename T,
typename DataType = typename T::value_type, typename DataType = typename T::value_type,
typename = std::enable_if_t< typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value && !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
@ -540,7 +543,7 @@ bool operator<(gsl::basic_string_span<CharT, Extent> one, const T& other)
} }
template < template <
typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename CharT, std::size_t Extent = gsl::dynamic_extent, typename T,
typename DataType = typename T::value_type, typename DataType = typename T::value_type,
typename = std::enable_if_t< typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value && !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
@ -555,7 +558,7 @@ bool operator<(const T& one, gsl::basic_string_span<CharT, Extent> other)
#endif #endif
// operator <= // operator <=
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, template <typename CharT, std::size_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) bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other)
@ -564,7 +567,7 @@ bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other)
} }
template < template <
typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename CharT, std::size_t Extent = gsl::dynamic_extent, typename T,
typename = std::enable_if_t< typename = 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>>
@ -579,7 +582,7 @@ bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other)
// so the cases below are already covered by the previous operators // so the cases below are already covered by the previous operators
template < template <
typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename CharT, std::size_t Extent = gsl::dynamic_extent, typename T,
typename DataType = typename T::value_type, typename DataType = typename T::value_type,
typename = std::enable_if_t< typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value && !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
@ -592,7 +595,7 @@ bool operator<=(gsl::basic_string_span<CharT, Extent> one, const T& other)
} }
template < template <
typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename CharT, std::size_t Extent = gsl::dynamic_extent, typename T,
typename DataType = typename T::value_type, typename DataType = typename T::value_type,
typename = std::enable_if_t< typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value && !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
@ -606,7 +609,7 @@ bool operator<=(const T& one, gsl::basic_string_span<CharT, Extent> other)
#endif #endif
// operator> // operator>
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, template <typename CharT, std::size_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) bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other)
@ -615,7 +618,7 @@ bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other)
} }
template < template <
typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename CharT, std::size_t Extent = gsl::dynamic_extent, typename T,
typename = std::enable_if_t< typename = 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>>
@ -630,7 +633,7 @@ bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other)
// so the cases below are already covered by the previous operators // so the cases below are already covered by the previous operators
template < template <
typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename CharT, std::size_t Extent = gsl::dynamic_extent, typename T,
typename DataType = typename T::value_type, typename DataType = typename T::value_type,
typename = std::enable_if_t< typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value && !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
@ -643,7 +646,7 @@ bool operator>(gsl::basic_string_span<CharT, Extent> one, const T& other)
} }
template < template <
typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename CharT, std::size_t Extent = gsl::dynamic_extent, typename T,
typename DataType = typename T::value_type, typename DataType = typename T::value_type,
typename = std::enable_if_t< typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value && !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
@ -657,7 +660,7 @@ bool operator>(const T& one, gsl::basic_string_span<CharT, Extent> other)
#endif #endif
// operator >= // operator >=
template <typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, template <typename CharT, std::size_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) bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other)
@ -666,7 +669,7 @@ bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other)
} }
template < template <
typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename CharT, std::size_t Extent = gsl::dynamic_extent, typename T,
typename = std::enable_if_t< typename = 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>>
@ -681,7 +684,7 @@ bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other)
// so the cases below are already covered by the previous operators // so the cases below are already covered by the previous operators
template < template <
typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename CharT, std::size_t Extent = gsl::dynamic_extent, typename T,
typename DataType = typename T::value_type, typename DataType = typename T::value_type,
typename = std::enable_if_t< typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value && !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
@ -694,7 +697,7 @@ bool operator>=(gsl::basic_string_span<CharT, Extent> one, const T& other)
} }
template < template <
typename CharT, std::ptrdiff_t Extent = gsl::dynamic_extent, typename T, typename CharT, std::size_t Extent = gsl::dynamic_extent, typename T,
typename DataType = typename T::value_type, typename DataType = typename T::value_type,
typename = std::enable_if_t< typename = std::enable_if_t<
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value && !gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&

View File

@ -45,14 +45,38 @@ if(MSVC) # MSVC or simulating MSVC
/EHsc /EHsc
/W4 /W4
/WX /WX
$<$<CXX_COMPILER_ID:MSVC>:
/wd4996 # Use of function or classes marked [[deprecated]]
/wd26409 # CppCoreCheck - GTest
/wd26426 # CppCoreCheck - GTest
/wd26440 # CppCoreCheck - GTest
/wd26446 # CppCoreCheck - prefer gsl::at()
/wd26472 # CppCoreCheck - use gsl::narrow(_cast)
/wd26481 # CppCoreCheck - use span instead of pointer arithmetic
$<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,1920>: # VS2015
/wd4189 # variable is initialized but not referenced
$<$<NOT:$<CONFIG:Debug>>: # Release, RelWithDebInfo
/wd4702 # Unreachable code
>
>
>
$<$<CXX_COMPILER_ID:Clang>: $<$<CXX_COMPILER_ID:Clang>:
-Weverything -Weverything
-Wno-c++98-compat -Wno-c++98-compat
-Wno-c++98-compat-pedantic -Wno-c++98-compat-pedantic
-Wno-covered-switch-default # GTest
-Wno-deprecated-declarations # Allow tests for [[deprecated]] elements
-Wno-global-constructors # GTest
-Wno-language-extension-token # GTest gtest-port.h
-Wno-missing-braces -Wno-missing-braces
-Wno-missing-prototypes -Wno-missing-prototypes
-Wno-unknown-attributes -Wno-shift-sign-overflow # GTest gtest-port.h
$<$<EQUAL:${GSL_CXX_STANDARD},14>:-Wno-unused-member-function> -Wno-undef # GTest
-Wno-used-but-marked-unused # GTest EXPECT_DEATH
$<$<EQUAL:${GSL_CXX_STANDARD},14>: # no support for [[maybe_unused]]
-Wno-unused-member-function
-Wno-unused-variable
>
> >
) )
else() else()
@ -67,16 +91,23 @@ else()
-Wpedantic -Wpedantic
-Wshadow -Wshadow
-Wsign-conversion -Wsign-conversion
-Wno-deprecated-declarations # Allow tests for [[deprecated]] elements
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>: $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
-Weverything -Weverything
-Wno-c++98-compat -Wno-c++98-compat
-Wno-c++98-compat-pedantic -Wno-c++98-compat-pedantic
-Wno-missing-braces -Wno-missing-braces
-Wno-covered-switch-default # GTest
-Wno-global-constructors # GTest
-Wno-missing-prototypes -Wno-missing-prototypes
-Wno-padded -Wno-padded
-Wno-unknown-attributes -Wno-unknown-attributes
$<$<EQUAL:${GSL_CXX_STANDARD},14>:-Wno-unused-member-function> -Wno-used-but-marked-unused # GTest EXPECT_DEATH
-Wno-weak-vtables -Wno-weak-vtables
$<$<EQUAL:${GSL_CXX_STANDARD},14>: # no support for [[maybe_unused]]
-Wno-unused-member-function
-Wno-unused-variable
>
> >
$<$<CXX_COMPILER_ID:Clang>: $<$<CXX_COMPILER_ID:Clang>:
$<$<AND:$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,4.99>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>: $<$<AND:$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,4.99>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>:
@ -88,6 +119,21 @@ else()
$<$<EQUAL:${GSL_CXX_STANDARD},17>:-Wno-undefined-func-template> $<$<EQUAL:${GSL_CXX_STANDARD},17>:-Wno-undefined-func-template>
> >
> >
$<$<CXX_COMPILER_ID:GNU>:
-Wdouble-promotion # float implicit to double
-Wlogical-op # suspicious uses of logical operators
$<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>:
-Wduplicated-cond # duplicated if-else conditions
-Wmisleading-indentation
-Wnull-dereference
$<$<EQUAL:${GSL_CXX_STANDARD},14>: # no support for [[maybe_unused]]
-Wno-unused-variable
>
>
$<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,7>>:
-Wduplicated-branches # identical if-else branches
>
>
) )
endif(MSVC) endif(MSVC)
@ -114,6 +160,8 @@ function(add_gsl_test name)
endfunction() endfunction()
add_gsl_test(span_tests) add_gsl_test(span_tests)
add_gsl_test(span_ext_tests)
add_gsl_test(span_compatibility_tests)
add_gsl_test(multi_span_tests) add_gsl_test(multi_span_tests)
add_gsl_test(strided_span_tests) add_gsl_test(strided_span_tests)
add_gsl_test(string_span_tests) add_gsl_test(string_span_tests)
@ -140,14 +188,18 @@ endforeach(flag_var)
# please try to keep entries ordered =) # please try to keep entries ordered =)
add_library(gsl_tests_config_noexcept INTERFACE) add_library(gsl_tests_config_noexcept INTERFACE)
if(MSVC) # MSVC or simulating MSVC if(MSVC) # MSVC or simulating MSVC
target_compile_definitions(gsl_tests_config_noexcept INTERFACE
_HAS_EXCEPTIONS=0 # disable exceptions in the Microsoft STL
)
target_compile_options(gsl_tests_config_noexcept INTERFACE target_compile_options(gsl_tests_config_noexcept INTERFACE
${GSL_CPLUSPLUS_OPT} ${GSL_CPLUSPLUS_OPT}
/EHsc
/W4 /W4
/WX /WX
$<$<CXX_COMPILER_ID:MSVC>: $<$<CXX_COMPILER_ID:MSVC>:
/wd4577 /wd4577
/wd4702 /wd4702
/wd26440 # CppCoreCheck - GTest
/wd26446 # CppCoreCheck - prefer gsl::at()
> >
$<$<CXX_COMPILER_ID:Clang>: $<$<CXX_COMPILER_ID:Clang>:
-Weverything -Weverything
@ -178,6 +230,22 @@ else()
-Wno-unknown-attributes -Wno-unknown-attributes
-Wno-weak-vtables -Wno-weak-vtables
> >
$<$<CXX_COMPILER_ID:GNU>:
-Wdouble-promotion # float implicit to double
-Wlogical-op # suspicious uses of logical operators
-Wuseless-cast # casting to its own type
$<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>:
-Wduplicated-cond # duplicated if-else conditions
-Wmisleading-indentation
-Wnull-dereference
>
$<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,7>>:
-Wduplicated-branches # identical if-else branches
>
$<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,8>>:
-Wcast-align=strict # increase alignment (i.e. char* to int*)
>
>
) )
endif(MSVC) endif(MSVC)

View File

@ -4,7 +4,7 @@ project(googletest-download NONE)
include(ExternalProject) include(ExternalProject)
ExternalProject_Add(googletest ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG master GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""

View File

@ -14,25 +14,6 @@
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch
#endif
#if __clang__ || __GNUC__
// disable warnings from gtest
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wundef"
#endif // __clang__ || __GNUC__
#if __clang__
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override"
#endif // __clang__
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gsl/gsl_algorithm> // for copy #include <gsl/gsl_algorithm> // for copy
#include <gsl/span> // for span #include <gsl/span> // for span
@ -244,7 +225,3 @@ TEST(algorithm_tests, small_destination_span)
copy(src_span_static, dst_span_static); copy(src_span_static, dst_span_static);
#endif #endif
} }
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif // __clang__ || __GNUC__

View File

@ -14,25 +14,6 @@
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch
#endif
#if __clang__ || __GNUC__
//disable warnings from gtest
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wundef"
#endif // __clang__ || __GNUC__
#if __clang__
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override"
#endif // __clang__
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gsl/gsl_assert> // for fail_fast (ptr only), Ensures, Expects #include <gsl/gsl_assert> // for fail_fast (ptr only), Ensures, Expects
@ -78,7 +59,3 @@ TEST(assertion_tests, ensures)
EXPECT_TRUE(g(2) == 3); EXPECT_TRUE(g(2) == 3);
EXPECT_DEATH(g(9), deathstring); EXPECT_DEATH(g(9), deathstring);
} }
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif // __clang__ || __GNUC__

View File

@ -14,25 +14,6 @@
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch
#endif
#if __clang__ || __GNUC__
//disable warnings from gtest
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wundef"
#endif // __clang__ || __GNUC__
#if __clang__
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override"
#endif // __clang__
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gsl/gsl_util> // for at #include <gsl/gsl_util> // for at
@ -152,7 +133,3 @@ static constexpr bool test_constexpr()
static_assert(test_constexpr(), "FAIL"); static_assert(test_constexpr(), "FAIL");
#endif #endif
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif // __clang__ || __GNUC__

View File

@ -14,28 +14,6 @@
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch
#pragma warning(disable : 4996) // use of function or classes marked [[deprecated]]
#endif
#if __clang__ || __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
//disable warnings from gtest
#pragma GCC diagnostic ignored "-Wundef"
#endif // __clang__ || __GNUC__
#if __clang__
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override"
#endif // __clang__
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gsl/multi_span> // for static_bounds, static_bounds_dynamic_range_t #include <gsl/multi_span> // for static_bounds, static_bounds_dynamic_range_t
@ -122,7 +100,3 @@ TEST(bounds_tests, bounds_convertible)
#ifdef CONFIRM_COMPILATION_ERRORS #ifdef CONFIRM_COMPILATION_ERRORS
copy(src_span_static, dst_span_static); copy(src_span_static, dst_span_static);
#endif #endif
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif // __clang__ || __GNUC__

View File

@ -14,25 +14,6 @@
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426)
#endif // _MSC_VER
#if __clang__ || __GNUC__
//disable warnings from gtest
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wundef"
#endif // __clang__ || __GNUC__
#if __clang__
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override"
#endif // __clang__
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gsl/gsl_byte> // for to_byte, to_integer, byte, operator&, ope... #include <gsl/gsl_byte> // for to_byte, to_integer, byte, operator&, ope...
@ -146,7 +127,3 @@ TEST(byte_tests, aliasing)
#ifdef CONFIRM_COMPILATION_ERRORS #ifdef CONFIRM_COMPILATION_ERRORS
copy(src_span_static, dst_span_static); copy(src_span_static, dst_span_static);
#endif #endif
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif // __clang__ || __GNUC__

View File

@ -14,29 +14,6 @@
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch
#pragma warning(disable : 4996) // multi_span is in the process of being deprecated.
// Suppressing warnings until it is completely removed
#endif
#if __clang__ || __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
//disable warnings from gtest
#pragma GCC diagnostic ignored "-Wundef"
#endif // __clang__ || __GNUC__
#if __clang__
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override"
#endif // __clang__
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gsl/gsl_byte> // for byte #include <gsl/gsl_byte> // for byte
@ -1884,7 +1861,3 @@ TEST(multi_span_test, iterator)
#ifdef CONFIRM_COMPILATION_ERRORS #ifdef CONFIRM_COMPILATION_ERRORS
copy(src_span_static, dst_span_static); copy(src_span_static, dst_span_static);
#endif #endif
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif // __clang__ || __GNUC__

View File

@ -14,28 +14,6 @@
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch
// Fix VS2015 build breaks in Release
#pragma warning(disable : 4702) // unreachable code
#endif
#if __clang__ || __GNUC__
//disable warnings from gtest
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wundef"
#endif // __clang__ || __GNUC__
#if __clang__
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override"
#endif // __clang__
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gsl/pointers> // for not_null, operator<, operator<=, operator> #include <gsl/pointers> // for not_null, operator<, operator<=, operator>
@ -555,10 +533,3 @@ TEST(notnull_tests, TestMakeNotNull)
} }
#endif #endif
} }
static_assert(std::is_nothrow_move_constructible<not_null<void*>>::value,
"not_null must be no-throw move constructible");
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif // __clang__ || __GNUC__

View File

@ -14,26 +14,6 @@
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch
#endif
#if __clang__ || __GNUC__
//disable warnings from gtest
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wundef"
#endif // __clang__ || __GNUC__
#if __clang__
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override"
#endif // __clang__
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gsl/pointers> // for owner #include <gsl/pointers> // for owner
@ -61,7 +41,3 @@ TEST(owner_tests, check_pointer_constraint)
} }
#endif #endif
} }
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif // __clang__ || __GNUC__

File diff suppressed because it is too large Load Diff

360
tests/span_ext_tests.cpp Normal file
View File

@ -0,0 +1,360 @@
///////////////////////////////////////////////////////////////////////////////
//
// 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 <gtest/gtest.h>
#include <gsl/gsl_util> // for narrow_cast, at
#include <gsl/span_ext> // for operator==, operator!=, make_span
#include <array> // for array
#include <iostream> // for cerr
#include <vector> // for vector
using namespace std;
using namespace gsl;
namespace
{
static constexpr char deathstring[] = "Expected Death";
} // namespace
TEST(span_ext_test, make_span_from_pointer_length_constructor)
{
std::set_terminate([] {
std::cerr << "Expected Death. from_pointer_length_constructor";
std::abort();
});
int arr[4] = {1, 2, 3, 4};
{
auto s = make_span(&arr[0], 2);
EXPECT_TRUE(s.size() == 2);
EXPECT_TRUE(s.data() == &arr[0]);
EXPECT_TRUE(s[0] == 1);
EXPECT_TRUE(s[1] == 2);
}
{
int* p = nullptr;
auto s = make_span(p, narrow_cast<span<int>::size_type>(0));
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == nullptr);
}
{
int* p = nullptr;
auto workaround_macro = [=]() { make_span(p, 2); };
EXPECT_DEATH(workaround_macro(), deathstring);
}
}
TEST(span_ext_test, make_span_from_pointer_pointer_construction)
{
int arr[4] = {1, 2, 3, 4};
{
auto s = make_span(&arr[0], &arr[2]);
EXPECT_TRUE(s.size() == 2);
EXPECT_TRUE(s.data() == &arr[0]);
EXPECT_TRUE(s[0] == 1);
EXPECT_TRUE(s[1] == 2);
}
{
auto s = make_span(&arr[0], &arr[0]);
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == &arr[0]);
}
{
int* p = nullptr;
auto s = make_span(p, p);
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == nullptr);
}
}
TEST(span_ext_test, make_span_from_array_constructor)
{
int arr[5] = {1, 2, 3, 4, 5};
int arr2d[2][3] = {1, 2, 3, 4, 5, 6};
int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
{
const auto s = make_span(arr);
EXPECT_TRUE(s.size() == 5);
EXPECT_TRUE(s.data() == std::addressof(arr[0]));
}
{
const auto s = make_span(std::addressof(arr2d[0]), 1);
EXPECT_TRUE(s.size() == 1);
EXPECT_TRUE(s.data() == std::addressof(arr2d[0]));
}
{
const auto s = make_span(std::addressof(arr3d[0]), 1);
EXPECT_TRUE(s.size() == 1);
EXPECT_TRUE(s.data() == std::addressof(arr3d[0]));
}
}
TEST(span_ext_test, make_span_from_dynamic_array_constructor)
{
double(*arr)[3][4] = new double[100][3][4];
{
auto s = make_span(&arr[0][0][0], 10);
EXPECT_TRUE(s.size() == 10);
EXPECT_TRUE(s.data() == &arr[0][0][0]);
}
delete[] arr;
}
TEST(span_ext_test, make_span_from_std_array_constructor)
{
std::array<int, 4> arr = {1, 2, 3, 4};
{
auto s = make_span(arr);
EXPECT_TRUE(s.size() == arr.size());
EXPECT_TRUE(s.data() == arr.data());
}
// This test checks for the bug found in gcc 6.1, 6.2, 6.3, 6.4, 6.5 7.1, 7.2, 7.3 - issue #590
{
span<int> s1 = make_span(arr);
static span<int> s2;
s2 = s1;
#if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \
__GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__)
// Known to be broken in gcc 6.4 and 6.5 with optimizations
// Issue in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83116
EXPECT_TRUE(s1.size() == 4);
EXPECT_TRUE(s2.size() == 0);
#else
EXPECT_TRUE(s1.size() == s2.size());
#endif
}
}
TEST(span_ext_test, make_span_from_const_std_array_constructor)
{
const std::array<int, 4> arr = {1, 2, 3, 4};
{
auto s = make_span(arr);
EXPECT_TRUE(s.size() == arr.size());
EXPECT_TRUE(s.data() == arr.data());
}
}
TEST(span_ext_test, make_span_from_std_array_const_constructor)
{
std::array<const int, 4> arr = {1, 2, 3, 4};
{
auto s = make_span(arr);
EXPECT_TRUE(s.size() == arr.size());
EXPECT_TRUE(s.data() == arr.data());
}
}
TEST(span_ext_test, make_span_from_container_constructor)
{
std::vector<int> v = {1, 2, 3};
const std::vector<int> cv = v;
{
auto s = make_span(v);
EXPECT_TRUE(s.size() == v.size());
EXPECT_TRUE(s.data() == v.data());
auto cs = make_span(cv);
EXPECT_TRUE(cs.size() == cv.size());
EXPECT_TRUE(cs.data() == cv.data());
}
}
TEST(span_test, interop_with_gsl_at)
{
int arr[5] = {1, 2, 3, 4, 5};
span<int> s{arr};
EXPECT_TRUE(at(s, 0) == 1);
EXPECT_TRUE(at(s, 1) == 2);
}
TEST(span_ext_test, iterator_free_functions)
{
int a[] = {1, 2, 3, 4};
span<int> s{a};
EXPECT_TRUE((std::is_same<decltype(s.begin()), decltype(begin(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.end()), decltype(end(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.cbegin()), decltype(cbegin(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.cend()), decltype(cend(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.rbegin()), decltype(rbegin(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.rend()), decltype(rend(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.crbegin()), decltype(crbegin(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.crend()), decltype(crend(s))>::value));
EXPECT_TRUE(s.begin() == begin(s));
EXPECT_TRUE(s.end() == end(s));
EXPECT_TRUE(s.cbegin() == cbegin(s));
EXPECT_TRUE(s.cend() == cend(s));
EXPECT_TRUE(s.rbegin() == rbegin(s));
EXPECT_TRUE(s.rend() == rend(s));
EXPECT_TRUE(s.crbegin() == crbegin(s));
EXPECT_TRUE(s.crend() == crend(s));
}
TEST(span_ext_test, ssize_free_function)
{
int a[] = {1, 2, 3, 4};
span<int> s{a};
EXPECT_FALSE((std::is_same<decltype(s.size()), decltype(ssize(s))>::value));
EXPECT_TRUE(s.size() == static_cast<std::size_t>(ssize(s)));
}
TEST(span_ext_test, comparison_operators)
{
{
span<int> s1;
span<int> s2;
EXPECT_TRUE(s1 == s2);
EXPECT_FALSE(s1 != s2);
EXPECT_FALSE(s1 < s2);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s1 >= s2);
EXPECT_TRUE(s2 == s1);
EXPECT_FALSE(s2 != s1);
EXPECT_FALSE(s2 != s1);
EXPECT_TRUE(s2 <= s1);
EXPECT_FALSE(s2 > s1);
EXPECT_TRUE(s2 >= s1);
}
{
int arr[] = {2, 1};
span<int> s1 = arr;
span<int> s2 = arr;
EXPECT_TRUE(s1 == s2);
EXPECT_FALSE(s1 != s2);
EXPECT_FALSE(s1 < s2);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s1 >= s2);
EXPECT_TRUE(s2 == s1);
EXPECT_FALSE(s2 != s1);
EXPECT_FALSE(s2 < s1);
EXPECT_TRUE(s2 <= s1);
EXPECT_FALSE(s2 > s1);
EXPECT_TRUE(s2 >= s1);
}
{
int arr[] = {2, 1}; // bigger
span<int> s1;
span<int> s2 = arr;
EXPECT_TRUE(s1 != s2);
EXPECT_TRUE(s2 != s1);
EXPECT_FALSE(s1 == s2);
EXPECT_FALSE(s2 == s1);
EXPECT_TRUE(s1 < s2);
EXPECT_FALSE(s2 < s1);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s2 <= s1);
EXPECT_TRUE(s2 > s1);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s2 >= s1);
EXPECT_FALSE(s1 >= s2);
}
{
int arr1[] = {1, 2};
int arr2[] = {1, 2};
span<int> s1 = arr1;
span<int> s2 = arr2;
EXPECT_TRUE(s1 == s2);
EXPECT_FALSE(s1 != s2);
EXPECT_FALSE(s1 < s2);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s1 >= s2);
EXPECT_TRUE(s2 == s1);
EXPECT_FALSE(s2 != s1);
EXPECT_FALSE(s2 < s1);
EXPECT_TRUE(s2 <= s1);
EXPECT_FALSE(s2 > s1);
EXPECT_TRUE(s2 >= s1);
}
{
int arr[] = {1, 2, 3};
span<int> s1 = {&arr[0], 2}; // shorter
span<int> s2 = arr; // longer
EXPECT_TRUE(s1 != s2);
EXPECT_TRUE(s2 != s1);
EXPECT_FALSE(s1 == s2);
EXPECT_FALSE(s2 == s1);
EXPECT_TRUE(s1 < s2);
EXPECT_FALSE(s2 < s1);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s2 <= s1);
EXPECT_TRUE(s2 > s1);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s2 >= s1);
EXPECT_FALSE(s1 >= s2);
}
{
int arr1[] = {1, 2}; // smaller
int arr2[] = {2, 1}; // bigger
span<int> s1 = arr1;
span<int> s2 = arr2;
EXPECT_TRUE(s1 != s2);
EXPECT_TRUE(s2 != s1);
EXPECT_FALSE(s1 == s2);
EXPECT_FALSE(s2 == s1);
EXPECT_TRUE(s1 < s2);
EXPECT_FALSE(s2 < s1);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s2 <= s1);
EXPECT_TRUE(s2 > s1);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s2 >= s1);
EXPECT_FALSE(s1 >= s2);
}
}

View File

@ -14,27 +14,6 @@
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426 26497 4189 4996)
#endif
#if __clang__ || __GNUC__
//disable warnings from gtest
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wundef"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif // __clang__ || __GNUC__
#if __clang__
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override"
#endif // __clang__
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gsl/gsl_byte> // for byte #include <gsl/gsl_byte> // for byte
@ -46,15 +25,11 @@
#include <iterator> // for reverse_iterator, operator-, operator== #include <iterator> // for reverse_iterator, operator-, operator==
#include <memory> // for unique_ptr, shared_ptr, make_unique, allo... #include <memory> // for unique_ptr, shared_ptr, make_unique, allo...
#include <regex> // for match_results, sub_match, match_results<>... #include <regex> // for match_results, sub_match, match_results<>...
#include <stddef.h> // for ptrdiff_t #include <cstddef> // for ptrdiff_t
#include <string> // for string #include <string> // for string
#include <type_traits> // for integral_constant<>::value, is_default_co... #include <type_traits> // for integral_constant<>::value, is_default_co...
#include <vector> // for vector #include <vector> // for vector
#include <utility>
namespace gsl
{
struct fail_fast;
} // namespace gsl
using namespace std; using namespace std;
using namespace gsl; using namespace gsl;
@ -131,17 +106,17 @@ TEST(span_test, from_nullptr_size_constructor)
std::abort(); std::abort();
}); });
{ {
span<int> s{nullptr, narrow_cast<span<int>::index_type>(0)}; span<int> s{nullptr, narrow_cast<span<int>::size_type>(0)};
EXPECT_TRUE(s.size() == 0); EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == nullptr); EXPECT_TRUE(s.data() == nullptr);
span<int> cs{nullptr, narrow_cast<span<int>::index_type>(0)}; span<int> cs{nullptr, narrow_cast<span<int>::size_type>(0)};
EXPECT_TRUE(cs.size() == 0); EXPECT_TRUE(cs.size() == 0);
EXPECT_TRUE(cs.data() == nullptr); EXPECT_TRUE(cs.data() == nullptr);
} }
{ {
auto workaround_macro = []() { auto workaround_macro = []() {
const span<int, 1> s{nullptr, narrow_cast<span<int>::index_type>(0)}; const span<int, 1> s{nullptr, narrow_cast<span<int>::size_type>(0)};
}; };
EXPECT_DEATH(workaround_macro(), deathstring); EXPECT_DEATH(workaround_macro(), deathstring);
} }
@ -160,11 +135,11 @@ TEST(span_test, from_nullptr_size_constructor)
EXPECT_DEATH(const_workaround_macro(), deathstring); EXPECT_DEATH(const_workaround_macro(), deathstring);
} }
{ {
span<int*> s{nullptr, narrow_cast<span<int>::index_type>(0)}; span<int*> s{nullptr, narrow_cast<span<int>::size_type>(0)};
EXPECT_TRUE(s.size() == 0); EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == nullptr); EXPECT_TRUE(s.data() == nullptr);
span<const int*> cs{nullptr, narrow_cast<span<int>::index_type>(0)}; span<const int*> cs{nullptr, narrow_cast<span<int>::size_type>(0)};
EXPECT_TRUE(cs.size() == 0); EXPECT_TRUE(cs.size() == 0);
EXPECT_TRUE(cs.data() == nullptr); EXPECT_TRUE(cs.data() == nullptr);
} }
@ -182,29 +157,21 @@ TEST(span_test, from_pointer_length_constructor)
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
{ {
{ {
span<int> s = {&arr[0], i}; span<int> s = {&arr[0], narrow_cast<std::size_t>(i)};
EXPECT_TRUE(s.size() == i); EXPECT_TRUE(s.size() == narrow_cast<std::size_t>(i));
EXPECT_TRUE(s.data() == &arr[0]); EXPECT_TRUE(s.data() == &arr[0]);
EXPECT_TRUE(s.empty() == (i == 0)); EXPECT_TRUE(s.empty() == (i == 0));
for (int j = 0; j < i; ++j) for (int j = 0; j < i; ++j)
{ EXPECT_TRUE(arr[j] == s[narrow_cast<std::size_t>(j)]);
EXPECT_TRUE(arr[j] == s[j]);
EXPECT_TRUE(arr[j] == s.at(j));
EXPECT_TRUE(arr[j] == s(j));
}
} }
{ {
span<int> s = {&arr[i], 4 - narrow_cast<ptrdiff_t>(i)}; span<int> s = {&arr[i], 4 - narrow_cast<std::size_t>(i)};
EXPECT_TRUE(s.size() == 4 - i); EXPECT_TRUE(s.size() == 4 - narrow_cast<std::size_t>(i));
EXPECT_TRUE(s.data() == &arr[i]); EXPECT_TRUE(s.data() == &arr[i]);
EXPECT_TRUE(s.empty() == ((4 - i) == 0)); EXPECT_TRUE(s.empty() == ((4 - i) == 0));
for (int j = 0; j < 4 - i; ++j) for (int j = 0; j < 4 - i; ++j)
{ EXPECT_TRUE(arr[j + i] == s[narrow_cast<std::size_t>(j)]);
EXPECT_TRUE(arr[j + i] == s[j]);
EXPECT_TRUE(arr[j + i] == s.at(j));
EXPECT_TRUE(arr[j + i] == s(j));
}
} }
} }
} }
@ -219,7 +186,7 @@ TEST(span_test, from_pointer_length_constructor)
{ {
int* p = nullptr; int* p = nullptr;
span<int> s{p, narrow_cast<span<int>::index_type>(0)}; span<int> s{p, narrow_cast<span<int>::size_type>(0)};
EXPECT_TRUE(s.size() == 0); EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == nullptr); EXPECT_TRUE(s.data() == nullptr);
} }
@ -229,27 +196,6 @@ TEST(span_test, from_pointer_length_constructor)
auto workaround_macro = [=]() { const span<int> s{p, 2}; }; auto workaround_macro = [=]() { const span<int> s{p, 2}; };
EXPECT_DEATH(workaround_macro(), deathstring); EXPECT_DEATH(workaround_macro(), deathstring);
} }
{
auto s = make_span(&arr[0], 2);
EXPECT_TRUE(s.size() == 2);
EXPECT_TRUE(s.data() == &arr[0]);
EXPECT_TRUE(s[0] == 1);
EXPECT_TRUE(s[1] == 2);
}
{
int* p = nullptr;
auto s = make_span(p, narrow_cast<span<int>::index_type>(0));
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == nullptr);
}
{
int* p = nullptr;
auto workaround_macro = [=]() { make_span(p, 2); };
EXPECT_DEATH(workaround_macro(), deathstring);
}
} }
TEST(span_test, from_pointer_pointer_construction) TEST(span_test, from_pointer_pointer_construction)
@ -316,27 +262,6 @@ TEST(span_test, from_pointer_pointer_construction)
// auto workaround_macro = [&]() { span<int> s{&arr[0], p}; }; // auto workaround_macro = [&]() { span<int> s{&arr[0], p}; };
// EXPECT_DEATH(workaround_macro(), deathstring); // EXPECT_DEATH(workaround_macro(), deathstring);
//} //}
{
auto s = make_span(&arr[0], &arr[2]);
EXPECT_TRUE(s.size() == 2);
EXPECT_TRUE(s.data() == &arr[0]);
EXPECT_TRUE(s[0] == 1);
EXPECT_TRUE(s[1] == 2);
}
{
auto s = make_span(&arr[0], &arr[0]);
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == &arr[0]);
}
{
int* p = nullptr;
auto s = make_span(p, p);
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == nullptr);
}
} }
TEST(span_test, from_array_constructor) TEST(span_test, from_array_constructor)
@ -426,24 +351,6 @@ TEST(span_test, from_array_constructor)
EXPECT_TRUE(s.size() == 1); EXPECT_TRUE(s.size() == 1);
} }
{
const auto s = make_span(arr);
EXPECT_TRUE(s.size() == 5);
EXPECT_TRUE(s.data() == std::addressof(arr[0]));
}
{
const auto s = make_span(std::addressof(arr2d[0]), 1);
EXPECT_TRUE(s.size() == 1);
EXPECT_TRUE(s.data() == std::addressof(arr2d[0]));
}
{
const auto s = make_span(std::addressof(arr3d[0]), 1);
EXPECT_TRUE(s.size() == 1);
EXPECT_TRUE(s.data() == std::addressof(arr3d[0]));
}
AddressOverloaded ao_arr[5] = {}; AddressOverloaded ao_arr[5] = {};
{ {
@ -463,12 +370,6 @@ TEST(span_test, from_array_constructor)
EXPECT_TRUE(s.data() == &arr[0][0][0]); EXPECT_TRUE(s.data() == &arr[0][0][0]);
} }
{
auto s = make_span(&arr[0][0][0], 10);
EXPECT_TRUE(s.size() == 10);
EXPECT_TRUE(s.data() == &arr[0][0][0]);
}
delete[] arr; delete[] arr;
} }
@ -478,21 +379,21 @@ TEST(span_test, from_array_constructor)
{ {
span<int> s{arr}; span<int> s{arr};
EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size())); EXPECT_TRUE(s.size() == arr.size());
EXPECT_TRUE(s.data() == arr.data()); EXPECT_TRUE(s.data() == arr.data());
span<const int> cs{arr}; span<const int> cs{arr};
EXPECT_TRUE(cs.size() == narrow_cast<ptrdiff_t>(arr.size())); EXPECT_TRUE(cs.size() == arr.size());
EXPECT_TRUE(cs.data() == arr.data()); EXPECT_TRUE(cs.data() == arr.data());
} }
{ {
span<int, 4> s{arr}; span<int, 4> s{arr};
EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size())); EXPECT_TRUE(s.size() == arr.size());
EXPECT_TRUE(s.data() == arr.data()); EXPECT_TRUE(s.data() == arr.data());
span<const int, 4> cs{arr}; span<const int, 4> cs{arr};
EXPECT_TRUE(cs.size() == narrow_cast<ptrdiff_t>(arr.size())); EXPECT_TRUE(cs.size() == arr.size());
EXPECT_TRUE(cs.data() == arr.data()); EXPECT_TRUE(cs.data() == arr.data());
} }
@ -507,7 +408,7 @@ TEST(span_test, from_array_constructor)
{ {
span<AddressOverloaded, 4> fs{ao_arr}; span<AddressOverloaded, 4> fs{ao_arr};
EXPECT_TRUE(fs.size() == narrow_cast<ptrdiff_t>(ao_arr.size())); EXPECT_TRUE(fs.size() == ao_arr.size());
EXPECT_TRUE(ao_arr.data() == fs.data()); EXPECT_TRUE(ao_arr.data() == fs.data());
} }
@ -550,30 +451,6 @@ TEST(span_test, from_array_constructor)
// try to take a temporary std::array // try to take a temporary std::array
take_a_span(get_an_array()); take_a_span(get_an_array());
} }
{
auto s = make_span(arr);
EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size()));
EXPECT_TRUE(s.data() == arr.data());
}
// This test checks for the bug found in gcc 6.1, 6.2, 6.3, 6.4, 6.5 7.1, 7.2, 7.3 - issue #590
{
span<int> s1 = make_span(arr);
static span<int> s2;
s2 = s1;
#if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \
__GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__)
// Known to be broken in gcc 6.4 and 6.5 with optimizations
// Issue in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83116
EXPECT_TRUE(s1.size() == 4);
EXPECT_TRUE(s2.size() == 0);
#else
EXPECT_TRUE(s1.size() == s2.size());
#endif
}
} }
TEST(span_test, from_const_std_array_constructor) TEST(span_test, from_const_std_array_constructor)
@ -582,13 +459,13 @@ TEST(span_test, from_array_constructor)
{ {
span<const int> s{arr}; span<const int> s{arr};
EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size())); EXPECT_TRUE(s.size() == arr.size());
EXPECT_TRUE(s.data() == arr.data()); EXPECT_TRUE(s.data() == arr.data());
} }
{ {
span<const int, 4> s{arr}; span<const int, 4> s{arr};
EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size())); EXPECT_TRUE(s.size() == arr.size());
EXPECT_TRUE(s.data() == arr.data()); EXPECT_TRUE(s.data() == arr.data());
} }
@ -596,7 +473,7 @@ TEST(span_test, from_array_constructor)
{ {
span<const AddressOverloaded, 4> s{ao_arr}; span<const AddressOverloaded, 4> s{ao_arr};
EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(ao_arr.size())); EXPECT_TRUE(s.size() == ao_arr.size());
EXPECT_TRUE(s.data() == ao_arr.data()); EXPECT_TRUE(s.data() == ao_arr.data());
} }
@ -624,12 +501,6 @@ TEST(span_test, from_array_constructor)
// try to take a temporary std::array // try to take a temporary std::array
take_a_span(get_an_array()); take_a_span(get_an_array());
} }
{
auto s = make_span(arr);
EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size()));
EXPECT_TRUE(s.data() == arr.data());
}
} }
TEST(span_test, from_std_array_const_constructor) TEST(span_test, from_std_array_const_constructor)
@ -638,13 +509,13 @@ TEST(span_test, from_array_constructor)
{ {
span<const int> s{arr}; span<const int> s{arr};
EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size())); EXPECT_TRUE(s.size() == arr.size());
EXPECT_TRUE(s.data() == arr.data()); EXPECT_TRUE(s.data() == arr.data());
} }
{ {
span<const int, 4> s{arr}; span<const int, 4> s{arr};
EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size())); EXPECT_TRUE(s.size() == arr.size());
EXPECT_TRUE(s.data() == arr.data()); EXPECT_TRUE(s.data() == arr.data());
} }
@ -669,12 +540,6 @@ TEST(span_test, from_array_constructor)
span<int, 4> s{arr}; span<int, 4> s{arr};
} }
#endif #endif
{
auto s = make_span(arr);
EXPECT_TRUE(s.size() == narrow_cast<ptrdiff_t>(arr.size()));
EXPECT_TRUE(s.data() == arr.data());
}
} }
TEST(span_test, from_container_constructor) TEST(span_test, from_container_constructor)
@ -684,11 +549,11 @@ TEST(span_test, from_array_constructor)
{ {
span<int> s{v}; span<int> s{v};
EXPECT_TRUE(s.size() == narrow_cast<std::ptrdiff_t>(v.size())); EXPECT_TRUE(s.size() == v.size());
EXPECT_TRUE(s.data() == v.data()); EXPECT_TRUE(s.data() == v.data());
span<const int> cs{v}; span<const int> cs{v};
EXPECT_TRUE(cs.size() == narrow_cast<std::ptrdiff_t>(v.size())); EXPECT_TRUE(cs.size() == v.size());
EXPECT_TRUE(cs.data() == v.data()); EXPECT_TRUE(cs.data() == v.data());
} }
@ -698,11 +563,11 @@ TEST(span_test, from_array_constructor)
{ {
#ifdef CONFIRM_COMPILATION_ERRORS #ifdef CONFIRM_COMPILATION_ERRORS
span<char> s{str}; span<char> s{str};
EXPECT_TRUE(s.size() == narrow_cast<std::ptrdiff_t>(str.size())); EXPECT_TRUE(s.size() == str.size());
EXPECT_TRUE(s.data() == str.data())); EXPECT_TRUE(s.data() == str.data()));
#endif #endif
span<const char> cs{str}; span<const char> cs{str};
EXPECT_TRUE(cs.size() == narrow_cast<std::ptrdiff_t>(str.size())); EXPECT_TRUE(cs.size() == str.size());
EXPECT_TRUE(cs.data() == str.data()); EXPECT_TRUE(cs.data() == str.data());
} }
@ -711,7 +576,7 @@ TEST(span_test, from_array_constructor)
span<char> s{cstr}; span<char> s{cstr};
#endif #endif
span<const char> cs{cstr}; span<const char> cs{cstr};
EXPECT_TRUE(cs.size() == narrow_cast<std::ptrdiff_t>(cstr.size())); EXPECT_TRUE(cs.size() == cstr.size());
EXPECT_TRUE(cs.data() == cstr.data()); EXPECT_TRUE(cs.data() == cstr.data());
} }
@ -763,16 +628,6 @@ TEST(span_test, from_array_constructor)
span<int> s{m}; span<int> s{m};
#endif #endif
} }
{
auto s = make_span(v);
EXPECT_TRUE(s.size() == narrow_cast<std::ptrdiff_t>(v.size()));
EXPECT_TRUE(s.data() == v.data());
auto cs = make_span(cv);
EXPECT_TRUE(cs.size() == narrow_cast<std::ptrdiff_t>(cv.size()));
EXPECT_TRUE(cs.data() == cv.data());
}
} }
TEST(span_test, from_convertible_span_constructor){{span<DerivedClass> avd; TEST(span_test, from_convertible_span_constructor){{span<DerivedClass> avd;
@ -987,7 +842,7 @@ TEST(span_test, from_array_constructor)
EXPECT_TRUE(av.subspan(5).size() == 0); EXPECT_TRUE(av.subspan(5).size() == 0);
EXPECT_DEATH(av.subspan(6).size(), deathstring); EXPECT_DEATH(av.subspan(6).size(), deathstring);
const auto av2 = av.subspan(1); const auto av2 = av.subspan(1);
for (int i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == i + 2); for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == static_cast<int>(i) + 2);
} }
{ {
@ -998,53 +853,7 @@ TEST(span_test, from_array_constructor)
EXPECT_TRUE(av.subspan(5).size() == 0); EXPECT_TRUE(av.subspan(5).size() == 0);
EXPECT_DEATH(av.subspan(6).size(), deathstring); EXPECT_DEATH(av.subspan(6).size(), deathstring);
const auto av2 = av.subspan(1); const auto av2 = av.subspan(1);
for (int i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == i + 2); for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == static_cast<int>(i) + 2);
}
}
TEST(span_test, at_call)
{
std::set_terminate([] {
std::cerr << "Expected Death. at_call";
std::abort();
});
int arr[4] = {1, 2, 3, 4};
{
span<int> s = arr;
EXPECT_TRUE(s.at(0) == 1);
EXPECT_DEATH(s.at(5), deathstring);
}
{
int arr2d[2] = {1, 6};
span<int, 2> s = arr2d;
EXPECT_TRUE(s.at(0) == 1);
EXPECT_TRUE(s.at(1) == 6);
EXPECT_DEATH(s.at(2), deathstring);
}
}
TEST(span_test, operator_function_call)
{
std::set_terminate([] {
std::cerr << "Expected Death. operator_function_call";
std::abort();
});
int arr[4] = {1, 2, 3, 4};
{
span<int> s = arr;
EXPECT_TRUE(s(0) == 1);
EXPECT_DEATH(s(5), deathstring);
}
{
int arr2d[2] = {1, 6};
span<int, 2> s = arr2d;
EXPECT_TRUE(s(0) == 1);
EXPECT_TRUE(s(1) == 6);
EXPECT_DEATH(s(2), deathstring);
} }
} }
@ -1083,46 +892,6 @@ TEST(span_test, from_array_constructor)
span<int>::const_iterator cit3 = it + 4; span<int>::const_iterator cit3 = it + 4;
EXPECT_TRUE(cit3 == s.cend()); EXPECT_TRUE(cit3 == s.cend());
} }
TEST(span_test, iterator_free_functions)
{
int a[] = {1, 2, 3, 4};
span<int> s{a};
EXPECT_TRUE((std::is_same<decltype(s.begin()), decltype(begin(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.end()), decltype(end(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.cbegin()), decltype(cbegin(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.cend()), decltype(cend(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.rbegin()), decltype(rbegin(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.rend()), decltype(rend(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.crbegin()), decltype(crbegin(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.crend()), decltype(crend(s))>::value));
EXPECT_TRUE(s.begin() == begin(s));
EXPECT_TRUE(s.end() == end(s));
EXPECT_TRUE(s.cbegin() == cbegin(s));
EXPECT_TRUE(s.cend() == cend(s));
EXPECT_TRUE(s.rbegin() == rbegin(s));
EXPECT_TRUE(s.rend() == rend(s));
EXPECT_TRUE(s.crbegin() == crbegin(s));
EXPECT_TRUE(s.crend() == crend(s));
}
TEST(span_test, ssize_free_function)
{
int a[] = {1, 2, 3, 4};
span<int> s{a};
EXPECT_TRUE((std::is_same<decltype(s.size()), decltype(ssize(s))>::value));
EXPECT_TRUE(s.size() == ssize(s));
}
TEST(span_test, iterator_comparisons) TEST(span_test, iterator_comparisons)
{ {
int a[] = {1, 2, 3, 4}; int a[] = {1, 2, 3, 4};
@ -1170,6 +939,28 @@ TEST(span_test, from_array_constructor)
} }
} }
TEST(span_test, incomparable_iterators)
{
std::set_terminate([] {
std::cerr << "Expected Death. incomparable_iterators";
std::abort();
});
int a[] = {1, 2, 3, 4};
int b[] = {1, 2, 3, 4};
{
span<int> s = a;
span<int> s2 = b;
#if (__cplusplus > 201402L)
EXPECT_DEATH([[maybe_unused]] bool _ = (s.begin() == s2.begin()), deathstring);
EXPECT_DEATH([[maybe_unused]] bool _ = (s.begin() <= s2.begin()), deathstring);
#else
EXPECT_DEATH(bool _ = (s.begin() == s2.begin()), deathstring);
EXPECT_DEATH(bool _ = (s.begin() <= s2.begin()), deathstring);
#endif
}
}
TEST(span_test, begin_end) TEST(span_test, begin_end)
{ {
std::set_terminate([] { std::set_terminate([] {
@ -1302,7 +1093,11 @@ TEST(span_test, from_array_constructor)
auto beyond = s.rend(); auto beyond = s.rend();
EXPECT_TRUE(it != beyond); EXPECT_TRUE(it != beyond);
EXPECT_DEATH(auto _ = *beyond , deathstring); #if (__cplusplus > 201402L)
EXPECT_DEATH([[maybe_unused]] auto _ = *beyond , deathstring);
#else
EXPECT_DEATH(auto _ = *beyond , deathstring);
#endif
EXPECT_TRUE(beyond - first == 4); EXPECT_TRUE(beyond - first == 4);
EXPECT_TRUE(first - first == 0); EXPECT_TRUE(first - first == 0);
@ -1347,7 +1142,11 @@ TEST(span_test, from_array_constructor)
auto beyond = s.crend(); auto beyond = s.crend();
EXPECT_TRUE(it != beyond); EXPECT_TRUE(it != beyond);
EXPECT_DEATH(auto _ = *beyond, deathstring); #if (__cplusplus > 201402L)
EXPECT_DEATH([[maybe_unused]] auto _ = *beyond, deathstring);
#else
EXPECT_DEATH(auto _ = *beyond, deathstring);
#endif
EXPECT_TRUE(beyond - first == 4); EXPECT_TRUE(beyond - first == 4);
EXPECT_TRUE(first - first == 0); EXPECT_TRUE(first - first == 0);
@ -1375,130 +1174,14 @@ TEST(span_test, from_array_constructor)
} }
} }
TEST(span_test, comparison_operators)
{
{
span<int> s1;
span<int> s2;
EXPECT_TRUE(s1 == s2);
EXPECT_FALSE(s1 != s2);
EXPECT_FALSE(s1 < s2);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s1 >= s2);
EXPECT_TRUE(s2 == s1);
EXPECT_FALSE(s2 != s1);
EXPECT_FALSE(s2 != s1);
EXPECT_TRUE(s2 <= s1);
EXPECT_FALSE(s2 > s1);
EXPECT_TRUE(s2 >= s1);
}
{
int arr[] = {2, 1};
span<int> s1 = arr;
span<int> s2 = arr;
EXPECT_TRUE(s1 == s2);
EXPECT_FALSE(s1 != s2);
EXPECT_FALSE(s1 < s2);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s1 >= s2);
EXPECT_TRUE(s2 == s1);
EXPECT_FALSE(s2 != s1);
EXPECT_FALSE(s2 < s1);
EXPECT_TRUE(s2 <= s1);
EXPECT_FALSE(s2 > s1);
EXPECT_TRUE(s2 >= s1);
}
{
int arr[] = {2, 1}; // bigger
span<int> s1;
span<int> s2 = arr;
EXPECT_TRUE(s1 != s2);
EXPECT_TRUE(s2 != s1);
EXPECT_FALSE(s1 == s2);
EXPECT_FALSE(s2 == s1);
EXPECT_TRUE(s1 < s2);
EXPECT_FALSE(s2 < s1);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s2 <= s1);
EXPECT_TRUE(s2 > s1);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s2 >= s1);
EXPECT_FALSE(s1 >= s2);
}
{
int arr1[] = {1, 2};
int arr2[] = {1, 2};
span<int> s1 = arr1;
span<int> s2 = arr2;
EXPECT_TRUE(s1 == s2);
EXPECT_FALSE(s1 != s2);
EXPECT_FALSE(s1 < s2);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s1 >= s2);
EXPECT_TRUE(s2 == s1);
EXPECT_FALSE(s2 != s1);
EXPECT_FALSE(s2 < s1);
EXPECT_TRUE(s2 <= s1);
EXPECT_FALSE(s2 > s1);
EXPECT_TRUE(s2 >= s1);
}
{
int arr[] = {1, 2, 3};
span<int> s1 = {&arr[0], 2}; // shorter
span<int> s2 = arr; // longer
EXPECT_TRUE(s1 != s2);
EXPECT_TRUE(s2 != s1);
EXPECT_FALSE(s1 == s2);
EXPECT_FALSE(s2 == s1);
EXPECT_TRUE(s1 < s2);
EXPECT_FALSE(s2 < s1);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s2 <= s1);
EXPECT_TRUE(s2 > s1);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s2 >= s1);
EXPECT_FALSE(s1 >= s2);
}
{
int arr1[] = {1, 2}; // smaller
int arr2[] = {2, 1}; // bigger
span<int> s1 = arr1;
span<int> s2 = arr2;
EXPECT_TRUE(s1 != s2);
EXPECT_TRUE(s2 != s1);
EXPECT_FALSE(s1 == s2);
EXPECT_FALSE(s2 == s1);
EXPECT_TRUE(s1 < s2);
EXPECT_FALSE(s2 < s1);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s2 <= s1);
EXPECT_TRUE(s2 > s1);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s2 >= s1);
EXPECT_FALSE(s1 >= s2);
}
}
TEST(span_test, as_bytes) TEST(span_test, as_bytes)
{ {
int a[] = {1, 2, 3, 4}; std::set_terminate([] {
std::cerr << "Expected Death. as_bytes";
std::abort();
});
int a[] = {1, 2, 3, 4};
{ {
const span<const int> s = a; const span<const int> s = a;
EXPECT_TRUE(s.size() == 4); EXPECT_TRUE(s.size() == 4);
@ -1523,9 +1206,15 @@ TEST(span_test, from_array_constructor)
EXPECT_TRUE(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data())); EXPECT_TRUE(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data()));
EXPECT_TRUE(bs.size() == s.size_bytes()); EXPECT_TRUE(bs.size() == s.size_bytes());
} }
int b[5] = {1, 2, 3, 4, 5};
{
span<int> sp(begin(b), static_cast<size_t>(-2));
EXPECT_DEATH((void) sp.size_bytes(), deathstring);
}
} }
TEST(span_test, as_writeable_bytes) TEST(span_test, as_writable_bytes)
{ {
int a[] = {1, 2, 3, 4}; int a[] = {1, 2, 3, 4};
@ -1534,7 +1223,7 @@ TEST(span_test, from_array_constructor)
// you should not be able to get writeable bytes for const objects // you should not be able to get writeable bytes for const objects
span<const int> s = a; span<const int> s = a;
EXPECT_TRUE(s.size() == 4); EXPECT_TRUE(s.size() == 4);
span<const byte> bs = as_writeable_bytes(s); span<const byte> bs = as_writable_bytes(s);
EXPECT_TRUE(static_cast<void*>(bs.data()) == static_cast<void*>(s.data())); EXPECT_TRUE(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));
EXPECT_TRUE(bs.size() == s.size_bytes()); EXPECT_TRUE(bs.size() == s.size_bytes());
#endif #endif
@ -1542,7 +1231,7 @@ TEST(span_test, from_array_constructor)
{ {
span<int> s; span<int> s;
const auto bs = as_writeable_bytes(s); const auto bs = as_writable_bytes(s);
EXPECT_TRUE(bs.size() == s.size()); EXPECT_TRUE(bs.size() == s.size());
EXPECT_TRUE(bs.size() == 0); EXPECT_TRUE(bs.size() == 0);
EXPECT_TRUE(bs.size_bytes() == 0); EXPECT_TRUE(bs.size_bytes() == 0);
@ -1552,7 +1241,7 @@ TEST(span_test, from_array_constructor)
{ {
span<int> s = a; span<int> s = a;
const auto bs = as_writeable_bytes(s); const auto bs = as_writable_bytes(s);
EXPECT_TRUE(static_cast<void*>(bs.data()) == static_cast<void*>(s.data())); EXPECT_TRUE(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));
EXPECT_TRUE(bs.size() == s.size_bytes()); EXPECT_TRUE(bs.size() == s.size_bytes());
} }
@ -1590,12 +1279,16 @@ TEST(span_test, from_array_constructor)
// even when done dynamically // even when done dynamically
{ {
/*
// this now results in a compile-time error, rather than runtime.
// There is no suitable conversion from dynamic span to fixed span.
span<int> s = arr; span<int> s = arr;
auto f = [&]() { auto f = [&]() {
const span<int, 2> s2 = s; const span<int, 2> s2 = s;
static_cast<void>(s2); static_cast<void>(s2);
}; };
EXPECT_DEATH(f(), deathstring); EXPECT_DEATH(f(), deathstring);
*/
} }
// but doing so explicitly is ok // but doing so explicitly is ok
@ -1610,12 +1303,19 @@ TEST(span_test, from_array_constructor)
static_cast<void>(s1); static_cast<void>(s1);
} }
// ...or dynamically /*
// this is not a legal operation in std::span, so we are no longer supporting it
// conversion from span<int, 4> to span<int, dynamic_extent> via call to `first`
// then convert from span<int, dynamic_extent> to span<int, 1>
// The dynamic to fixed extents are not supported in the standard
// to make this work, span<int, 1> would need to be span<int>.
{ {
// NB: implicit conversion to span<int,1> from span<int> // NB: implicit conversion to span<int,1> from span<int>
span<int, 1> s1 = s4.first(1); span<int, 1> s1 = s4.first(1);
static_cast<void>(s1); static_cast<void>(s1);
} }
*/
// initialization or assignment to static span that requires size INCREASE is not ok. // initialization or assignment to static span that requires size INCREASE is not ok.
int arr2[2] = {1, 2}; int arr2[2] = {1, 2};
@ -1637,12 +1337,15 @@ TEST(span_test, from_array_constructor)
EXPECT_DEATH(f(), deathstring); EXPECT_DEATH(f(), deathstring);
} }
/*
// This no longer compiles. There is no suitable conversion from dynamic span to a fixed size span.
// this should fail - we are trying to assign a small dynamic span to a fixed_size larger one // this should fail - we are trying to assign a small dynamic span to a fixed_size larger one
span<int> av = arr2; auto f = [&]() { span<int> av = arr2; auto f = [&]() {
const span<int, 4> _s4 = av; const span<int, 4> _s4 = av;
static_cast<void>(_s4); static_cast<void>(_s4);
}; };
EXPECT_DEATH(f(), deathstring); EXPECT_DEATH(f(), deathstring);
*/
} }
TEST(span_test, interop_with_std_regex) TEST(span_test, interop_with_std_regex)
@ -1668,14 +1371,6 @@ TEST(span_test, from_array_constructor)
EXPECT_TRUE(match[0].second == (f_it + 1)); EXPECT_TRUE(match[0].second == (f_it + 1));
} }
TEST(span_test, interop_with_gsl_at)
{
int arr[5] = {1, 2, 3, 4, 5};
span<int> s{arr};
EXPECT_TRUE(at(s, 0) == 1);
EXPECT_TRUE(at(s, 1) == 2);
}
TEST(span_test, default_constructible) TEST(span_test, default_constructible)
{ {
EXPECT_TRUE((std::is_default_constructible<span<int>>::value)); EXPECT_TRUE((std::is_default_constructible<span<int>>::value));
@ -1698,7 +1393,3 @@ TEST(span_test, from_array_constructor)
EXPECT_DEATH(s2.front(), deathstring); EXPECT_DEATH(s2.front(), deathstring);
EXPECT_DEATH(s2.back(), deathstring); EXPECT_DEATH(s2.back(), deathstring);
} }
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif // __clang__ || __GNUC__

View File

@ -14,28 +14,6 @@
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch
// Fix VS2015 build breaks in Release
#pragma warning(disable : 4702) // unreachable code
#endif
#if __clang__ || __GNUC__
//disable warnings from gtest
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wundef"
#endif // __clang__ || __GNUC__
#if __clang__
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override"
#endif // __clang__
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gsl/pointers> // for not_null, operator<, operator<=, operator> #include <gsl/pointers> // for not_null, operator<, operator<=, operator>
@ -210,10 +188,3 @@ TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction)
#endif #endif
} }
#endif // #if defined(__cplusplus) && (__cplusplus >= 201703L) #endif // #if defined(__cplusplus) && (__cplusplus >= 201703L)
static_assert(std::is_nothrow_move_constructible<strict_not_null<void*>>::value,
"strict_not_null must be no-throw move constructible");
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif // __clang__ || __GNUC__

View File

@ -14,28 +14,6 @@
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch deprecated
#pragma warning(disable : 4996) // strided_span is in the process of being deprecated.
// Suppressing warnings until it is completely removed
#endif
#if __clang__ || __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
//disable warnings from gtest
#pragma GCC diagnostic ignored "-Wundef"
#endif // __clang__ || __GNUC__
#if __clang__
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override"
#endif // __clang__
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gsl/gsl_byte> // for byte #include <gsl/gsl_byte> // for byte
#include <gsl/gsl_util> // for narrow_cast #include <gsl/gsl_util> // for narrow_cast
@ -810,7 +788,3 @@ TEST(strided_span_tests, strided_span_conversion)
i++; i++;
} }
} }
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif // __clang__ || __GNUC__

View File

@ -14,26 +14,6 @@
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch
#endif
#if __clang__ || __GNUC__
//disable warnings from gtest
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wundef"
#endif // __clang__ || __GNUC__
#if __clang__
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override"
#endif // __clang__
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gsl/gsl_assert> // for Expects, fail_fast (ptr only) #include <gsl/gsl_assert> // for Expects, fail_fast (ptr only)
@ -104,7 +84,7 @@ czstring_span<> CreateTempName(string_span<> span)
{ {
Expects(span.size() > 1); Expects(span.size() > 1);
int last = 0; std::size_t last = 0;
if (span.size() > 4) { if (span.size() > 4) {
span[0] = 't'; span[0] = 't';
span[1] = 'm'; span[1] = 'm';
@ -121,7 +101,7 @@ cwzstring_span<> CreateTempNameW(wstring_span<> span)
{ {
Expects(span.size() > 1); Expects(span.size() > 1);
int last = 0; std::size_t last = 0;
if (span.size() > 4) { if (span.size() > 4) {
span[0] = L't'; span[0] = L't';
span[1] = L'm'; span[1] = L'm';
@ -138,7 +118,7 @@ cu16zstring_span<> CreateTempNameU16(u16string_span<> span)
{ {
Expects(span.size() > 1); Expects(span.size() > 1);
int last = 0; std::size_t last = 0;
if (span.size() > 4) { if (span.size() > 4) {
span[0] = u't'; span[0] = u't';
span[1] = u'm'; span[1] = u'm';
@ -155,7 +135,7 @@ cu32zstring_span<> CreateTempNameU32(u32string_span<> span)
{ {
Expects(span.size() > 1); Expects(span.size() > 1);
int last = 0; std::size_t last = 0;
if (span.size() > 4) { if (span.size() > 4) {
span[0] = U't'; span[0] = U't';
span[1] = U'm'; span[1] = U'm';
@ -183,14 +163,14 @@ TEST(string_span_tests, TestConstructFromStdString)
{ {
std::string s = "Hello there world"; std::string s = "Hello there world";
cstring_span<> v = s; cstring_span<> v = s;
EXPECT_TRUE(v.length() == static_cast<cstring_span<>::index_type>(s.length())); EXPECT_TRUE(v.length() == static_cast<cstring_span<>::size_type>(s.length()));
} }
TEST(string_span_tests, TestConstructFromStdVector) TEST(string_span_tests, TestConstructFromStdVector)
{ {
std::vector<char> vec(5, 'h'); std::vector<char> vec(5, 'h');
string_span<> v{vec}; string_span<> v{vec};
EXPECT_TRUE(v.length() == static_cast<string_span<>::index_type>(vec.size())); EXPECT_TRUE(v.length() == static_cast<string_span<>::size_type>(vec.size()));
} }
TEST(string_span_tests, TestStackArrayConstruction) TEST(string_span_tests, TestStackArrayConstruction)
@ -252,7 +232,7 @@ TEST(string_span_tests, TestToString)
char stack_string[] = "Hello"; char stack_string[] = "Hello";
cstring_span<> v = ensure_z(stack_string); cstring_span<> v = ensure_z(stack_string);
auto s2 = gsl::to_string(v); auto s2 = gsl::to_string(v);
EXPECT_TRUE(static_cast<cstring_span<>::index_type>(s2.length()) == v.length()); EXPECT_TRUE(static_cast<cstring_span<>::size_type>(s2.length()) == v.length());
EXPECT_TRUE(s2.length() == static_cast<size_t>(5)); EXPECT_TRUE(s2.length() == static_cast<size_t>(5));
} }
@ -265,7 +245,7 @@ TEST(string_span_tests, TestToBasicString)
char stack_string[] = "Hello"; char stack_string[] = "Hello";
cstring_span<> v = ensure_z(stack_string); cstring_span<> v = ensure_z(stack_string);
auto s2 = gsl::to_basic_string<char, std::char_traits<char>, ::std::allocator<char>>(v); auto s2 = gsl::to_basic_string<char, std::char_traits<char>, ::std::allocator<char>>(v);
EXPECT_TRUE(static_cast<cstring_span<>::index_type>(s2.length()) == v.length()); EXPECT_TRUE(static_cast<cstring_span<>::size_type>(s2.length()) == v.length());
EXPECT_TRUE(s2.length() == static_cast<size_t>(5)); EXPECT_TRUE(s2.length() == static_cast<size_t>(5));
} }
@ -1226,16 +1206,12 @@ TEST(string_span_tests, as_bytes)
EXPECT_TRUE(bs.size() == s.size_bytes()); EXPECT_TRUE(bs.size() == s.size_bytes());
} }
TEST(string_span_tests, as_writeable_bytes) TEST(string_span_tests, as_writable_bytes)
{ {
wchar_t buf[]{L"qwerty"}; wchar_t buf[]{L"qwerty"};
wzstring_span<> v(buf); wzstring_span<> v(buf);
const auto s = v.as_string_span(); const auto s = v.as_string_span();
const auto bs = as_writeable_bytes(s); const auto bs = as_writable_bytes(s);
EXPECT_TRUE(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data())); EXPECT_TRUE(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data()));
EXPECT_TRUE(bs.size() == s.size_bytes()); EXPECT_TRUE(bs.size() == s.size_bytes());
} }
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif // __clang__ || __GNUC__

View File

@ -14,27 +14,6 @@
// //
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26440 26426) // from catch
#endif
#if __clang__ || __GNUC__
//disable warnings from gtest
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wundef"
#endif // __clang__ || __GNUC__
#if __clang__
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
#pragma GCC diagnostic ignored "-Winconsistent-missing-destructor-override"
#endif // __clang__
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gsl/gsl_util> // for narrow, finally, narrow_cast, narrowing_e... #include <gsl/gsl_util> // for narrow, finally, narrow_cast, narrowing_e...
@ -44,6 +23,7 @@
#include <limits> // for numeric_limits #include <limits> // for numeric_limits
#include <stdint.h> // for uint32_t, int32_t #include <stdint.h> // for uint32_t, int32_t
#include <type_traits> // for is_same #include <type_traits> // for is_same
#include <cstddef> // for std::ptrdiff_t
using namespace gsl; using namespace gsl;
@ -154,7 +134,3 @@ TEST(utils_tests, narrow)
#endif #endif
} }
#if __clang__ || __GNUC__
#pragma GCC diagnostic pop
#endif // __clang__ || __GNUC__