mirror of
https://github.com/microsoft/GSL.git
synced 2025-03-12 22:28:06 -04:00
Merge branch 'master' into TravisCI
This commit is contained in:
commit
30c068781f
@ -5,6 +5,9 @@ project(GSL CXX)
|
||||
include(ExternalProject)
|
||||
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)
|
||||
add_library(GSL INTERFACE)
|
||||
|
||||
@ -54,15 +57,13 @@ target_compile_definitions(GSL INTERFACE
|
||||
# the SYSTEM keyword suppresses warnings for users of the library
|
||||
if(GSL_STANDALONE_PROJECT)
|
||||
target_include_directories(GSL INTERFACE
|
||||
$<BUILD_INTERFACE:
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
else()
|
||||
target_include_directories(GSL SYSTEM INTERFACE
|
||||
$<BUILD_INTERFACE:
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
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
|
||||
if(VS_ADD_NATIVE_VISUALIZERS)
|
||||
target_sources(GSL INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GSL.natvis
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GSL.natvis>
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
install(TARGETS GSL EXPORT Microsoft.GSLConfig)
|
||||
install(
|
||||
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})
|
||||
if (GSL_TEST)
|
||||
|
21
README.md
21
README.md
@ -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!
|
||||
|
||||
## 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
|
||||
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>
|
||||
|
||||
## 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
|
||||
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.
|
||||
|
@ -37,8 +37,8 @@ namespace gsl
|
||||
{
|
||||
// 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)
|
||||
template <class SrcElementType, std::ptrdiff_t SrcExtent, class DestElementType,
|
||||
std::ptrdiff_t DestExtent>
|
||||
template <class SrcElementType, std::size_t SrcExtent, class DestElementType,
|
||||
std::size_t DestExtent>
|
||||
void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent> dest)
|
||||
{
|
||||
static_assert(std::is_assignable<decltype(*dest.data()), decltype(*src.data())>::value,
|
||||
|
@ -17,8 +17,27 @@
|
||||
#ifndef 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>
|
||||
|
||||
#endif // defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS))
|
||||
|
||||
//
|
||||
// make suppress attributes parse for some compilers
|
||||
// Hopefully temporary until suppression standardization occurs
|
||||
@ -33,32 +52,18 @@
|
||||
#endif // _MSC_VER
|
||||
#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(x) GSL_STRINGIFY_DETAIL(x)
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#define GSL_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
#else
|
||||
|
||||
#define GSL_LIKELY(x) (!!(x))
|
||||
#define GSL_UNLIKELY(x) (!!(x))
|
||||
#endif
|
||||
#endif // defined(__clang__) || defined(__GNUC__)
|
||||
|
||||
//
|
||||
// GSL_ASSUME(cond)
|
||||
@ -85,9 +90,11 @@ namespace details
|
||||
{
|
||||
#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
|
||||
// clang-format on
|
||||
[[noreturn]] inline void __cdecl default_terminate_handler()
|
||||
{
|
||||
__fastfail(RANGE_CHECKS_FAILURE);
|
||||
@ -99,7 +106,7 @@ namespace details
|
||||
return handler;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
|
||||
|
||||
[[noreturn]] inline void terminate() noexcept
|
||||
{
|
||||
@ -107,21 +114,12 @@ namespace details
|
||||
(*gsl::details::get_terminate_handler())();
|
||||
#else
|
||||
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 gsl
|
||||
|
||||
|
||||
#define GSL_CONTRACT_CHECK(type, cond) \
|
||||
(GSL_LIKELY(cond) ? static_cast<void>(0) : gsl::details::terminate())
|
||||
|
||||
|
@ -88,7 +88,6 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
not_null(not_null&& other) = default;
|
||||
not_null(const not_null& other) = default;
|
||||
not_null& operator=(const not_null& other) = default;
|
||||
|
||||
|
658
include/gsl/span
658
include/gsl/span
File diff suppressed because it is too large
Load Diff
198
include/gsl/span_ext
Normal file
198
include/gsl/span_ext
Normal 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
|
@ -19,14 +19,14 @@
|
||||
|
||||
#include <gsl/gsl_assert> // for Ensures, Expects
|
||||
#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 <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 <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_...
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
@ -56,43 +56,43 @@ namespace gsl
|
||||
// (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*;
|
||||
|
||||
template <std::ptrdiff_t Extent = dynamic_extent>
|
||||
template <std::size_t Extent = dynamic_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>;
|
||||
|
||||
template <std::ptrdiff_t Extent = dynamic_extent>
|
||||
template <std::size_t Extent = dynamic_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>;
|
||||
|
||||
template <std::ptrdiff_t Extent = dynamic_extent>
|
||||
template <std::size_t Extent = dynamic_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>;
|
||||
|
||||
template <std::ptrdiff_t Extent = dynamic_extent>
|
||||
template <std::size_t Extent = dynamic_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>;
|
||||
|
||||
namespace details
|
||||
{
|
||||
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};
|
||||
|
||||
std::ptrdiff_t len = 0;
|
||||
std::size_t len = 0;
|
||||
while (len < n && str_span[len]) len++;
|
||||
|
||||
return len;
|
||||
@ -108,18 +108,20 @@ namespace details
|
||||
// Will fail-fast if sentinel cannot be found before max elements are examined.
|
||||
//
|
||||
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);
|
||||
|
||||
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;
|
||||
Ensures(cur != nullptr); // workaround for removing the warning
|
||||
|
||||
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);
|
||||
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.
|
||||
//
|
||||
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);
|
||||
}
|
||||
@ -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>
|
||||
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>
|
||||
span<typename std::remove_pointer<typename Cont::pointer>::type, dynamic_extent>
|
||||
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;
|
||||
|
||||
namespace details {
|
||||
namespace details
|
||||
{
|
||||
template <typename T>
|
||||
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
|
||||
{
|
||||
};
|
||||
@ -169,7 +173,7 @@ namespace details {
|
||||
//
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
@ -180,14 +184,12 @@ public:
|
||||
using const_reference = std::add_lvalue_reference_t<std::add_const_t<element_type>>;
|
||||
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 const_iterator = typename impl_type::const_iterator;
|
||||
using reverse_iterator = typename impl_type::reverse_iterator;
|
||||
using const_reverse_iterator = typename impl_type::const_reverse_iterator;
|
||||
|
||||
using size_type = index_type;
|
||||
|
||||
// default (empty)
|
||||
constexpr basic_string_span() noexcept = default;
|
||||
|
||||
@ -197,7 +199,7 @@ public:
|
||||
// assign
|
||||
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) {}
|
||||
|
||||
// From static arrays - if 0-terminated, remove 0 from the view
|
||||
@ -218,7 +220,7 @@ public:
|
||||
template <class Traits, class Allocator>
|
||||
// GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute // TODO: parser bug
|
||||
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>
|
||||
@ -247,56 +249,56 @@ public:
|
||||
|
||||
// from string_span
|
||||
template <
|
||||
class OtherValueType, std::ptrdiff_t OtherExtent,
|
||||
class OtherValueType, std::size_t OtherExtent,
|
||||
class = std::enable_if_t<std::is_convertible<
|
||||
typename basic_string_span<OtherValueType, OtherExtent>::impl_type, impl_type>::value>>
|
||||
constexpr basic_string_span(basic_string_span<OtherValueType, OtherExtent> other)
|
||||
: span_(other.data(), other.length())
|
||||
{}
|
||||
|
||||
template <index_type Count>
|
||||
template <size_type Count>
|
||||
constexpr basic_string_span<element_type, Count> first() const
|
||||
{
|
||||
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)};
|
||||
}
|
||||
|
||||
template <index_type Count>
|
||||
template <size_type Count>
|
||||
constexpr basic_string_span<element_type, Count> last() const
|
||||
{
|
||||
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)};
|
||||
}
|
||||
|
||||
template <index_type Offset, index_type Count>
|
||||
template <size_type Offset, size_type Count>
|
||||
constexpr basic_string_span<element_type, Count> subspan() const
|
||||
{
|
||||
return {span_.template subspan<Offset, Count>()};
|
||||
}
|
||||
|
||||
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)};
|
||||
}
|
||||
|
||||
constexpr reference operator[](index_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 reference operator()(size_type idx) const { return span_[idx]; }
|
||||
|
||||
constexpr pointer data() const { return span_.data(); }
|
||||
|
||||
constexpr index_type length() const noexcept { return span_.size(); }
|
||||
constexpr index_type size() const noexcept { return span_.size(); }
|
||||
constexpr index_type size_bytes() const noexcept { return span_.size_bytes(); }
|
||||
constexpr index_type length_bytes() const noexcept { return span_.length_bytes(); }
|
||||
constexpr size_type length() const noexcept { return span_.size(); }
|
||||
constexpr size_type size() const noexcept { return span_.size(); }
|
||||
constexpr size_type size_bytes() const noexcept { return span_.size_bytes(); }
|
||||
constexpr size_type length_bytes() const noexcept { return span_.length_bytes(); }
|
||||
constexpr bool empty() const noexcept { return size() == 0; }
|
||||
|
||||
constexpr iterator begin() const noexcept { return span_.begin(); }
|
||||
@ -312,7 +314,7 @@ public:
|
||||
constexpr const_reverse_iterator crend() const noexcept { return span_.crend(); }
|
||||
|
||||
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)};
|
||||
}
|
||||
@ -320,41 +322,41 @@ private:
|
||||
template <std::size_t 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_;
|
||||
};
|
||||
|
||||
template <std::ptrdiff_t Extent = dynamic_extent>
|
||||
template <std::size_t Extent = dynamic_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>;
|
||||
|
||||
template <std::ptrdiff_t Extent = dynamic_extent>
|
||||
template <std::size_t Extent = dynamic_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>;
|
||||
|
||||
template <std::ptrdiff_t Extent = dynamic_extent>
|
||||
template <std::size_t Extent = dynamic_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>;
|
||||
|
||||
template <std::ptrdiff_t Extent = dynamic_extent>
|
||||
template <std::size_t Extent = dynamic_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>;
|
||||
|
||||
//
|
||||
// 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>
|
||||
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>,
|
||||
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)
|
||||
{
|
||||
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>
|
||||
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()};
|
||||
}
|
||||
|
||||
template <class ElementType, std::ptrdiff_t Extent,
|
||||
template <class ElementType, std::size_t Extent,
|
||||
class = std::enable_if_t<!std::is_const<ElementType>::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
|
||||
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 spans to legacy strings
|
||||
template <typename CharT, std::ptrdiff_t Extent = dynamic_extent>
|
||||
class basic_zstring_span {
|
||||
template <typename CharT, std::size_t Extent = dynamic_extent>
|
||||
class basic_zstring_span
|
||||
{
|
||||
public:
|
||||
using value_type = CharT;
|
||||
using const_value_type = std::add_const_t<CharT>;
|
||||
@ -435,32 +438,32 @@ private:
|
||||
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>;
|
||||
|
||||
template <std::ptrdiff_t Max = dynamic_extent>
|
||||
template <std::size_t Max = dynamic_extent>
|
||||
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>;
|
||||
|
||||
template <std::ptrdiff_t Max = dynamic_extent>
|
||||
template <std::size_t Max = dynamic_extent>
|
||||
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>;
|
||||
|
||||
template <std::ptrdiff_t Max = dynamic_extent>
|
||||
template <std::size_t Max = dynamic_extent>
|
||||
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>;
|
||||
|
||||
template <std::ptrdiff_t Max = dynamic_extent>
|
||||
template <std::size_t Max = dynamic_extent>
|
||||
using cu32zstring_span = basic_zstring_span<const char32_t, Max>;
|
||||
|
||||
// operator ==
|
||||
template <class CharT, std::ptrdiff_t Extent, class T,
|
||||
template <class CharT, std::size_t Extent, class T,
|
||||
class = std::enable_if_t<
|
||||
details::is_basic_string_span<T>::value ||
|
||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>>
|
||||
@ -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());
|
||||
}
|
||||
|
||||
template <class CharT, std::ptrdiff_t Extent, class T,
|
||||
template <class CharT, std::size_t Extent, class T,
|
||||
class = std::enable_if_t<
|
||||
!details::is_basic_string_span<T>::value &&
|
||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>>>::value>>
|
||||
@ -481,7 +484,7 @@ bool operator==(const T& one, const gsl::basic_string_span<CharT, Extent>& other
|
||||
}
|
||||
|
||||
// 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<
|
||||
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
|
||||
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 <
|
||||
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<
|
||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::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<
|
||||
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<
|
||||
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
|
||||
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 <
|
||||
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<
|
||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::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
|
||||
|
||||
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 = std::enable_if_t<
|
||||
!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 <
|
||||
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 = std::enable_if_t<
|
||||
!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
|
||||
|
||||
// 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<
|
||||
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
|
||||
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 <
|
||||
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<
|
||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::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
|
||||
|
||||
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 = std::enable_if_t<
|
||||
!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 <
|
||||
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 = std::enable_if_t<
|
||||
!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
|
||||
|
||||
// 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<
|
||||
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
|
||||
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 <
|
||||
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<
|
||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::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
|
||||
|
||||
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 = std::enable_if_t<
|
||||
!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 <
|
||||
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 = std::enable_if_t<
|
||||
!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
|
||||
|
||||
// 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<
|
||||
T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::value>>
|
||||
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 <
|
||||
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<
|
||||
std::is_convertible<T, gsl::basic_string_span<std::add_const_t<CharT>, Extent>>::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
|
||||
|
||||
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 = std::enable_if_t<
|
||||
!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 <
|
||||
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 = std::enable_if_t<
|
||||
!gsl::details::is_span<T>::value && !gsl::details::is_basic_string_span<T>::value &&
|
||||
|
@ -45,14 +45,38 @@ if(MSVC) # MSVC or simulating MSVC
|
||||
/EHsc
|
||||
/W4
|
||||
/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>:
|
||||
-Weverything
|
||||
-Wno-c++98-compat
|
||||
-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-prototypes
|
||||
-Wno-unknown-attributes
|
||||
$<$<EQUAL:${GSL_CXX_STANDARD},14>:-Wno-unused-member-function>
|
||||
-Wno-shift-sign-overflow # GTest gtest-port.h
|
||||
-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()
|
||||
@ -67,16 +91,23 @@ else()
|
||||
-Wpedantic
|
||||
-Wshadow
|
||||
-Wsign-conversion
|
||||
-Wno-deprecated-declarations # Allow tests for [[deprecated]] elements
|
||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
|
||||
-Weverything
|
||||
-Wno-c++98-compat
|
||||
-Wno-c++98-compat-pedantic
|
||||
-Wno-missing-braces
|
||||
-Wno-covered-switch-default # GTest
|
||||
-Wno-global-constructors # GTest
|
||||
-Wno-missing-prototypes
|
||||
-Wno-padded
|
||||
-Wno-unknown-attributes
|
||||
$<$<EQUAL:${GSL_CXX_STANDARD},14>:-Wno-unused-member-function>
|
||||
-Wno-used-but-marked-unused # GTest EXPECT_DEATH
|
||||
-Wno-weak-vtables
|
||||
$<$<EQUAL:${GSL_CXX_STANDARD},14>: # no support for [[maybe_unused]]
|
||||
-Wno-unused-member-function
|
||||
-Wno-unused-variable
|
||||
>
|
||||
>
|
||||
$<$<CXX_COMPILER_ID:Clang>:
|
||||
$<$<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>
|
||||
>
|
||||
>
|
||||
$<$<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)
|
||||
|
||||
@ -114,6 +160,8 @@ function(add_gsl_test name)
|
||||
endfunction()
|
||||
|
||||
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(strided_span_tests)
|
||||
add_gsl_test(string_span_tests)
|
||||
@ -140,14 +188,18 @@ endforeach(flag_var)
|
||||
# please try to keep entries ordered =)
|
||||
add_library(gsl_tests_config_noexcept INTERFACE)
|
||||
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
|
||||
${GSL_CPLUSPLUS_OPT}
|
||||
/EHsc
|
||||
/W4
|
||||
/WX
|
||||
$<$<CXX_COMPILER_ID:MSVC>:
|
||||
/wd4577
|
||||
/wd4702
|
||||
/wd26440 # CppCoreCheck - GTest
|
||||
/wd26446 # CppCoreCheck - prefer gsl::at()
|
||||
>
|
||||
$<$<CXX_COMPILER_ID:Clang>:
|
||||
-Weverything
|
||||
@ -178,6 +230,22 @@ else()
|
||||
-Wno-unknown-attributes
|
||||
-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)
|
||||
|
||||
|
@ -4,7 +4,7 @@ project(googletest-download NONE)
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(googletest
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG master
|
||||
GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e
|
||||
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
|
||||
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
|
||||
CONFIGURE_COMMAND ""
|
||||
|
@ -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 <gsl/gsl_algorithm> // for copy
|
||||
#include <gsl/span> // for span
|
||||
@ -244,7 +225,3 @@ TEST(algorithm_tests, small_destination_span)
|
||||
copy(src_span_static, dst_span_static);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __clang__ || __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // __clang__ || __GNUC__
|
||||
|
@ -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 <gsl/gsl_assert> // for fail_fast (ptr only), Ensures, Expects
|
||||
|
||||
@ -78,7 +59,3 @@ TEST(assertion_tests, ensures)
|
||||
EXPECT_TRUE(g(2) == 3);
|
||||
EXPECT_DEATH(g(9), deathstring);
|
||||
}
|
||||
|
||||
#if __clang__ || __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // __clang__ || __GNUC__
|
||||
|
@ -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 <gsl/gsl_util> // for at
|
||||
@ -152,7 +133,3 @@ static constexpr bool test_constexpr()
|
||||
|
||||
static_assert(test_constexpr(), "FAIL");
|
||||
#endif
|
||||
|
||||
#if __clang__ || __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // __clang__ || __GNUC__
|
||||
|
@ -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 <gsl/multi_span> // for static_bounds, static_bounds_dynamic_range_t
|
||||
@ -122,7 +100,3 @@ TEST(bounds_tests, bounds_convertible)
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
copy(src_span_static, dst_span_static);
|
||||
#endif
|
||||
|
||||
#if __clang__ || __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // __clang__ || __GNUC__
|
||||
|
@ -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 <gsl/gsl_byte> // for to_byte, to_integer, byte, operator&, ope...
|
||||
@ -146,7 +127,3 @@ TEST(byte_tests, aliasing)
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
copy(src_span_static, dst_span_static);
|
||||
#endif
|
||||
|
||||
#if __clang__ || __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // __clang__ || __GNUC__
|
||||
|
@ -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 <gsl/gsl_byte> // for byte
|
||||
@ -1884,7 +1861,3 @@ TEST(multi_span_test, iterator)
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
copy(src_span_static, dst_span_static);
|
||||
#endif
|
||||
|
||||
#if __clang__ || __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // __clang__ || __GNUC__
|
||||
|
@ -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 <gsl/pointers> // for not_null, operator<, operator<=, operator>
|
||||
@ -555,10 +533,3 @@ TEST(notnull_tests, TestMakeNotNull)
|
||||
}
|
||||
#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__
|
||||
|
@ -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 <gsl/pointers> // for owner
|
||||
@ -61,7 +41,3 @@ TEST(owner_tests, check_pointer_constraint)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __clang__ || __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // __clang__ || __GNUC__
|
||||
|
1072
tests/span_compatibility_tests.cpp
Normal file
1072
tests/span_compatibility_tests.cpp
Normal file
File diff suppressed because it is too large
Load Diff
360
tests/span_ext_tests.cpp
Normal file
360
tests/span_ext_tests.cpp
Normal 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);
|
||||
}
|
||||
}
|
@ -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 <gsl/gsl_byte> // for byte
|
||||
@ -46,15 +25,11 @@
|
||||
#include <iterator> // for reverse_iterator, operator-, operator==
|
||||
#include <memory> // for unique_ptr, shared_ptr, make_unique, allo...
|
||||
#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 <type_traits> // for integral_constant<>::value, is_default_co...
|
||||
#include <vector> // for vector
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
struct fail_fast;
|
||||
} // namespace gsl
|
||||
#include <utility>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsl;
|
||||
@ -131,17 +106,17 @@ TEST(span_test, from_nullptr_size_constructor)
|
||||
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.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.data() == nullptr);
|
||||
}
|
||||
{
|
||||
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);
|
||||
}
|
||||
@ -160,11 +135,11 @@ TEST(span_test, from_nullptr_size_constructor)
|
||||
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.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.data() == nullptr);
|
||||
}
|
||||
@ -182,29 +157,21 @@ TEST(span_test, from_pointer_length_constructor)
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
{
|
||||
span<int> s = {&arr[0], i};
|
||||
EXPECT_TRUE(s.size() == i);
|
||||
span<int> s = {&arr[0], narrow_cast<std::size_t>(i)};
|
||||
EXPECT_TRUE(s.size() == narrow_cast<std::size_t>(i));
|
||||
EXPECT_TRUE(s.data() == &arr[0]);
|
||||
EXPECT_TRUE(s.empty() == (i == 0));
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
EXPECT_TRUE(arr[j] == s[j]);
|
||||
EXPECT_TRUE(arr[j] == s.at(j));
|
||||
EXPECT_TRUE(arr[j] == s(j));
|
||||
}
|
||||
EXPECT_TRUE(arr[j] == s[narrow_cast<std::size_t>(j)]);
|
||||
}
|
||||
{
|
||||
span<int> s = {&arr[i], 4 - narrow_cast<ptrdiff_t>(i)};
|
||||
EXPECT_TRUE(s.size() == 4 - i);
|
||||
span<int> s = {&arr[i], 4 - narrow_cast<std::size_t>(i)};
|
||||
EXPECT_TRUE(s.size() == 4 - narrow_cast<std::size_t>(i));
|
||||
EXPECT_TRUE(s.data() == &arr[i]);
|
||||
EXPECT_TRUE(s.empty() == ((4 - i) == 0));
|
||||
|
||||
for (int j = 0; j < 4 - i; ++j)
|
||||
{
|
||||
EXPECT_TRUE(arr[j + i] == s[j]);
|
||||
EXPECT_TRUE(arr[j + i] == s.at(j));
|
||||
EXPECT_TRUE(arr[j + i] == s(j));
|
||||
}
|
||||
EXPECT_TRUE(arr[j + i] == s[narrow_cast<std::size_t>(j)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -219,7 +186,7 @@ TEST(span_test, from_pointer_length_constructor)
|
||||
|
||||
{
|
||||
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.data() == nullptr);
|
||||
}
|
||||
@ -229,27 +196,6 @@ TEST(span_test, from_pointer_length_constructor)
|
||||
auto workaround_macro = [=]() { const span<int> s{p, 2}; };
|
||||
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)
|
||||
@ -316,27 +262,6 @@ TEST(span_test, from_pointer_pointer_construction)
|
||||
// auto workaround_macro = [&]() { span<int> s{&arr[0], p}; };
|
||||
// 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)
|
||||
@ -426,24 +351,6 @@ TEST(span_test, from_array_constructor)
|
||||
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] = {};
|
||||
|
||||
{
|
||||
@ -463,12 +370,6 @@ TEST(span_test, from_array_constructor)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -478,21 +379,21 @@ TEST(span_test, from_array_constructor)
|
||||
|
||||
{
|
||||
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());
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
{
|
||||
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());
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@ -507,7 +408,7 @@ TEST(span_test, from_array_constructor)
|
||||
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
@ -550,30 +451,6 @@ TEST(span_test, from_array_constructor)
|
||||
// try to take a temporary std::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)
|
||||
@ -582,13 +459,13 @@ TEST(span_test, from_array_constructor)
|
||||
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
@ -596,7 +473,7 @@ TEST(span_test, from_array_constructor)
|
||||
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
@ -624,12 +501,6 @@ TEST(span_test, from_array_constructor)
|
||||
// try to take a temporary std::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)
|
||||
@ -638,13 +509,13 @@ TEST(span_test, from_array_constructor)
|
||||
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
@ -669,12 +540,6 @@ TEST(span_test, from_array_constructor)
|
||||
span<int, 4> s{arr};
|
||||
}
|
||||
#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)
|
||||
@ -684,11 +549,11 @@ TEST(span_test, from_array_constructor)
|
||||
|
||||
{
|
||||
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());
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@ -698,11 +563,11 @@ TEST(span_test, from_array_constructor)
|
||||
{
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
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()));
|
||||
#endif
|
||||
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());
|
||||
}
|
||||
|
||||
@ -711,7 +576,7 @@ TEST(span_test, from_array_constructor)
|
||||
span<char> s{cstr};
|
||||
#endif
|
||||
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());
|
||||
}
|
||||
|
||||
@ -763,16 +628,6 @@ TEST(span_test, from_array_constructor)
|
||||
span<int> s{m};
|
||||
#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;
|
||||
@ -987,7 +842,7 @@ TEST(span_test, from_array_constructor)
|
||||
EXPECT_TRUE(av.subspan(5).size() == 0);
|
||||
EXPECT_DEATH(av.subspan(6).size(), deathstring);
|
||||
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_DEATH(av.subspan(6).size(), deathstring);
|
||||
const auto av2 = av.subspan(1);
|
||||
for (int i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == 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);
|
||||
for (std::size_t i = 0; i < 4; ++i) EXPECT_TRUE(av2[i] == static_cast<int>(i) + 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1083,46 +892,6 @@ TEST(span_test, from_array_constructor)
|
||||
span<int>::const_iterator cit3 = it + 4;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
std::set_terminate([] {
|
||||
@ -1302,7 +1093,11 @@ TEST(span_test, from_array_constructor)
|
||||
|
||||
auto beyond = s.rend();
|
||||
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(first - first == 0);
|
||||
@ -1347,7 +1142,11 @@ TEST(span_test, from_array_constructor)
|
||||
|
||||
auto beyond = s.crend();
|
||||
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(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)
|
||||
{
|
||||
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;
|
||||
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(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};
|
||||
|
||||
@ -1534,7 +1223,7 @@ TEST(span_test, from_array_constructor)
|
||||
// you should not be able to get writeable bytes for const objects
|
||||
span<const int> s = a;
|
||||
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(bs.size() == s.size_bytes());
|
||||
#endif
|
||||
@ -1542,7 +1231,7 @@ TEST(span_test, from_array_constructor)
|
||||
|
||||
{
|
||||
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() == 0);
|
||||
EXPECT_TRUE(bs.size_bytes() == 0);
|
||||
@ -1552,7 +1241,7 @@ TEST(span_test, from_array_constructor)
|
||||
|
||||
{
|
||||
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(bs.size() == s.size_bytes());
|
||||
}
|
||||
@ -1590,12 +1279,16 @@ TEST(span_test, from_array_constructor)
|
||||
|
||||
// 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;
|
||||
auto f = [&]() {
|
||||
const span<int, 2> s2 = s;
|
||||
static_cast<void>(s2);
|
||||
};
|
||||
EXPECT_DEATH(f(), deathstring);
|
||||
*/
|
||||
}
|
||||
|
||||
// but doing so explicitly is ok
|
||||
@ -1610,12 +1303,19 @@ TEST(span_test, from_array_constructor)
|
||||
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>
|
||||
span<int, 1> s1 = s4.first(1);
|
||||
static_cast<void>(s1);
|
||||
}
|
||||
*/
|
||||
|
||||
// initialization or assignment to static span that requires size INCREASE is not ok.
|
||||
int arr2[2] = {1, 2};
|
||||
@ -1637,12 +1337,15 @@ TEST(span_test, from_array_constructor)
|
||||
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
|
||||
span<int> av = arr2; auto f = [&]() {
|
||||
const span<int, 4> _s4 = av;
|
||||
static_cast<void>(_s4);
|
||||
};
|
||||
EXPECT_DEATH(f(), deathstring);
|
||||
*/
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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.back(), deathstring);
|
||||
}
|
||||
|
||||
#if __clang__ || __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // __clang__ || __GNUC__
|
||||
|
@ -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 <gsl/pointers> // for not_null, operator<, operator<=, operator>
|
||||
|
||||
@ -210,10 +188,3 @@ TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction)
|
||||
#endif
|
||||
}
|
||||
#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__
|
||||
|
@ -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 <gsl/gsl_byte> // for byte
|
||||
#include <gsl/gsl_util> // for narrow_cast
|
||||
@ -810,7 +788,3 @@ TEST(strided_span_tests, strided_span_conversion)
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
#if __clang__ || __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // __clang__ || __GNUC__
|
||||
|
@ -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 <gsl/gsl_assert> // for Expects, fail_fast (ptr only)
|
||||
@ -104,7 +84,7 @@ czstring_span<> CreateTempName(string_span<> span)
|
||||
{
|
||||
Expects(span.size() > 1);
|
||||
|
||||
int last = 0;
|
||||
std::size_t last = 0;
|
||||
if (span.size() > 4) {
|
||||
span[0] = 't';
|
||||
span[1] = 'm';
|
||||
@ -121,7 +101,7 @@ cwzstring_span<> CreateTempNameW(wstring_span<> span)
|
||||
{
|
||||
Expects(span.size() > 1);
|
||||
|
||||
int last = 0;
|
||||
std::size_t last = 0;
|
||||
if (span.size() > 4) {
|
||||
span[0] = L't';
|
||||
span[1] = L'm';
|
||||
@ -138,7 +118,7 @@ cu16zstring_span<> CreateTempNameU16(u16string_span<> span)
|
||||
{
|
||||
Expects(span.size() > 1);
|
||||
|
||||
int last = 0;
|
||||
std::size_t last = 0;
|
||||
if (span.size() > 4) {
|
||||
span[0] = u't';
|
||||
span[1] = u'm';
|
||||
@ -155,7 +135,7 @@ cu32zstring_span<> CreateTempNameU32(u32string_span<> span)
|
||||
{
|
||||
Expects(span.size() > 1);
|
||||
|
||||
int last = 0;
|
||||
std::size_t last = 0;
|
||||
if (span.size() > 4) {
|
||||
span[0] = U't';
|
||||
span[1] = U'm';
|
||||
@ -183,14 +163,14 @@ TEST(string_span_tests, TestConstructFromStdString)
|
||||
{
|
||||
std::string s = "Hello there world";
|
||||
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)
|
||||
{
|
||||
std::vector<char> vec(5, 'h');
|
||||
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)
|
||||
@ -252,7 +232,7 @@ TEST(string_span_tests, TestToString)
|
||||
char stack_string[] = "Hello";
|
||||
cstring_span<> v = ensure_z(stack_string);
|
||||
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));
|
||||
}
|
||||
|
||||
@ -265,7 +245,7 @@ TEST(string_span_tests, TestToBasicString)
|
||||
char stack_string[] = "Hello";
|
||||
cstring_span<> v = ensure_z(stack_string);
|
||||
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));
|
||||
}
|
||||
|
||||
@ -1226,16 +1206,12 @@ TEST(string_span_tests, as_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"};
|
||||
wzstring_span<> v(buf);
|
||||
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(bs.size() == s.size_bytes());
|
||||
}
|
||||
|
||||
#if __clang__ || __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // __clang__ || __GNUC__
|
||||
|
@ -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 <gsl/gsl_util> // for narrow, finally, narrow_cast, narrowing_e...
|
||||
@ -44,6 +23,7 @@
|
||||
#include <limits> // for numeric_limits
|
||||
#include <stdint.h> // for uint32_t, int32_t
|
||||
#include <type_traits> // for is_same
|
||||
#include <cstddef> // for std::ptrdiff_t
|
||||
|
||||
using namespace gsl;
|
||||
|
||||
@ -154,7 +134,3 @@ TEST(utils_tests, narrow)
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if __clang__ || __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // __clang__ || __GNUC__
|
||||
|
Loading…
x
Reference in New Issue
Block a user