mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
Merge branch 'master' into thread_classes
This commit is contained in:
commit
7d608055d8
@ -2,6 +2,49 @@ cmake_minimum_required(VERSION 2.8.7)
|
|||||||
|
|
||||||
project(GSL CXX)
|
project(GSL CXX)
|
||||||
|
|
||||||
|
# creates a library GSL which is an interface (header files only)
|
||||||
|
add_library(GSL INTERFACE)
|
||||||
|
|
||||||
|
# when minimum version required is 3.8.0 remove if below
|
||||||
|
# both branches do exactly the same thing
|
||||||
|
if ( CMAKE_MAJOR_VERSION VERSION_LESS 3.7.9)
|
||||||
|
if (NOT MSVC)
|
||||||
|
include(CheckCXXCompilerFlag)
|
||||||
|
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
|
||||||
|
if(COMPILER_SUPPORTS_CXX14)
|
||||||
|
target_compile_options(GSL INTERFACE "-std=c++14")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
else ()
|
||||||
|
# set the GSL library to be compiled only with c++14
|
||||||
|
target_compile_features(GSL INTERFACE cxx_std_14)
|
||||||
|
# on *nix systems force the use of -std=c++XX instead of -std=gnu++XX (default)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# add definitions to the library and targets that consume it
|
||||||
|
target_compile_definitions(GSL INTERFACE
|
||||||
|
$<$<CXX_COMPILER_ID:MSVC>:
|
||||||
|
# remove unnecessary warnings about unchecked iterators
|
||||||
|
_SCL_SECURE_NO_WARNINGS
|
||||||
|
>
|
||||||
|
)
|
||||||
|
|
||||||
|
# add include folders to the library and targets that consume it
|
||||||
|
target_include_directories(GSL INTERFACE
|
||||||
|
$<BUILD_INTERFACE:
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
|
>
|
||||||
|
)
|
||||||
|
|
||||||
|
# add natvis file to the library so it will automatically be loaded into Visual Studio
|
||||||
|
target_sources(GSL INTERFACE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/GSL.natvis
|
||||||
|
)
|
||||||
|
|
||||||
install(
|
install(
|
||||||
DIRECTORY include/gsl
|
DIRECTORY include/gsl
|
||||||
DESTINATION include
|
DESTINATION include
|
||||||
|
@ -27,8 +27,9 @@ The test suite that exercises GSL has been built and passes successfully on the
|
|||||||
* Windows using GCC 5.1
|
* Windows using GCC 5.1
|
||||||
* GNU/Linux using Clang/LLVM 3.6
|
* GNU/Linux using Clang/LLVM 3.6
|
||||||
* GNU/Linux using GCC 5.1
|
* GNU/Linux using GCC 5.1
|
||||||
* OS X Yosemite using Xcode with AppleClang 7.0.0.7000072
|
* OS X Yosemite using Xcode with Apple Clang 7.0.0.7000072
|
||||||
* OS X Yosemite using GCC-5.2.0
|
* OS X Yosemite using GCC-5.2.0
|
||||||
|
* OS X Sierra 10.12.4 using Apple LLVM version 8.1.0 (Clang-802.0.42)
|
||||||
* FreeBSD 10.x with Clang/LLVM 3.6
|
* FreeBSD 10.x with Clang/LLVM 3.6
|
||||||
|
|
||||||
> If you successfully port GSL to another platform, we would love to hear from you. Please submit an issue to let us know. Also please consider
|
> If you successfully port GSL to another platform, we would love to hear from you. Please submit an issue to let us know. Also please consider
|
||||||
|
@ -25,23 +25,25 @@
|
|||||||
#include <gsl/span> // span
|
#include <gsl/span> // span
|
||||||
#include <gsl/string_span> // zstring, string_span, zstring_builder...
|
#include <gsl/string_span> // zstring, string_span, zstring_builder...
|
||||||
#include <gsl/gsl_thread> // raii_thread, detached_thread...
|
#include <gsl/gsl_thread> // raii_thread, detached_thread...
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1910
|
#if defined(_MSC_VER) && _MSC_VER < 1910
|
||||||
#pragma push_macro("constexpr")
|
#pragma push_macro("constexpr")
|
||||||
#define constexpr /*constexpr*/
|
#define constexpr /*constexpr*/
|
||||||
|
|
||||||
// MSVC 2013 workarounds
|
// MSVC 2013 workarounds
|
||||||
#if _MSC_VER <= 1800
|
#if _MSC_VER <= 1800
|
||||||
// noexcept is not understood
|
// noexcept is not understood
|
||||||
#pragma push_macro("noexcept")
|
#pragma push_macro("noexcept")
|
||||||
#define noexcept /*noexcept*/
|
#define noexcept /*noexcept*/
|
||||||
|
|
||||||
// turn off some misguided warnings
|
// turn off some misguided warnings
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
|
#pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
|
||||||
#endif // _MSC_VER <= 1800
|
#endif // _MSC_VER <= 1800
|
||||||
#endif // defined(_MSC_VER) && _MSC_VER < 1910
|
#endif // defined(_MSC_VER) && _MSC_VER < 1910
|
||||||
|
|
||||||
namespace gsl
|
namespace gsl
|
||||||
@ -77,10 +79,15 @@ public:
|
|||||||
static_assert(std::is_assignable<T&, std::nullptr_t>::value, "T cannot be assigned nullptr.");
|
static_assert(std::is_assignable<T&, std::nullptr_t>::value, "T cannot be assigned nullptr.");
|
||||||
|
|
||||||
template <typename U, typename Dummy = std::enable_if_t<std::is_convertible<U, T>::value>>
|
template <typename U, typename Dummy = std::enable_if_t<std::is_convertible<U, T>::value>>
|
||||||
constexpr not_null(U&& u) : ptr_(std::forward<U>(u)) { Expects(ptr_ != nullptr); }
|
constexpr not_null(U&& u) : ptr_(std::forward<U>(u))
|
||||||
|
{
|
||||||
|
Expects(ptr_ != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename U, typename Dummy = std::enable_if_t<std::is_convertible<U, T>::value>>
|
template <typename U, typename Dummy = std::enable_if_t<std::is_convertible<U, T>::value>>
|
||||||
constexpr not_null(const not_null<U>& other) : not_null(other.get()) {}
|
constexpr not_null(const not_null<U>& other) : not_null(other.get())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
not_null(const not_null& other) = default;
|
not_null(const not_null& other) = default;
|
||||||
not_null& operator=(const not_null& other) = default;
|
not_null& operator=(const not_null& other) = default;
|
||||||
@ -177,15 +184,15 @@ struct hash<gsl::not_null<T>>
|
|||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1910
|
#if defined(_MSC_VER) && _MSC_VER < 1910
|
||||||
#undef constexpr
|
#undef constexpr
|
||||||
#pragma pop_macro("constexpr")
|
#pragma pop_macro("constexpr")
|
||||||
|
|
||||||
#if _MSC_VER <= 1800
|
#if _MSC_VER <= 1800
|
||||||
#undef noexcept
|
#undef noexcept
|
||||||
#pragma pop_macro("noexcept")
|
#pragma pop_macro("noexcept")
|
||||||
|
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif // _MSC_VER <= 1800
|
#endif // _MSC_VER <= 1800
|
||||||
#endif // defined(_MSC_VER) && _MSC_VER < 1910
|
#endif // defined(_MSC_VER) && _MSC_VER < 1910
|
||||||
|
|
||||||
#endif // GSL_GSL_H
|
#endif // GSL_GSL_H
|
||||||
|
@ -20,30 +20,32 @@
|
|||||||
#define GSL_ALGORITHM_H
|
#define GSL_ALGORITHM_H
|
||||||
|
|
||||||
#include <gsl/span>
|
#include <gsl/span>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
|
||||||
// turn off some warnings that are noisy about our Expects statements
|
// turn off some warnings that are noisy about our Expects statements
|
||||||
#pragma warning(disable : 4127) // conditional expression is constant
|
#pragma warning(disable : 4127) // conditional expression is constant
|
||||||
|
|
||||||
// blanket turn off warnings from CppCoreCheck for now
|
// blanket turn off warnings from CppCoreCheck for now
|
||||||
// so people aren't annoyed by them when running the tool.
|
// so people aren't annoyed by them when running the tool.
|
||||||
// more targeted suppressions will be added in a future update to the GSL
|
// more targeted suppressions will be added in a future update to the GSL
|
||||||
#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
|
#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
namespace gsl
|
namespace gsl
|
||||||
{
|
{
|
||||||
|
|
||||||
template <class SrcElementType, std::ptrdiff_t SrcExtent,
|
template <class SrcElementType, std::ptrdiff_t SrcExtent, class DestElementType,
|
||||||
class DestElementType, std::ptrdiff_t DestExtent>
|
std::ptrdiff_t DestExtent>
|
||||||
void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent> dest)
|
void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent> dest)
|
||||||
{
|
{
|
||||||
static_assert(std::is_assignable<decltype(*dest.data()), decltype(*src.data())>::value,
|
static_assert(std::is_assignable<decltype(*dest.data()), decltype(*src.data())>::value,
|
||||||
"Elements of source span can not be assigned to elements of destination span");
|
"Elements of source span can not be assigned to elements of destination span");
|
||||||
static_assert(SrcExtent == dynamic_extent || DestExtent == dynamic_extent || (SrcExtent <= DestExtent),
|
static_assert(SrcExtent == dynamic_extent || DestExtent == dynamic_extent ||
|
||||||
|
(SrcExtent <= DestExtent),
|
||||||
"Source range is longer than target range");
|
"Source range is longer than target range");
|
||||||
|
|
||||||
Expects(dest.size() >= src.size());
|
Expects(dest.size() >= src.size());
|
||||||
@ -53,7 +55,7 @@ void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent>
|
|||||||
} // namespace gsl
|
} // namespace gsl
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#endif // GSL_ALGORITHM_H
|
#endif // GSL_ALGORITHM_H
|
||||||
|
@ -32,18 +32,18 @@
|
|||||||
//
|
//
|
||||||
#if !(defined(GSL_THROW_ON_CONTRACT_VIOLATION) || defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) || \
|
#if !(defined(GSL_THROW_ON_CONTRACT_VIOLATION) || defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) || \
|
||||||
defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION))
|
defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION))
|
||||||
#define GSL_TERMINATE_ON_CONTRACT_VIOLATION
|
#define GSL_TERMINATE_ON_CONTRACT_VIOLATION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GSL_STRINGIFY_DETAIL(x) #x
|
#define GSL_STRINGIFY_DETAIL(x) #x
|
||||||
#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x)
|
#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x)
|
||||||
|
|
||||||
#if defined(__clang__) || defined(__GNUC__)
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
#define GSL_LIKELY(x) __builtin_expect (!!(x), 1)
|
#define GSL_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||||
#define GSL_UNLIKELY(x) __builtin_expect (!!(x), 0)
|
#define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||||
#else
|
#else
|
||||||
#define GSL_LIKELY(x) (!!(x))
|
#define GSL_LIKELY(x) (!!(x))
|
||||||
#define GSL_UNLIKELY(x) (!!(x))
|
#define GSL_UNLIKELY(x) (!!(x))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -53,13 +53,13 @@
|
|||||||
// whether or not cond is actually evaluated.
|
// whether or not cond is actually evaluated.
|
||||||
//
|
//
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define GSL_ASSUME(cond) __assume(cond)
|
#define GSL_ASSUME(cond) __assume(cond)
|
||||||
#elif defined(__clang__)
|
#elif defined(__clang__)
|
||||||
#define GSL_ASSUME(cond) __builtin_assume(cond)
|
#define GSL_ASSUME(cond) __builtin_assume(cond)
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
#define GSL_ASSUME(cond) ((cond) ? static_cast<void>(0) : __builtin_unreachable())
|
#define GSL_ASSUME(cond) ((cond) ? static_cast<void>(0) : __builtin_unreachable())
|
||||||
#else
|
#else
|
||||||
#define GSL_ASSUME(cond) static_cast<void>(!!(cond))
|
#define GSL_ASSUME(cond) static_cast<void>(!!(cond))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -76,18 +76,18 @@ struct fail_fast : public std::logic_error
|
|||||||
|
|
||||||
#if defined(GSL_THROW_ON_CONTRACT_VIOLATION)
|
#if defined(GSL_THROW_ON_CONTRACT_VIOLATION)
|
||||||
|
|
||||||
#define GSL_CONTRACT_CHECK(type, cond) \
|
#define GSL_CONTRACT_CHECK(type, cond) \
|
||||||
(GSL_LIKELY(cond) ? static_cast<void>(0) : \
|
(GSL_LIKELY(cond) ? static_cast<void>(0) \
|
||||||
throw gsl::fail_fast("GSL: " type " failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__)))
|
: throw gsl::fail_fast("GSL: " type " failure at " __FILE__ \
|
||||||
|
": " GSL_STRINGIFY(__LINE__)))
|
||||||
|
|
||||||
#elif defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
|
#elif defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
|
||||||
|
|
||||||
#define GSL_CONTRACT_CHECK(type, cond) \
|
#define GSL_CONTRACT_CHECK(type, cond) (GSL_LIKELY(cond) ? static_cast<void>(0) : std::terminate())
|
||||||
(GSL_LIKELY(cond) ? static_cast<void>(0) : std::terminate())
|
|
||||||
|
|
||||||
#elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)
|
#elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)
|
||||||
|
|
||||||
#define GSL_CONTRACT_CHECK(type, cond) GSL_ASSUME(cond)
|
#define GSL_CONTRACT_CHECK(type, cond) GSL_ASSUME(cond)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -22,21 +22,21 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
|
||||||
// don't warn about function style casts in byte related operators
|
// don't warn about function style casts in byte related operators
|
||||||
#pragma warning(disable : 26493)
|
#pragma warning(disable : 26493)
|
||||||
|
|
||||||
// MSVC 2013 workarounds
|
// MSVC 2013 workarounds
|
||||||
#if _MSC_VER <= 1800
|
#if _MSC_VER <= 1800
|
||||||
// constexpr is not understood
|
// constexpr is not understood
|
||||||
#pragma push_macro("constexpr")
|
#pragma push_macro("constexpr")
|
||||||
#define constexpr /*constexpr*/
|
#define constexpr /*constexpr*/
|
||||||
|
|
||||||
// noexcept is not understood
|
// noexcept is not understood
|
||||||
#pragma push_macro("noexcept")
|
#pragma push_macro("noexcept")
|
||||||
#define noexcept /*noexcept*/
|
#define noexcept /*noexcept*/
|
||||||
#endif // _MSC_VER <= 1800
|
#endif // _MSC_VER <= 1800
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
namespace gsl
|
namespace gsl
|
||||||
@ -109,23 +109,21 @@ inline constexpr IntegerType to_integer(byte b) noexcept
|
|||||||
return static_cast<IntegerType>(b);
|
return static_cast<IntegerType>(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool E, typename T>
|
template <bool E, typename T>
|
||||||
inline constexpr byte to_byte_impl(T t) noexcept
|
inline constexpr byte to_byte_impl(T t) noexcept
|
||||||
{
|
{
|
||||||
static_assert(
|
static_assert(
|
||||||
E,
|
E, "gsl::to_byte(t) must be provided an unsigned char, otherwise data loss may occur. "
|
||||||
"gsl::to_byte(t) must be provided an unsigned char, otherwise data loss may occur. "
|
"If you are calling to_byte with an integer contant use: gsl::to_byte<t>() version.");
|
||||||
"If you are calling to_byte with an integer contant use: gsl::to_byte<t>() version."
|
|
||||||
);
|
|
||||||
return static_cast<byte>(t);
|
return static_cast<byte>(t);
|
||||||
}
|
}
|
||||||
template<>
|
template <>
|
||||||
inline constexpr byte to_byte_impl<true, unsigned char>(unsigned char t) noexcept
|
inline constexpr byte to_byte_impl<true, unsigned char>(unsigned char t) noexcept
|
||||||
{
|
{
|
||||||
return byte(t);
|
return byte(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
inline constexpr byte to_byte(T t) noexcept
|
inline constexpr byte to_byte(T t) noexcept
|
||||||
{
|
{
|
||||||
return to_byte_impl<std::is_same<T, unsigned char>::value, T>(t);
|
return to_byte_impl<std::is_same<T, unsigned char>::value, T>(t);
|
||||||
@ -134,22 +132,23 @@ inline constexpr byte to_byte(T t) noexcept
|
|||||||
template <int I>
|
template <int I>
|
||||||
inline constexpr byte to_byte() noexcept
|
inline constexpr byte to_byte() noexcept
|
||||||
{
|
{
|
||||||
static_assert(I >= 0 && I <= 255, "gsl::byte only has 8 bits of storage, values must be in range 0-255");
|
static_assert(I >= 0 && I <= 255,
|
||||||
|
"gsl::byte only has 8 bits of storage, values must be in range 0-255");
|
||||||
return static_cast<byte>(I);
|
return static_cast<byte>(I);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace gsl
|
} // namespace gsl
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#if _MSC_VER <= 1800
|
#if _MSC_VER <= 1800
|
||||||
#undef constexpr
|
#undef constexpr
|
||||||
#pragma pop_macro("constexpr")
|
#pragma pop_macro("constexpr")
|
||||||
|
|
||||||
#undef noexcept
|
#undef noexcept
|
||||||
#pragma pop_macro("noexcept")
|
#pragma pop_macro("noexcept")
|
||||||
#endif // _MSC_VER <= 1800
|
#endif // _MSC_VER <= 1800
|
||||||
|
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#endif // GSL_BYTE_H
|
#endif // GSL_BYTE_H
|
||||||
|
@ -20,27 +20,28 @@
|
|||||||
#define GSL_UTIL_H
|
#define GSL_UTIL_H
|
||||||
|
|
||||||
#include <gsl/gsl_assert> // Ensures/Expects
|
#include <gsl/gsl_assert> // Ensures/Expects
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4127) // conditional expression is constant
|
#pragma warning(disable : 4127) // conditional expression is constant
|
||||||
|
|
||||||
#if _MSC_VER < 1910
|
#if _MSC_VER < 1910
|
||||||
#pragma push_macro("constexpr")
|
#pragma push_macro("constexpr")
|
||||||
#define constexpr /*constexpr*/
|
#define constexpr /*constexpr*/
|
||||||
// MSVC 2013 workarounds
|
// MSVC 2013 workarounds
|
||||||
#if _MSC_VER <= 1800
|
#if _MSC_VER <= 1800
|
||||||
// noexcept is not understood
|
// noexcept is not understood
|
||||||
#pragma push_macro("noexcept")
|
#pragma push_macro("noexcept")
|
||||||
#define noexcept /*noexcept*/
|
#define noexcept /*noexcept*/
|
||||||
// turn off some misguided warnings
|
// turn off some misguided warnings
|
||||||
#pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
|
#pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
|
||||||
#endif // _MSC_VER <= 1800
|
#endif // _MSC_VER <= 1800
|
||||||
#endif // _MSC_VER < 1910
|
#endif // _MSC_VER < 1910
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
namespace gsl
|
namespace gsl
|
||||||
@ -154,16 +155,16 @@ inline constexpr T at(const std::initializer_list<T> cont, const std::ptrdiff_t
|
|||||||
} // namespace gsl
|
} // namespace gsl
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#if _MSC_VER < 1910
|
#if _MSC_VER < 1910
|
||||||
#undef constexpr
|
#undef constexpr
|
||||||
#pragma pop_macro("constexpr")
|
#pragma pop_macro("constexpr")
|
||||||
|
|
||||||
#if _MSC_VER <= 1800
|
#if _MSC_VER <= 1800
|
||||||
#undef noexcept
|
#undef noexcept
|
||||||
#pragma pop_macro("noexcept")
|
#pragma pop_macro("noexcept")
|
||||||
#endif // _MSC_VER <= 1800
|
#endif // _MSC_VER <= 1800
|
||||||
#endif // _MSC_VER < 1910
|
#endif // _MSC_VER < 1910
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#endif // GSL_UTIL_H
|
#endif // GSL_UTIL_H
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <gsl/gsl_assert>
|
#include <gsl/gsl_assert>
|
||||||
#include <gsl/gsl_byte>
|
#include <gsl/gsl_byte>
|
||||||
#include <gsl/gsl_util>
|
#include <gsl/gsl_util>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -37,34 +38,34 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
// turn off some warnings that are noisy about our Expects statements
|
// turn off some warnings that are noisy about our Expects statements
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4127) // conditional expression is constant
|
#pragma warning(disable : 4127) // conditional expression is constant
|
||||||
|
|
||||||
#if _MSC_VER < 1910
|
#if _MSC_VER < 1910
|
||||||
#pragma push_macro("constexpr")
|
#pragma push_macro("constexpr")
|
||||||
#define constexpr /*constexpr*/
|
#define constexpr /*constexpr*/
|
||||||
|
|
||||||
// VS 2013 workarounds
|
// VS 2013 workarounds
|
||||||
#if _MSC_VER <= 1800
|
#if _MSC_VER <= 1800
|
||||||
#define GSL_MSVC_HAS_VARIADIC_CTOR_BUG
|
#define GSL_MSVC_HAS_VARIADIC_CTOR_BUG
|
||||||
#define GSL_MSVC_NO_SUPPORT_FOR_MOVE_CTOR_DEFAULT
|
#define GSL_MSVC_NO_SUPPORT_FOR_MOVE_CTOR_DEFAULT
|
||||||
|
|
||||||
// noexcept is not understood
|
// noexcept is not understood
|
||||||
#pragma push_macro("noexcept")
|
#pragma push_macro("noexcept")
|
||||||
#define noexcept /*noexcept*/
|
#define noexcept /*noexcept*/
|
||||||
|
|
||||||
// turn off some misguided warnings
|
// turn off some misguided warnings
|
||||||
#pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
|
#pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
|
||||||
#pragma warning(disable : 4512) // warns that assignment op could not be generated
|
#pragma warning(disable : 4512) // warns that assignment op could not be generated
|
||||||
#endif // _MSC_VER <= 1800
|
#endif // _MSC_VER <= 1800
|
||||||
#endif // _MSC_VER < 1910
|
#endif // _MSC_VER < 1910
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#ifdef GSL_THROW_ON_CONTRACT_VIOLATION
|
#ifdef GSL_THROW_ON_CONTRACT_VIOLATION
|
||||||
#define GSL_NOEXCEPT /*noexcept*/
|
#define GSL_NOEXCEPT /*noexcept*/
|
||||||
#else
|
#else
|
||||||
#define GSL_NOEXCEPT noexcept
|
#define GSL_NOEXCEPT noexcept
|
||||||
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
|
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
|
||||||
|
|
||||||
namespace gsl
|
namespace gsl
|
||||||
@ -207,7 +208,10 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend constexpr index operator*(value_type v, const index& rhs) GSL_NOEXCEPT { return rhs * v; }
|
friend constexpr index operator*(value_type v, const index& rhs) GSL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return rhs * v;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr index& operator*=(value_type v) GSL_NOEXCEPT
|
constexpr index& operator*=(value_type v) GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
@ -344,10 +348,11 @@ namespace details
|
|||||||
static const std::size_t DynamicNum = Base::DynamicNum + 1;
|
static const std::size_t DynamicNum = Base::DynamicNum + 1;
|
||||||
static const size_type CurrentRange = dynamic_range;
|
static const size_type CurrentRange = dynamic_range;
|
||||||
static const size_type TotalSize = dynamic_range;
|
static const size_type TotalSize = dynamic_range;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_type m_bound;
|
size_type m_bound;
|
||||||
public:
|
|
||||||
|
|
||||||
|
public:
|
||||||
BoundsRanges(const std::ptrdiff_t* const arr)
|
BoundsRanges(const std::ptrdiff_t* const arr)
|
||||||
: Base(arr + 1), m_bound(*arr * this->Base::totalSize())
|
: Base(arr + 1), m_bound(*arr * this->Base::totalSize())
|
||||||
{
|
{
|
||||||
@ -492,7 +497,8 @@ namespace details
|
|||||||
return obj_;
|
return obj_;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t N, typename MyChain = TypeChain, typename MyBase = typename MyChain::Base>
|
template <std::size_t N, typename MyChain = TypeChain,
|
||||||
|
typename MyBase = typename MyChain::Base>
|
||||||
auto getObj(std::false_type)
|
auto getObj(std::false_type)
|
||||||
-> decltype(TypeListIndexer<MyBase>(static_cast<const MyBase&>(obj_)).template get<N>())
|
-> decltype(TypeListIndexer<MyBase>(static_cast<const MyBase&>(obj_)).template get<N>())
|
||||||
{
|
{
|
||||||
@ -690,7 +696,10 @@ public:
|
|||||||
return !(*this == rhs);
|
return !(*this == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr const_iterator begin() const GSL_NOEXCEPT { return const_iterator(*this, index_type{}); }
|
constexpr const_iterator begin() const GSL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return const_iterator(*this, index_type{});
|
||||||
|
}
|
||||||
|
|
||||||
constexpr const_iterator end() const GSL_NOEXCEPT
|
constexpr const_iterator end() const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
@ -790,9 +799,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr index_type index_bounds() const GSL_NOEXCEPT { return m_extents; }
|
constexpr index_type index_bounds() const GSL_NOEXCEPT { return m_extents; }
|
||||||
constexpr const_iterator begin() const GSL_NOEXCEPT { return const_iterator{*this, index_type{}}; }
|
constexpr const_iterator begin() const GSL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return const_iterator{*this, index_type{}};
|
||||||
|
}
|
||||||
|
|
||||||
constexpr const_iterator end() const GSL_NOEXCEPT { return const_iterator{*this, index_bounds()}; }
|
constexpr const_iterator end() const GSL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return const_iterator{*this, index_bounds()};
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
index_type m_extents;
|
index_type m_extents;
|
||||||
@ -931,18 +946,27 @@ public:
|
|||||||
return curr_ == rhs.curr_;
|
return curr_ == rhs.curr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool operator!=(const bounds_iterator& rhs) const GSL_NOEXCEPT { return !(*this == rhs); }
|
constexpr bool operator!=(const bounds_iterator& rhs) const GSL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
constexpr bool operator<(const bounds_iterator& rhs) const GSL_NOEXCEPT
|
constexpr bool operator<(const bounds_iterator& rhs) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
return less(curr_, rhs.curr_);
|
return less(curr_, rhs.curr_);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool operator<=(const bounds_iterator& rhs) const GSL_NOEXCEPT { return !(rhs < *this); }
|
constexpr bool operator<=(const bounds_iterator& rhs) const GSL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return !(rhs < *this);
|
||||||
|
}
|
||||||
|
|
||||||
constexpr bool operator>(const bounds_iterator& rhs) const GSL_NOEXCEPT { return rhs < *this; }
|
constexpr bool operator>(const bounds_iterator& rhs) const GSL_NOEXCEPT { return rhs < *this; }
|
||||||
|
|
||||||
constexpr bool operator>=(const bounds_iterator& rhs) const GSL_NOEXCEPT { return !(rhs > *this); }
|
constexpr bool operator>=(const bounds_iterator& rhs) const GSL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return !(rhs > *this);
|
||||||
|
}
|
||||||
|
|
||||||
void swap(bounds_iterator& rhs) GSL_NOEXCEPT
|
void swap(bounds_iterator& rhs) GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
@ -1227,7 +1251,8 @@ public:
|
|||||||
|
|
||||||
// construct from nullptr with size of 0 (helps with template function calls)
|
// construct from nullptr with size of 0 (helps with template function calls)
|
||||||
template <class IntType, typename = std::enable_if_t<std::is_integral<IntType>::value>>
|
template <class IntType, typename = std::enable_if_t<std::is_integral<IntType>::value>>
|
||||||
constexpr multi_span(std::nullptr_t, IntType size) GSL_NOEXCEPT : multi_span(nullptr, bounds_type{})
|
constexpr multi_span(std::nullptr_t, IntType size) GSL_NOEXCEPT
|
||||||
|
: multi_span(nullptr, bounds_type{})
|
||||||
{
|
{
|
||||||
static_assert(bounds_type::dynamic_rank != 0 ||
|
static_assert(bounds_type::dynamic_rank != 0 ||
|
||||||
(bounds_type::dynamic_rank == 0 && bounds_type::static_size == 0),
|
(bounds_type::dynamic_rank == 0 && bounds_type::static_size == 0),
|
||||||
@ -1249,7 +1274,8 @@ public:
|
|||||||
constexpr multi_span(value_type&&) = delete;
|
constexpr multi_span(value_type&&) = delete;
|
||||||
|
|
||||||
// construct from pointer + length
|
// construct from pointer + length
|
||||||
constexpr multi_span(pointer ptr, size_type size) GSL_NOEXCEPT : multi_span(ptr, bounds_type{size})
|
constexpr multi_span(pointer ptr, size_type size) GSL_NOEXCEPT
|
||||||
|
: multi_span(ptr, bounds_type{size})
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1426,9 +1452,8 @@ public:
|
|||||||
|
|
||||||
// subspan() - create a subview of count elements starting at offset
|
// subspan() - create a subview of count elements starting at offset
|
||||||
// supplying dynamic_range for count will consume all available elements from offset
|
// supplying dynamic_range for count will consume all available elements from offset
|
||||||
constexpr multi_span<ValueType, dynamic_range> subspan(size_type offset,
|
constexpr multi_span<ValueType, dynamic_range>
|
||||||
size_type count = dynamic_range) const
|
subspan(size_type offset, size_type count = dynamic_range) const GSL_NOEXCEPT
|
||||||
GSL_NOEXCEPT
|
|
||||||
{
|
{
|
||||||
Expects((offset >= 0 && offset <= this->size()) &&
|
Expects((offset >= 0 && offset <= this->size()) &&
|
||||||
(count == dynamic_range || (count <= this->size() - offset)));
|
(count == dynamic_range || (count <= this->size() - offset)));
|
||||||
@ -1436,8 +1461,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// section - creates a non-contiguous, strided multi_span from a contiguous one
|
// section - creates a non-contiguous, strided multi_span from a contiguous one
|
||||||
constexpr strided_span<ValueType, Rank> section(index_type origin, index_type extents) const
|
constexpr strided_span<ValueType, Rank> section(index_type origin,
|
||||||
GSL_NOEXCEPT
|
index_type extents) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
size_type size = this->bounds().total_size() - this->bounds().linearize(origin);
|
size_type size = this->bounds().total_size() - this->bounds().linearize(origin);
|
||||||
return {&this->operator[](origin), size,
|
return {&this->operator[](origin), size,
|
||||||
@ -1451,7 +1476,10 @@ public:
|
|||||||
constexpr size_type length() const GSL_NOEXCEPT { return this->size(); }
|
constexpr size_type length() const GSL_NOEXCEPT { return this->size(); }
|
||||||
|
|
||||||
// length of the multi_span in bytes
|
// length of the multi_span in bytes
|
||||||
constexpr size_type size_bytes() const GSL_NOEXCEPT { return narrow_cast<size_type>(sizeof(value_type)) * this->size(); }
|
constexpr size_type size_bytes() const GSL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return narrow_cast<size_type>(sizeof(value_type)) * this->size();
|
||||||
|
}
|
||||||
|
|
||||||
// length of the multi_span in bytes
|
// length of the multi_span in bytes
|
||||||
constexpr size_type length_bytes() const GSL_NOEXCEPT { return this->size_bytes(); }
|
constexpr size_type length_bytes() const GSL_NOEXCEPT { return this->size_bytes(); }
|
||||||
@ -1539,8 +1567,8 @@ public:
|
|||||||
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
|
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
|
||||||
typename Dummy = std::enable_if_t<std::is_same<
|
typename Dummy = std::enable_if_t<std::is_same<
|
||||||
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
||||||
constexpr bool operator==(const multi_span<OtherValueType, OtherDimensions...>& other) const
|
constexpr bool
|
||||||
GSL_NOEXCEPT
|
operator==(const multi_span<OtherValueType, OtherDimensions...>& other) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
return bounds_.size() == other.bounds_.size() &&
|
return bounds_.size() == other.bounds_.size() &&
|
||||||
(data_ == other.data_ || std::equal(this->begin(), this->end(), other.begin()));
|
(data_ == other.data_ || std::equal(this->begin(), this->end(), other.begin()));
|
||||||
@ -1549,8 +1577,8 @@ public:
|
|||||||
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
|
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
|
||||||
typename Dummy = std::enable_if_t<std::is_same<
|
typename Dummy = std::enable_if_t<std::is_same<
|
||||||
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
||||||
constexpr bool operator!=(const multi_span<OtherValueType, OtherDimensions...>& other) const
|
constexpr bool
|
||||||
GSL_NOEXCEPT
|
operator!=(const multi_span<OtherValueType, OtherDimensions...>& other) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
@ -1558,8 +1586,8 @@ public:
|
|||||||
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
|
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
|
||||||
typename Dummy = std::enable_if_t<std::is_same<
|
typename Dummy = std::enable_if_t<std::is_same<
|
||||||
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
||||||
constexpr bool operator<(const multi_span<OtherValueType, OtherDimensions...>& other) const
|
constexpr bool
|
||||||
GSL_NOEXCEPT
|
operator<(const multi_span<OtherValueType, OtherDimensions...>& other) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
return std::lexicographical_compare(this->begin(), this->end(), other.begin(), other.end());
|
return std::lexicographical_compare(this->begin(), this->end(), other.begin(), other.end());
|
||||||
}
|
}
|
||||||
@ -1567,8 +1595,8 @@ public:
|
|||||||
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
|
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
|
||||||
typename Dummy = std::enable_if_t<std::is_same<
|
typename Dummy = std::enable_if_t<std::is_same<
|
||||||
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
||||||
constexpr bool operator<=(const multi_span<OtherValueType, OtherDimensions...>& other) const
|
constexpr bool
|
||||||
GSL_NOEXCEPT
|
operator<=(const multi_span<OtherValueType, OtherDimensions...>& other) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
return !(other < *this);
|
return !(other < *this);
|
||||||
}
|
}
|
||||||
@ -1576,8 +1604,8 @@ public:
|
|||||||
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
|
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
|
||||||
typename Dummy = std::enable_if_t<std::is_same<
|
typename Dummy = std::enable_if_t<std::is_same<
|
||||||
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
||||||
constexpr bool operator>(const multi_span<OtherValueType, OtherDimensions...>& other) const
|
constexpr bool
|
||||||
GSL_NOEXCEPT
|
operator>(const multi_span<OtherValueType, OtherDimensions...>& other) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
return (other < *this);
|
return (other < *this);
|
||||||
}
|
}
|
||||||
@ -1585,8 +1613,8 @@ public:
|
|||||||
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
|
template <typename OtherValueType, std::ptrdiff_t... OtherDimensions,
|
||||||
typename Dummy = std::enable_if_t<std::is_same<
|
typename Dummy = std::enable_if_t<std::is_same<
|
||||||
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
||||||
constexpr bool operator>=(const multi_span<OtherValueType, OtherDimensions...>& other) const
|
constexpr bool
|
||||||
GSL_NOEXCEPT
|
operator>=(const multi_span<OtherValueType, OtherDimensions...>& other) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
return !(*this < other);
|
return !(*this < other);
|
||||||
}
|
}
|
||||||
@ -1638,7 +1666,8 @@ multi_span<byte> as_writeable_bytes(multi_span<U, Dimensions...> s) GSL_NOEXCEPT
|
|||||||
// on all implementations. It should be considered an experimental extension
|
// on all implementations. It should be considered an experimental extension
|
||||||
// to the standard GSL interface.
|
// to the standard GSL interface.
|
||||||
template <typename U, std::ptrdiff_t... Dimensions>
|
template <typename U, std::ptrdiff_t... Dimensions>
|
||||||
inline constexpr auto as_multi_span(multi_span<const byte, Dimensions...> s) GSL_NOEXCEPT -> multi_span<
|
inline constexpr auto
|
||||||
|
as_multi_span(multi_span<const byte, Dimensions...> s) GSL_NOEXCEPT -> multi_span<
|
||||||
const U, static_cast<std::ptrdiff_t>(
|
const U, static_cast<std::ptrdiff_t>(
|
||||||
multi_span<const byte, Dimensions...>::bounds_type::static_size != dynamic_range
|
multi_span<const byte, Dimensions...>::bounds_type::static_size != dynamic_range
|
||||||
? (static_cast<std::size_t>(
|
? (static_cast<std::size_t>(
|
||||||
@ -1830,7 +1859,8 @@ public:
|
|||||||
|
|
||||||
size_type size = this->bounds().total_size() / d;
|
size_type size = this->bounds().total_size() / d;
|
||||||
return {const_cast<OtherValueType*>(reinterpret_cast<const OtherValueType*>(this->data())),
|
return {const_cast<OtherValueType*>(reinterpret_cast<const OtherValueType*>(this->data())),
|
||||||
size, bounds_type{resize_extent(this->bounds().index_bounds(), d),
|
size,
|
||||||
|
bounds_type{resize_extent(this->bounds().index_bounds(), d),
|
||||||
resize_stride(this->bounds().strides(), d)}};
|
resize_stride(this->bounds().strides(), d)}};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1898,7 +1928,8 @@ public:
|
|||||||
template <typename OtherValueType, std::ptrdiff_t OtherRank,
|
template <typename OtherValueType, std::ptrdiff_t OtherRank,
|
||||||
typename Dummy = std::enable_if_t<std::is_same<
|
typename Dummy = std::enable_if_t<std::is_same<
|
||||||
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
||||||
constexpr bool operator==(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
|
constexpr bool
|
||||||
|
operator==(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
return bounds_.size() == other.bounds_.size() &&
|
return bounds_.size() == other.bounds_.size() &&
|
||||||
(data_ == other.data_ || std::equal(this->begin(), this->end(), other.begin()));
|
(data_ == other.data_ || std::equal(this->begin(), this->end(), other.begin()));
|
||||||
@ -1907,7 +1938,8 @@ public:
|
|||||||
template <typename OtherValueType, std::ptrdiff_t OtherRank,
|
template <typename OtherValueType, std::ptrdiff_t OtherRank,
|
||||||
typename Dummy = std::enable_if_t<std::is_same<
|
typename Dummy = std::enable_if_t<std::is_same<
|
||||||
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
||||||
constexpr bool operator!=(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
|
constexpr bool
|
||||||
|
operator!=(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
@ -1915,7 +1947,8 @@ public:
|
|||||||
template <typename OtherValueType, std::ptrdiff_t OtherRank,
|
template <typename OtherValueType, std::ptrdiff_t OtherRank,
|
||||||
typename Dummy = std::enable_if_t<std::is_same<
|
typename Dummy = std::enable_if_t<std::is_same<
|
||||||
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
||||||
constexpr bool operator<(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
|
constexpr bool
|
||||||
|
operator<(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
return std::lexicographical_compare(this->begin(), this->end(), other.begin(), other.end());
|
return std::lexicographical_compare(this->begin(), this->end(), other.begin(), other.end());
|
||||||
}
|
}
|
||||||
@ -1923,7 +1956,8 @@ public:
|
|||||||
template <typename OtherValueType, std::ptrdiff_t OtherRank,
|
template <typename OtherValueType, std::ptrdiff_t OtherRank,
|
||||||
typename Dummy = std::enable_if_t<std::is_same<
|
typename Dummy = std::enable_if_t<std::is_same<
|
||||||
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
||||||
constexpr bool operator<=(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
|
constexpr bool
|
||||||
|
operator<=(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
return !(other < *this);
|
return !(other < *this);
|
||||||
}
|
}
|
||||||
@ -1931,7 +1965,8 @@ public:
|
|||||||
template <typename OtherValueType, std::ptrdiff_t OtherRank,
|
template <typename OtherValueType, std::ptrdiff_t OtherRank,
|
||||||
typename Dummy = std::enable_if_t<std::is_same<
|
typename Dummy = std::enable_if_t<std::is_same<
|
||||||
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
||||||
constexpr bool operator>(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
|
constexpr bool
|
||||||
|
operator>(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
return (other < *this);
|
return (other < *this);
|
||||||
}
|
}
|
||||||
@ -1939,7 +1974,8 @@ public:
|
|||||||
template <typename OtherValueType, std::ptrdiff_t OtherRank,
|
template <typename OtherValueType, std::ptrdiff_t OtherRank,
|
||||||
typename Dummy = std::enable_if_t<std::is_same<
|
typename Dummy = std::enable_if_t<std::is_same<
|
||||||
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
|
||||||
constexpr bool operator>=(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
|
constexpr bool
|
||||||
|
operator>=(const strided_span<OtherValueType, OtherRank>& other) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
return !(*this < other);
|
return !(*this < other);
|
||||||
}
|
}
|
||||||
@ -2074,15 +2110,24 @@ public:
|
|||||||
Expects(m_validator == rhs.m_validator);
|
Expects(m_validator == rhs.m_validator);
|
||||||
return data_ == rhs.data_;
|
return data_ == rhs.data_;
|
||||||
}
|
}
|
||||||
bool operator!=(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT { return !(*this == rhs); }
|
bool operator!=(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
bool operator<(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT
|
bool operator<(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
Expects(m_validator == rhs.m_validator);
|
Expects(m_validator == rhs.m_validator);
|
||||||
return data_ < rhs.data_;
|
return data_ < rhs.data_;
|
||||||
}
|
}
|
||||||
bool operator<=(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT { return !(rhs < *this); }
|
bool operator<=(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return !(rhs < *this);
|
||||||
|
}
|
||||||
bool operator>(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT { return rhs < *this; }
|
bool operator>(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT { return rhs < *this; }
|
||||||
bool operator>=(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT { return !(rhs > *this); }
|
bool operator>=(const contiguous_span_iterator& rhs) const GSL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return !(rhs > *this);
|
||||||
|
}
|
||||||
void swap(contiguous_span_iterator& rhs) GSL_NOEXCEPT
|
void swap(contiguous_span_iterator& rhs) GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
std::swap(data_, rhs.data_);
|
std::swap(data_, rhs.data_);
|
||||||
@ -2202,20 +2247,20 @@ general_span_iterator<Span> operator+(typename general_span_iterator<Span>::diff
|
|||||||
#undef GSL_NOEXCEPT
|
#undef GSL_NOEXCEPT
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#if _MSC_VER < 1910
|
#if _MSC_VER < 1910
|
||||||
#if _MSC_VER <= 1800
|
#if _MSC_VER <= 1800
|
||||||
#undef noexcept
|
#undef noexcept
|
||||||
#pragma pop_macro("noexcept")
|
#pragma pop_macro("noexcept")
|
||||||
|
|
||||||
#undef GSL_MSVC_HAS_VARIADIC_CTOR_BUG
|
#undef GSL_MSVC_HAS_VARIADIC_CTOR_BUG
|
||||||
#undef GSL_MSVC_NO_SUPPORT_FOR_MOVE_CTOR_DEFAULT
|
#undef GSL_MSVC_NO_SUPPORT_FOR_MOVE_CTOR_DEFAULT
|
||||||
#endif // _MSC_VER <= 1800
|
#endif // _MSC_VER <= 1800
|
||||||
|
|
||||||
#undef constexpr
|
#undef constexpr
|
||||||
#pragma pop_macro("constexpr")
|
#pragma pop_macro("constexpr")
|
||||||
#endif // _MSC_VER < 1910
|
#endif // _MSC_VER < 1910
|
||||||
|
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#endif // GSL_MULTI_SPAN_H
|
#endif // GSL_MULTI_SPAN_H
|
||||||
|
192
include/gsl/span
192
include/gsl/span
@ -23,53 +23,54 @@
|
|||||||
#include <gsl/gsl_assert>
|
#include <gsl/gsl_assert>
|
||||||
#include <gsl/gsl_byte>
|
#include <gsl/gsl_byte>
|
||||||
#include <gsl/gsl_util>
|
#include <gsl/gsl_util>
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
|
||||||
// turn off some warnings that are noisy about our Expects statements
|
// turn off some warnings that are noisy about our Expects statements
|
||||||
#pragma warning(disable : 4127) // conditional expression is constant
|
#pragma warning(disable : 4127) // conditional expression is constant
|
||||||
|
|
||||||
// blanket turn off warnings from CppCoreCheck for now
|
// blanket turn off warnings from CppCoreCheck for now
|
||||||
// so people aren't annoyed by them when running the tool.
|
// so people aren't annoyed by them when running the tool.
|
||||||
// more targeted suppressions will be added in a future update to the GSL
|
// more targeted suppressions will be added in a future update to the GSL
|
||||||
#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
|
#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
|
||||||
|
|
||||||
#if _MSC_VER < 1910
|
#if _MSC_VER < 1910
|
||||||
#pragma push_macro("constexpr")
|
#pragma push_macro("constexpr")
|
||||||
#define constexpr /*constexpr*/
|
#define constexpr /*constexpr*/
|
||||||
|
|
||||||
// VS 2013 workarounds
|
// VS 2013 workarounds
|
||||||
#if _MSC_VER <= 1800
|
#if _MSC_VER <= 1800
|
||||||
#define GSL_MSVC_HAS_VARIADIC_CTOR_BUG
|
#define GSL_MSVC_HAS_VARIADIC_CTOR_BUG
|
||||||
#define GSL_MSVC_NO_DEFAULT_MOVE_CTOR
|
#define GSL_MSVC_NO_DEFAULT_MOVE_CTOR
|
||||||
#define GSL_MSVC_NO_CPP14_STD_EQUAL
|
#define GSL_MSVC_NO_CPP14_STD_EQUAL
|
||||||
|
|
||||||
// noexcept is not understood
|
// noexcept is not understood
|
||||||
#pragma push_macro("noexcept")
|
#pragma push_macro("noexcept")
|
||||||
#define noexcept /*noexcept*/
|
#define noexcept /*noexcept*/
|
||||||
|
|
||||||
#pragma push_macro("alignof")
|
#pragma push_macro("alignof")
|
||||||
#define alignof __alignof
|
#define alignof __alignof
|
||||||
|
|
||||||
// turn off some misguided warnings
|
// turn off some misguided warnings
|
||||||
#pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
|
#pragma warning(disable : 4351) // warns about newly introduced aggregate initializer behavior
|
||||||
#pragma warning(disable : 4512) // warns that assignment op could not be generated
|
#pragma warning(disable : 4512) // warns that assignment op could not be generated
|
||||||
#endif // _MSC_VER <= 1800
|
#endif // _MSC_VER <= 1800
|
||||||
#endif // _MSC_VER < 1910
|
#endif // _MSC_VER < 1910
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#ifdef GSL_THROW_ON_CONTRACT_VIOLATION
|
#ifdef GSL_THROW_ON_CONTRACT_VIOLATION
|
||||||
#define GSL_NOEXCEPT /*noexcept*/
|
#define GSL_NOEXCEPT /*noexcept*/
|
||||||
#else
|
#else
|
||||||
#define GSL_NOEXCEPT noexcept
|
#define GSL_NOEXCEPT noexcept
|
||||||
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
|
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
|
||||||
|
|
||||||
namespace gsl
|
namespace gsl
|
||||||
@ -131,13 +132,13 @@ namespace details
|
|||||||
class span_iterator
|
class span_iterator
|
||||||
{
|
{
|
||||||
using element_type_ = typename Span::element_type;
|
using element_type_ = typename Span::element_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using iterator_category = std::random_access_iterator_tag;
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
using value_type = std::remove_cv_t<element_type_>;
|
using value_type = std::remove_cv_t<element_type_>;
|
||||||
using difference_type = typename Span::index_type;
|
using difference_type = typename Span::index_type;
|
||||||
|
|
||||||
using reference =
|
using reference = std::conditional_t<IsConst, const element_type_, element_type_>&;
|
||||||
std::conditional_t<IsConst, const element_type_, element_type_> &;
|
|
||||||
using pointer = std::add_pointer_t<reference>;
|
using pointer = std::add_pointer_t<reference>;
|
||||||
|
|
||||||
constexpr span_iterator() GSL_NOEXCEPT : span_iterator(nullptr, 0) {}
|
constexpr span_iterator() GSL_NOEXCEPT : span_iterator(nullptr, 0) {}
|
||||||
@ -154,7 +155,8 @@ namespace details
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr span_iterator<Span, IsConst>& operator=(const span_iterator<Span, IsConst>&) GSL_NOEXCEPT = default;
|
constexpr span_iterator<Span, IsConst>&
|
||||||
|
operator=(const span_iterator<Span, IsConst>&) GSL_NOEXCEPT = default;
|
||||||
|
|
||||||
constexpr reference operator*() const
|
constexpr reference operator*() const
|
||||||
{
|
{
|
||||||
@ -223,7 +225,10 @@ namespace details
|
|||||||
return index_ - rhs.index_;
|
return index_ - rhs.index_;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr reference operator[](difference_type n) const GSL_NOEXCEPT { return *(*this + n); }
|
constexpr reference operator[](difference_type n) const GSL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return *(*this + n);
|
||||||
|
}
|
||||||
|
|
||||||
constexpr friend bool operator==(const span_iterator& lhs,
|
constexpr friend bool operator==(const span_iterator& lhs,
|
||||||
const span_iterator& rhs) GSL_NOEXCEPT
|
const span_iterator& rhs) GSL_NOEXCEPT
|
||||||
@ -249,7 +254,8 @@ namespace details
|
|||||||
return !(rhs < lhs);
|
return !(rhs < lhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr friend bool operator>(const span_iterator& lhs, const span_iterator& rhs) GSL_NOEXCEPT
|
constexpr friend bool operator>(const span_iterator& lhs,
|
||||||
|
const span_iterator& rhs) GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
return rhs < lhs;
|
return rhs < lhs;
|
||||||
}
|
}
|
||||||
@ -356,7 +362,9 @@ public:
|
|||||||
// "Dependent" is needed to make "std::enable_if_t<Dependent || Extent <= 0>" SFINAE,
|
// "Dependent" is needed to make "std::enable_if_t<Dependent || Extent <= 0>" SFINAE,
|
||||||
// since "std::enable_if_t<Extent <= 0>" is ill-formed when Extent is greater than 0.
|
// since "std::enable_if_t<Extent <= 0>" is ill-formed when Extent is greater than 0.
|
||||||
class = std::enable_if_t<(Dependent || Extent <= 0)>>
|
class = std::enable_if_t<(Dependent || Extent <= 0)>>
|
||||||
constexpr span() GSL_NOEXCEPT : storage_(nullptr, details::extent_type<0>()) {}
|
constexpr span() GSL_NOEXCEPT : storage_(nullptr, details::extent_type<0>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
constexpr span(std::nullptr_t) GSL_NOEXCEPT : span() {}
|
constexpr span(std::nullptr_t) GSL_NOEXCEPT : span() {}
|
||||||
|
|
||||||
@ -368,7 +376,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
constexpr span(element_type (&arr)[N]) GSL_NOEXCEPT : storage_(&arr[0], details::extent_type<N>())
|
constexpr span(element_type (&arr)[N]) GSL_NOEXCEPT
|
||||||
|
: storage_(&arr[0], details::extent_type<N>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,11 +393,18 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class ArrayElementType = std::add_pointer<element_type>>
|
template <class ArrayElementType = std::add_pointer<element_type>>
|
||||||
constexpr span(const std::unique_ptr<ArrayElementType>& ptr, index_type count) : storage_(ptr.get(), count) {}
|
constexpr span(const std::unique_ptr<ArrayElementType>& ptr, index_type count)
|
||||||
|
: storage_(ptr.get(), count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
constexpr span(const std::unique_ptr<ElementType>& ptr) : storage_(ptr.get(), ptr.get() ? 1 : 0) {}
|
constexpr span(const std::unique_ptr<ElementType>& ptr) : storage_(ptr.get(), ptr.get() ? 1 : 0)
|
||||||
constexpr span(const std::shared_ptr<ElementType>& ptr) : storage_(ptr.get(), ptr.get() ? 1 : 0) {}
|
{
|
||||||
|
}
|
||||||
|
constexpr span(const std::shared_ptr<ElementType>& ptr) : storage_(ptr.get(), ptr.get() ? 1 : 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// NB: the SFINAE here uses .data() as a incomplete/imperfect proxy for the requirement
|
// NB: the SFINAE here uses .data() as a incomplete/imperfect proxy for the requirement
|
||||||
// on Container to be a contiguous sequence container.
|
// on Container to be a contiguous sequence container.
|
||||||
@ -498,7 +514,10 @@ public:
|
|||||||
constexpr index_type length() const GSL_NOEXCEPT { return size(); }
|
constexpr index_type length() const GSL_NOEXCEPT { return size(); }
|
||||||
constexpr index_type size() const GSL_NOEXCEPT { return storage_.size(); }
|
constexpr index_type size() const GSL_NOEXCEPT { return storage_.size(); }
|
||||||
constexpr index_type length_bytes() const GSL_NOEXCEPT { return size_bytes(); }
|
constexpr index_type length_bytes() const GSL_NOEXCEPT { return size_bytes(); }
|
||||||
constexpr index_type size_bytes() const GSL_NOEXCEPT { return size() * narrow_cast<index_type>(sizeof(element_type)); }
|
constexpr index_type size_bytes() const GSL_NOEXCEPT
|
||||||
|
{
|
||||||
|
return size() * narrow_cast<index_type>(sizeof(element_type));
|
||||||
|
}
|
||||||
constexpr bool empty() const GSL_NOEXCEPT { return size() == 0; }
|
constexpr bool empty() const GSL_NOEXCEPT { return size() == 0; }
|
||||||
|
|
||||||
// [span.elem], span element access
|
// [span.elem], span element access
|
||||||
@ -561,31 +580,36 @@ inline constexpr bool operator==(const span<ElementType, FirstExtent>& l,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class ElementType, std::ptrdiff_t Extent>
|
template <class ElementType, std::ptrdiff_t Extent>
|
||||||
inline constexpr bool operator!=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r)
|
inline constexpr bool operator!=(const span<ElementType, Extent>& l,
|
||||||
|
const span<ElementType, Extent>& r)
|
||||||
{
|
{
|
||||||
return !(l == r);
|
return !(l == r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ElementType, std::ptrdiff_t Extent>
|
template <class ElementType, std::ptrdiff_t Extent>
|
||||||
inline constexpr bool operator<(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r)
|
inline constexpr bool operator<(const span<ElementType, Extent>& l,
|
||||||
|
const span<ElementType, Extent>& r)
|
||||||
{
|
{
|
||||||
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
|
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ElementType, std::ptrdiff_t Extent>
|
template <class ElementType, std::ptrdiff_t Extent>
|
||||||
inline constexpr bool operator<=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r)
|
inline constexpr bool operator<=(const span<ElementType, Extent>& l,
|
||||||
|
const span<ElementType, Extent>& r)
|
||||||
{
|
{
|
||||||
return !(l > r);
|
return !(l > r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ElementType, std::ptrdiff_t Extent>
|
template <class ElementType, std::ptrdiff_t Extent>
|
||||||
inline constexpr bool operator>(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r)
|
inline constexpr bool operator>(const span<ElementType, Extent>& l,
|
||||||
|
const span<ElementType, Extent>& r)
|
||||||
{
|
{
|
||||||
return r < l;
|
return r < l;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ElementType, std::ptrdiff_t Extent>
|
template <class ElementType, std::ptrdiff_t Extent>
|
||||||
inline constexpr bool operator>=(const span<ElementType, Extent>& l, const span<ElementType, Extent>& r)
|
inline constexpr bool operator>=(const span<ElementType, Extent>& l,
|
||||||
|
const span<ElementType, Extent>& r)
|
||||||
{
|
{
|
||||||
return !(l < r);
|
return !(l < r);
|
||||||
}
|
}
|
||||||
@ -633,40 +657,46 @@ as_writeable_bytes(span<ElementType, Extent> s) GSL_NOEXCEPT
|
|||||||
// make_span() - Utility functions for creating spans
|
// make_span() - Utility functions for creating spans
|
||||||
//
|
//
|
||||||
template <class ElementType>
|
template <class ElementType>
|
||||||
span<ElementType>
|
span<ElementType> make_span(ElementType* ptr, typename span<ElementType>::index_type count)
|
||||||
make_span(ElementType* ptr, typename span<ElementType>::index_type count)
|
{
|
||||||
{ return span<ElementType>(ptr, count); }
|
return span<ElementType>(ptr, count);
|
||||||
|
}
|
||||||
|
|
||||||
template <class ElementType>
|
template <class ElementType>
|
||||||
span<ElementType>
|
span<ElementType> make_span(ElementType* firstElem, ElementType* lastElem)
|
||||||
make_span(ElementType* firstElem, ElementType* lastElem)
|
{
|
||||||
{ return span<ElementType>(firstElem, lastElem); }
|
return span<ElementType>(firstElem, lastElem);
|
||||||
|
}
|
||||||
|
|
||||||
template <class ElementType, std::size_t N>
|
template <class ElementType, std::size_t N>
|
||||||
span<ElementType>
|
span<ElementType, N> make_span(ElementType (&arr)[N])
|
||||||
make_span(ElementType (&arr)[N])
|
{
|
||||||
{ return span<ElementType>(arr); }
|
return span<ElementType, N>(arr);
|
||||||
|
}
|
||||||
|
|
||||||
template <class Container>
|
template <class Container>
|
||||||
span<typename Container::value_type>
|
span<typename Container::value_type> make_span(Container& cont)
|
||||||
make_span(Container &cont)
|
{
|
||||||
{ return span<typename Container::value_type>(cont); }
|
return span<typename Container::value_type>(cont);
|
||||||
|
}
|
||||||
|
|
||||||
template <class Container>
|
template <class Container>
|
||||||
span<const typename Container::value_type>
|
span<const typename Container::value_type> make_span(const Container& cont)
|
||||||
make_span(const Container &cont)
|
{
|
||||||
{ return span<const typename Container::value_type>(cont); }
|
return span<const typename Container::value_type>(cont);
|
||||||
|
}
|
||||||
|
|
||||||
template <class Ptr>
|
template <class Ptr>
|
||||||
span<typename Ptr::element_type>
|
span<typename Ptr::element_type> make_span(Ptr& cont, std::ptrdiff_t count)
|
||||||
make_span(Ptr& cont, std::ptrdiff_t count)
|
{
|
||||||
{ return span<typename Ptr::element_type>(cont, count); }
|
return span<typename Ptr::element_type>(cont, count);
|
||||||
|
}
|
||||||
|
|
||||||
template <class Ptr>
|
template <class Ptr>
|
||||||
span<typename Ptr::element_type>
|
span<typename Ptr::element_type> make_span(Ptr& cont)
|
||||||
make_span(Ptr& cont)
|
{
|
||||||
{ return span<typename Ptr::element_type>(cont); }
|
return span<typename Ptr::element_type>(cont);
|
||||||
|
}
|
||||||
|
|
||||||
// Specialization of gsl::at for span
|
// Specialization of gsl::at for span
|
||||||
template <class ElementType, std::ptrdiff_t Extent>
|
template <class ElementType, std::ptrdiff_t Extent>
|
||||||
@ -681,24 +711,24 @@ inline constexpr ElementType& at(const span<ElementType, Extent>& s, std::ptrdif
|
|||||||
#undef GSL_NOEXCEPT
|
#undef GSL_NOEXCEPT
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#if _MSC_VER < 1910
|
#if _MSC_VER < 1910
|
||||||
#undef constexpr
|
#undef constexpr
|
||||||
#pragma pop_macro("constexpr")
|
#pragma pop_macro("constexpr")
|
||||||
|
|
||||||
#if _MSC_VER <= 1800
|
#if _MSC_VER <= 1800
|
||||||
#undef noexcept
|
#undef noexcept
|
||||||
#pragma pop_macro("noexcept")
|
#pragma pop_macro("noexcept")
|
||||||
|
|
||||||
#undef alignof
|
#undef alignof
|
||||||
#pragma pop_macro("alignof")
|
#pragma pop_macro("alignof")
|
||||||
|
|
||||||
#undef GSL_MSVC_HAS_VARIADIC_CTOR_BUG
|
#undef GSL_MSVC_HAS_VARIADIC_CTOR_BUG
|
||||||
#undef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
|
#undef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
|
||||||
#undef GSL_MSVC_NO_CPP14_STD_EQUAL
|
#undef GSL_MSVC_NO_CPP14_STD_EQUAL
|
||||||
#endif // _MSC_VER <= 1800
|
#endif // _MSC_VER <= 1800
|
||||||
#endif // _MSC_VER < 1910
|
#endif // _MSC_VER < 1910
|
||||||
|
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#endif // GSL_SPAN_H
|
#endif // GSL_SPAN_H
|
||||||
|
@ -22,41 +22,42 @@
|
|||||||
#include <gsl/gsl_assert>
|
#include <gsl/gsl_assert>
|
||||||
#include <gsl/gsl_util>
|
#include <gsl/gsl_util>
|
||||||
#include <gsl/span>
|
#include <gsl/span>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
|
||||||
// blanket turn off warnings from CppCoreCheck for now
|
// blanket turn off warnings from CppCoreCheck for now
|
||||||
// so people aren't annoyed by them when running the tool.
|
// so people aren't annoyed by them when running the tool.
|
||||||
// more targeted suppressions will be added in a future update to the GSL
|
// more targeted suppressions will be added in a future update to the GSL
|
||||||
#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
|
#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
|
||||||
|
|
||||||
#if _MSC_VER < 1910
|
#if _MSC_VER < 1910
|
||||||
#pragma push_macro("constexpr")
|
#pragma push_macro("constexpr")
|
||||||
#define constexpr /*constexpr*/
|
#define constexpr /*constexpr*/
|
||||||
|
|
||||||
// VS 2013 workarounds
|
// VS 2013 workarounds
|
||||||
#if _MSC_VER <= 1800
|
#if _MSC_VER <= 1800
|
||||||
#define GSL_MSVC_HAS_TYPE_DEDUCTION_BUG
|
#define GSL_MSVC_HAS_TYPE_DEDUCTION_BUG
|
||||||
#define GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE
|
#define GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE
|
||||||
#define GSL_MSVC_NO_CPP14_STD_EQUAL
|
#define GSL_MSVC_NO_CPP14_STD_EQUAL
|
||||||
#define GSL_MSVC_NO_DEFAULT_MOVE_CTOR
|
#define GSL_MSVC_NO_DEFAULT_MOVE_CTOR
|
||||||
|
|
||||||
// noexcept is not understood
|
// noexcept is not understood
|
||||||
#pragma push_macro("noexcept")
|
#pragma push_macro("noexcept")
|
||||||
#define noexcept /*noexcept*/
|
#define noexcept /*noexcept*/
|
||||||
#endif // _MSC_VER <= 1800
|
#endif // _MSC_VER <= 1800
|
||||||
#endif // _MSC_VER < 1910
|
#endif // _MSC_VER < 1910
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
// In order to test the library, we need it to throw exceptions that we can catch
|
// In order to test the library, we need it to throw exceptions that we can catch
|
||||||
#ifdef GSL_THROW_ON_CONTRACT_VIOLATION
|
#ifdef GSL_THROW_ON_CONTRACT_VIOLATION
|
||||||
#define GSL_NOEXCEPT /*noexcept*/
|
#define GSL_NOEXCEPT /*noexcept*/
|
||||||
#else
|
#else
|
||||||
#define GSL_NOEXCEPT noexcept
|
#define GSL_NOEXCEPT noexcept
|
||||||
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
|
#endif // GSL_THROW_ON_CONTRACT_VIOLATION
|
||||||
|
|
||||||
namespace gsl
|
namespace gsl
|
||||||
@ -89,30 +90,26 @@ using wzstring = basic_zstring<wchar_t, Extent>;
|
|||||||
|
|
||||||
namespace details
|
namespace details
|
||||||
{
|
{
|
||||||
inline std::ptrdiff_t string_length(const char *str, std::ptrdiff_t n)
|
inline std::ptrdiff_t string_length(const char* str, std::ptrdiff_t n)
|
||||||
{
|
{
|
||||||
if (str == nullptr || n <= 0)
|
if (str == nullptr || n <= 0) return 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
span<const char> str_span{str, n};
|
span<const char> str_span{str, n};
|
||||||
|
|
||||||
std::ptrdiff_t len = 0;
|
std::ptrdiff_t len = 0;
|
||||||
while (len < n && str_span[len])
|
while (len < n && str_span[len]) len++;
|
||||||
len++;
|
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::ptrdiff_t wstring_length(const wchar_t *str, std::ptrdiff_t n)
|
inline std::ptrdiff_t wstring_length(const wchar_t* str, std::ptrdiff_t n)
|
||||||
{
|
{
|
||||||
if (str == nullptr || n <= 0)
|
if (str == nullptr || n <= 0) return 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
span<const wchar_t> str_span{str, n};
|
span<const wchar_t> str_span{str, n};
|
||||||
|
|
||||||
std::ptrdiff_t len = 0;
|
std::ptrdiff_t len = 0;
|
||||||
while (len < n && str_span[len])
|
while (len < n && str_span[len]) len++;
|
||||||
len++;
|
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@ -316,7 +313,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
|
template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>>
|
||||||
constexpr basic_string_span(const std::array<ArrayElementType, N>& arr) GSL_NOEXCEPT : span_(arr)
|
constexpr basic_string_span(const std::array<ArrayElementType, N>& arr) GSL_NOEXCEPT
|
||||||
|
: span_(arr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,11 +482,8 @@ inline std::wstring to_string(wstring_span<> view)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename CharT,
|
template <typename CharT, typename Traits = typename std::char_traits<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::ptrdiff_t Extent>
|
|
||||||
std::basic_string<CharT, Traits, Allocator> to_basic_string(basic_string_span<gCharT, Extent> view)
|
std::basic_string<CharT, Traits, Allocator> to_basic_string(basic_string_span<gCharT, Extent> view)
|
||||||
{
|
{
|
||||||
return {view.data(), static_cast<std::size_t>(view.length())};
|
return {view.data(), static_cast<std::size_t>(view.length())};
|
||||||
@ -830,23 +825,23 @@ bool operator>=(const T& one, gsl::basic_string_span<CharT, Extent> other) GSL_N
|
|||||||
#undef GSL_NOEXCEPT
|
#undef GSL_NOEXCEPT
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
|
||||||
#if _MSC_VER < 1910
|
#if _MSC_VER < 1910
|
||||||
#undef constexpr
|
#undef constexpr
|
||||||
#pragma pop_macro("constexpr")
|
#pragma pop_macro("constexpr")
|
||||||
|
|
||||||
// VS 2013 workarounds
|
// VS 2013 workarounds
|
||||||
#if _MSC_VER <= 1800
|
#if _MSC_VER <= 1800
|
||||||
#undef noexcept
|
#undef noexcept
|
||||||
#pragma pop_macro("noexcept")
|
#pragma pop_macro("noexcept")
|
||||||
|
|
||||||
#undef GSL_MSVC_HAS_TYPE_DEDUCTION_BUG
|
#undef GSL_MSVC_HAS_TYPE_DEDUCTION_BUG
|
||||||
#undef GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE
|
#undef GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE
|
||||||
#undef GSL_MSVC_NO_CPP14_STD_EQUAL
|
#undef GSL_MSVC_NO_CPP14_STD_EQUAL
|
||||||
#undef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
|
#undef GSL_MSVC_NO_DEFAULT_MOVE_CTOR
|
||||||
#endif // _MSC_VER <= 1800
|
#endif // _MSC_VER <= 1800
|
||||||
#endif // _MSC_VER < 1910
|
#endif // _MSC_VER < 1910
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#endif // GSL_STRING_SPAN_H
|
#endif // GSL_STRING_SPAN_H
|
||||||
|
@ -2,43 +2,70 @@ cmake_minimum_required(VERSION 2.8.7)
|
|||||||
|
|
||||||
project(GSLTests CXX)
|
project(GSLTests CXX)
|
||||||
|
|
||||||
if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/unittest-cpp/tests)
|
# will make visual studio generated project group files
|
||||||
execute_process(COMMAND git submodule update --init WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
||||||
|
if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/unittest-cpp/CMakeLists.txt)
|
||||||
|
find_package(Git)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GIT_EXECUTABLE} submodule update --init
|
||||||
|
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(unittest-cpp)
|
add_subdirectory(unittest-cpp)
|
||||||
|
|
||||||
include_directories(
|
# this interface adds compile options to how the tests are run
|
||||||
../include
|
# please try to keep entries ordered =)
|
||||||
|
add_library(gsl_tests_config INTERFACE)
|
||||||
|
target_compile_options(gsl_tests_config INTERFACE
|
||||||
|
$<$<CXX_COMPILER_ID:MSVC>:
|
||||||
|
/EHsc
|
||||||
|
/W4
|
||||||
|
/WX
|
||||||
|
>
|
||||||
|
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:
|
||||||
|
-fno-strict-aliasing
|
||||||
|
-Wall
|
||||||
|
-Wcast-align
|
||||||
|
-Wconversion
|
||||||
|
-Wctor-dtor-privacy
|
||||||
|
-Werror
|
||||||
|
-Wextra
|
||||||
|
-Wno-missing-braces
|
||||||
|
-Wnon-virtual-dtor
|
||||||
|
-Wold-style-cast
|
||||||
|
-Woverloaded-virtual
|
||||||
|
-Wpedantic
|
||||||
|
-Wshadow
|
||||||
|
-Wsign-conversion
|
||||||
|
>
|
||||||
|
)
|
||||||
|
|
||||||
|
# set test to include the unittest-cpp headers
|
||||||
|
# this shiuld be removed when UnitTest++ has the proper headers
|
||||||
|
target_include_directories(gsl_tests_config INTERFACE
|
||||||
./unittest-cpp
|
./unittest-cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_definitions(-DGSL_THROW_ON_CONTRACT_VIOLATION)
|
# set definitions for tests
|
||||||
|
target_compile_definitions(gsl_tests_config INTERFACE
|
||||||
if(MSVC) # has the support we need
|
GSL_THROW_ON_CONTRACT_VIOLATION
|
||||||
# remove unnecessary warnings about unchecked iterators
|
)
|
||||||
add_definitions(-D_SCL_SECURE_NO_WARNINGS)
|
|
||||||
add_compile_options(/EHsc /W4 /WX)
|
|
||||||
else()
|
|
||||||
include(CheckCXXCompilerFlag)
|
|
||||||
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
|
|
||||||
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
|
|
||||||
if(COMPILER_SUPPORTS_CXX14)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -fno-strict-aliasing -std=c++14 -Wall -Wextra -Wpedantic -Wno-missing-braces -Wconversion -Wsign-conversion -Wctor-dtor-privacy -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Woverloaded-virtual")
|
|
||||||
elseif(COMPILER_SUPPORTS_CXX11)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -fno-strict-aliasing -std=c++11 -Wall -Wextra -Wpedantic -Wno-missing-braces -Wconversion -Wsign-conversion -Wctor-dtor-privacy -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Woverloaded-virtual")
|
|
||||||
else()
|
|
||||||
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
function(add_gsl_test name)
|
function(add_gsl_test name)
|
||||||
add_executable(${name} ${name}.cpp)
|
add_executable(${name} ${name}.cpp)
|
||||||
target_link_libraries(${name} UnitTest++)
|
target_link_libraries(${name}
|
||||||
|
UnitTest++
|
||||||
|
GSL
|
||||||
|
gsl_tests_config
|
||||||
|
)
|
||||||
add_test(
|
add_test(
|
||||||
${name}
|
${name}
|
||||||
${name}
|
${name}
|
||||||
)
|
)
|
||||||
|
# group all tests under GSL_tests
|
||||||
|
set_property(TARGET ${name} PROPERTY FOLDER "GSL_tests")
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
add_gsl_test(span_tests)
|
add_gsl_test(span_tests)
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <UnitTest++/UnitTest++.h>
|
#include <UnitTest++/UnitTest++.h>
|
||||||
|
|
||||||
#include <gsl/gsl_algorithm>
|
#include <gsl/gsl_algorithm>
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <UnitTest++/UnitTest++.h>
|
#include <UnitTest++/UnitTest++.h>
|
||||||
|
|
||||||
#include <gsl/gsl>
|
#include <gsl/gsl>
|
||||||
|
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
@ -47,7 +48,4 @@ SUITE(assertion_tests)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int, const char *[])
|
int main(int, const char* []) { return UnitTest::RunAllTests(); }
|
||||||
{
|
|
||||||
return UnitTest::RunAllTests();
|
|
||||||
}
|
|
||||||
|
@ -15,9 +15,11 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <UnitTest++/UnitTest++.h>
|
#include <UnitTest++/UnitTest++.h>
|
||||||
|
|
||||||
#include <gsl/gsl>
|
#include <gsl/gsl>
|
||||||
#include <vector>
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
using gsl::fail_fast;
|
using gsl::fail_fast;
|
||||||
|
|
||||||
@ -25,8 +27,8 @@ SUITE(at_tests)
|
|||||||
{
|
{
|
||||||
TEST(static_array)
|
TEST(static_array)
|
||||||
{
|
{
|
||||||
int a[4] = { 1, 2, 3, 4 };
|
int a[4] = {1, 2, 3, 4};
|
||||||
const int (&c_a)[4] = a;
|
const int(&c_a)[4] = a;
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
CHECK(&gsl::at(a, i) == &a[i]);
|
CHECK(&gsl::at(a, i) == &a[i]);
|
||||||
@ -41,7 +43,7 @@ SUITE(at_tests)
|
|||||||
|
|
||||||
TEST(std_array)
|
TEST(std_array)
|
||||||
{
|
{
|
||||||
std::array<int, 4> a = { 1, 2, 3, 4 };
|
std::array<int, 4> a = {1, 2, 3, 4};
|
||||||
const std::array<int, 4>& c_a = a;
|
const std::array<int, 4>& c_a = a;
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
@ -57,7 +59,7 @@ SUITE(at_tests)
|
|||||||
|
|
||||||
TEST(StdVector)
|
TEST(StdVector)
|
||||||
{
|
{
|
||||||
std::vector<int> a = { 1, 2, 3, 4 };
|
std::vector<int> a = {1, 2, 3, 4};
|
||||||
const std::vector<int>& c_a = a;
|
const std::vector<int>& c_a = a;
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
@ -73,26 +75,26 @@ SUITE(at_tests)
|
|||||||
|
|
||||||
TEST(InitializerList)
|
TEST(InitializerList)
|
||||||
{
|
{
|
||||||
std::initializer_list<int> a = { 1, 2, 3, 4 };
|
std::initializer_list<int> a = {1, 2, 3, 4};
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
CHECK(gsl::at(a, i) == i+1);
|
CHECK(gsl::at(a, i) == i + 1);
|
||||||
CHECK(gsl::at({1,2,3,4}, i) == i+1);
|
CHECK(gsl::at({1, 2, 3, 4}, i) == i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_THROW(gsl::at(a, -1), fail_fast);
|
CHECK_THROW(gsl::at(a, -1), fail_fast);
|
||||||
CHECK_THROW(gsl::at(a, 4), fail_fast);
|
CHECK_THROW(gsl::at(a, 4), fail_fast);
|
||||||
CHECK_THROW(gsl::at({1,2,3,4}, -1), fail_fast);
|
CHECK_THROW(gsl::at({1, 2, 3, 4}, -1), fail_fast);
|
||||||
CHECK_THROW(gsl::at({1,2,3,4}, 4), fail_fast);
|
CHECK_THROW(gsl::at({1, 2, 3, 4}, 4), fail_fast);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || defined(__clang__) || _MSC_VER >= 1910
|
#if !defined(_MSC_VER) || defined(__clang__) || _MSC_VER >= 1910
|
||||||
static constexpr bool test_constexpr()
|
static constexpr bool test_constexpr()
|
||||||
{
|
{
|
||||||
int a1[4] = { 1, 2, 3, 4 };
|
int a1[4] = {1, 2, 3, 4};
|
||||||
const int (&c_a1)[4] = a1;
|
const int(&c_a1)[4] = a1;
|
||||||
std::array<int,4> a2 = { 1, 2, 3, 4 };
|
std::array<int, 4> a2 = {1, 2, 3, 4};
|
||||||
const std::array<int, 4>& c_a2 = a2;
|
const std::array<int, 4>& c_a2 = a2;
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
@ -101,7 +103,7 @@ static constexpr bool test_constexpr()
|
|||||||
// requires C++17:
|
// requires C++17:
|
||||||
// if (&gsl::at(a2, i) != &a2[static_cast<std::size_t>(i)]) return false;
|
// if (&gsl::at(a2, i) != &a2[static_cast<std::size_t>(i)]) return false;
|
||||||
if (&gsl::at(c_a2, i) != &c_a2[static_cast<std::size_t>(i)]) return false;
|
if (&gsl::at(c_a2, i) != &c_a2[static_cast<std::size_t>(i)]) return false;
|
||||||
if (gsl::at({1,2,3,4}, i) != i+1) return false;
|
if (gsl::at({1, 2, 3, 4}, i) != i + 1) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -110,7 +112,4 @@ static constexpr bool test_constexpr()
|
|||||||
static_assert(test_constexpr(), "FAIL");
|
static_assert(test_constexpr(), "FAIL");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main()
|
int main() { return UnitTest::RunAllTests(); }
|
||||||
{
|
|
||||||
return UnitTest::RunAllTests();
|
|
||||||
}
|
|
||||||
|
@ -15,7 +15,9 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <UnitTest++/UnitTest++.h>
|
#include <UnitTest++/UnitTest++.h>
|
||||||
|
|
||||||
#include <gsl/multi_span>
|
#include <gsl/multi_span>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -23,18 +25,16 @@ using namespace gsl;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
void use(std::ptrdiff_t&) {}
|
void use(std::ptrdiff_t&) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
SUITE(bounds_test)
|
SUITE(bounds_test)
|
||||||
{
|
{
|
||||||
TEST(basic_bounds)
|
TEST(basic_bounds)
|
||||||
{
|
{
|
||||||
for (auto point : static_bounds<dynamic_range, 3, 4 > { 2 })
|
for (auto point : static_bounds<dynamic_range, 3, 4>{2}) {
|
||||||
{
|
|
||||||
for (decltype(point)::size_type j = 0;
|
for (decltype(point)::size_type j = 0;
|
||||||
j < static_cast<decltype(point)::size_type>(decltype(point)::rank);
|
j < static_cast<decltype(point)::size_type>(decltype(point)::rank); j++)
|
||||||
j++)
|
|
||||||
{
|
{
|
||||||
use(j);
|
use(j);
|
||||||
use(point[static_cast<std::size_t>(j)]);
|
use(point[static_cast<std::size_t>(j)]);
|
||||||
@ -46,17 +46,17 @@ SUITE(bounds_test)
|
|||||||
{
|
{
|
||||||
static_bounds<3, 4, 5> b;
|
static_bounds<3, 4, 5> b;
|
||||||
const auto a = b.slice();
|
const auto a = b.slice();
|
||||||
(void)a;
|
(void) a;
|
||||||
static_bounds<4, dynamic_range, 2> x{ 4 };
|
static_bounds<4, dynamic_range, 2> x{4};
|
||||||
x.slice().slice();
|
x.slice().slice();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST (arrayview_iterator)
|
TEST(arrayview_iterator)
|
||||||
{
|
{
|
||||||
static_bounds<4, dynamic_range, 2> bounds{ 3 };
|
static_bounds<4, dynamic_range, 2> bounds{3};
|
||||||
|
|
||||||
const auto itr = bounds.begin();
|
const auto itr = bounds.begin();
|
||||||
(void)itr;
|
(void) itr;
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
multi_span<int, 4, dynamic_range, 2> av(nullptr, bounds);
|
multi_span<int, 4, dynamic_range, 2> av(nullptr, bounds);
|
||||||
|
|
||||||
@ -69,18 +69,18 @@ SUITE(bounds_test)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST (bounds_convertible)
|
TEST(bounds_convertible)
|
||||||
{
|
{
|
||||||
static_bounds<7, 4, 2> b1;
|
static_bounds<7, 4, 2> b1;
|
||||||
static_bounds<7, dynamic_range, 2> b2 = b1;
|
static_bounds<7, dynamic_range, 2> b2 = b1;
|
||||||
(void)b2;
|
(void) b2;
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
static_bounds<7, dynamic_range, 1> b4 = b2;
|
static_bounds<7, dynamic_range, 1> b4 = b2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static_bounds<dynamic_range, dynamic_range, dynamic_range> b3 = b1;
|
static_bounds<dynamic_range, dynamic_range, dynamic_range> b3 = b1;
|
||||||
static_bounds<7, 4, 2> b4 = b3;
|
static_bounds<7, 4, 2> b4 = b3;
|
||||||
(void)b4;
|
(void) b4;
|
||||||
|
|
||||||
static_bounds<dynamic_range> b11;
|
static_bounds<dynamic_range> b11;
|
||||||
|
|
||||||
@ -97,7 +97,4 @@ SUITE(bounds_test)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int, const char *[])
|
int main(int, const char* []) { return UnitTest::RunAllTests(); }
|
||||||
{
|
|
||||||
return UnitTest::RunAllTests();
|
|
||||||
}
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <UnitTest++/UnitTest++.h>
|
#include <UnitTest++/UnitTest++.h>
|
||||||
|
|
||||||
#include <gsl/gsl_byte>
|
#include <gsl/gsl_byte>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -111,11 +112,11 @@ SUITE(byte_tests)
|
|||||||
CHECK(0x12 == gsl::to_integer<unsigned long>(b));
|
CHECK(0x12 == gsl::to_integer<unsigned long>(b));
|
||||||
CHECK(0x12 == gsl::to_integer<unsigned long long>(b));
|
CHECK(0x12 == gsl::to_integer<unsigned long long>(b));
|
||||||
|
|
||||||
// CHECK(0x12 == gsl::to_integer<float>(b)); // expect compile-time error
|
// CHECK(0x12 == gsl::to_integer<float>(b)); // expect compile-time error
|
||||||
// CHECK(0x12 == gsl::to_integer<double>(b)); // expect compile-time error
|
// CHECK(0x12 == gsl::to_integer<double>(b)); // expect compile-time error
|
||||||
}
|
}
|
||||||
|
|
||||||
int modify_both(gsl::byte& b, int& i)
|
int modify_both(gsl::byte & b, int& i)
|
||||||
{
|
{
|
||||||
i = 10;
|
i = 10;
|
||||||
b = to_byte<5>();
|
b = to_byte<5>();
|
||||||
@ -124,12 +125,11 @@ SUITE(byte_tests)
|
|||||||
|
|
||||||
TEST(aliasing)
|
TEST(aliasing)
|
||||||
{
|
{
|
||||||
int i{ 0 };
|
int i{0};
|
||||||
const int res = modify_both(reinterpret_cast<byte&>(i), i);
|
const int res = modify_both(reinterpret_cast<byte&>(i), i);
|
||||||
CHECK(res == i);
|
CHECK(res == i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int, const char* []) { return UnitTest::RunAllTests(); }
|
int main(int, const char* []) { return UnitTest::RunAllTests(); }
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <UnitTest++/UnitTest++.h>
|
#include <UnitTest++/UnitTest++.h>
|
||||||
|
|
||||||
#include <gsl/multi_span>
|
#include <gsl/multi_span>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -668,7 +669,9 @@ SUITE(multi_span_tests)
|
|||||||
CHECK(s2.empty());
|
CHECK(s2.empty());
|
||||||
|
|
||||||
auto get_temp_span = [&]() -> multi_span<int> { return {&arr[1], 2}; };
|
auto get_temp_span = [&]() -> multi_span<int> { return {&arr[1], 2}; };
|
||||||
auto use_span = [&](multi_span<const int> s) { CHECK(s.length() == 2 && s.data() == &arr[1]); };
|
auto use_span = [&](multi_span<const int> s) {
|
||||||
|
CHECK(s.length() == 2 && s.data() == &arr[1]);
|
||||||
|
};
|
||||||
use_span(get_temp_span());
|
use_span(get_temp_span());
|
||||||
|
|
||||||
s1 = get_temp_span();
|
s1 = get_temp_span();
|
||||||
@ -1283,10 +1286,7 @@ SUITE(multi_span_tests)
|
|||||||
delete[] arr;
|
delete[] arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(index_constructors)
|
TEST(index_constructors){{// components of the same type
|
||||||
{
|
|
||||||
{
|
|
||||||
// components of the same type
|
|
||||||
index<3> i1(0, 1, 2);
|
index<3> i1(0, 1, 2);
|
||||||
CHECK(i1[0] == 0);
|
CHECK(i1[0] == 0);
|
||||||
|
|
||||||
@ -1311,9 +1311,9 @@ SUITE(multi_span_tests)
|
|||||||
// default
|
// default
|
||||||
index<3> i9 = {};
|
index<3> i9 = {};
|
||||||
CHECK(i9[0] == 0);
|
CHECK(i9[0] == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// components of the same type
|
// components of the same type
|
||||||
index<1> i1(0);
|
index<1> i1(0);
|
||||||
CHECK(i1[0] == 0);
|
CHECK(i1[0] == 0);
|
||||||
@ -1342,21 +1342,21 @@ SUITE(multi_span_tests)
|
|||||||
// default
|
// default
|
||||||
index<1> i9 = {};
|
index<1> i9 = {};
|
||||||
CHECK(i9[0] == 0);
|
CHECK(i9[0] == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
index<3> i1(0, 1);
|
index<3> i1(0, 1);
|
||||||
index<3> i2(0, 1, 2, 3);
|
index<3> i2(0, 1, 2, 3);
|
||||||
index<3> i3 = {0};
|
index<3> i3 = {0};
|
||||||
index<3> i4 = {0, 1, 2, 3};
|
index<3> i4 = {0, 1, 2, 3};
|
||||||
index<1> i5 = {0, 1};
|
index<1> i5 = {0, 1};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(index_operations)
|
TEST(index_operations)
|
||||||
{
|
{
|
||||||
ptrdiff_t a[3] = {0, 1, 2};
|
ptrdiff_t a[3] = {0, 1, 2};
|
||||||
ptrdiff_t b[3] = {3, 4, 5};
|
ptrdiff_t b[3] = {3, 4, 5};
|
||||||
index<3> i = a;
|
index<3> i = a;
|
||||||
@ -1408,10 +1408,10 @@ SUITE(multi_span_tests)
|
|||||||
CHECK(k[0] == 1);
|
CHECK(k[0] == 1);
|
||||||
CHECK(k[1] == 2);
|
CHECK(k[1] == 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void iterate_second_column(multi_span<int, dynamic_range, dynamic_range> av)
|
void iterate_second_column(multi_span<int, dynamic_range, dynamic_range> av)
|
||||||
{
|
{
|
||||||
auto length = av.size() / 2;
|
auto length = av.size() / 2;
|
||||||
|
|
||||||
// view to the second column
|
// view to the second column
|
||||||
@ -1463,10 +1463,10 @@ SUITE(multi_span_tests)
|
|||||||
|
|
||||||
CHECK(sum == check_sum);
|
CHECK(sum == check_sum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_section_iteration)
|
TEST(span_section_iteration)
|
||||||
{
|
{
|
||||||
int arr[4][2] = {{4, 0}, {5, 1}, {6, 2}, {7, 3}};
|
int arr[4][2] = {{4, 0}, {5, 1}, {6, 2}, {7, 3}};
|
||||||
|
|
||||||
// static bounds
|
// static bounds
|
||||||
@ -1489,10 +1489,10 @@ SUITE(multi_span_tests)
|
|||||||
multi_span<int, dynamic_range, dynamic_range> av = arr;
|
multi_span<int, dynamic_range, dynamic_range> av = arr;
|
||||||
iterate_second_column(av);
|
iterate_second_column(av);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(dynamic_span_section_iteration)
|
TEST(dynamic_span_section_iteration)
|
||||||
{
|
{
|
||||||
auto height = 4, width = 2;
|
auto height = 4, width = 2;
|
||||||
auto size = height * width;
|
auto size = height * width;
|
||||||
|
|
||||||
@ -1515,15 +1515,16 @@ SUITE(multi_span_tests)
|
|||||||
}
|
}
|
||||||
// both bounds are dynamic
|
// both bounds are dynamic
|
||||||
{
|
{
|
||||||
multi_span<int, dynamic_range, dynamic_range> av2 = as_multi_span(av, dim(height), dim(width));
|
multi_span<int, dynamic_range, dynamic_range> av2 =
|
||||||
|
as_multi_span(av, dim(height), dim(width));
|
||||||
iterate_second_column(av2);
|
iterate_second_column(av2);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] arr;
|
delete[] arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_structure_size)
|
TEST(span_structure_size)
|
||||||
{
|
{
|
||||||
double(*arr)[3][4] = new double[100][3][4];
|
double(*arr)[3][4] = new double[100][3][4];
|
||||||
multi_span<double, dynamic_range, 3, 4> av1(arr, 10);
|
multi_span<double, dynamic_range, 3, 4> av1(arr, 10);
|
||||||
|
|
||||||
@ -1536,12 +1537,13 @@ SUITE(multi_span_tests)
|
|||||||
|
|
||||||
CHECK_THROW(av1[10][3][4], fail_fast);
|
CHECK_THROW(av1[10][3][4], fail_fast);
|
||||||
|
|
||||||
multi_span<const double, dynamic_range, 6, 4> av2 = as_multi_span(av1, dim(5), dim<6>(), dim<4>());
|
multi_span<const double, dynamic_range, 6, 4> av2 =
|
||||||
|
as_multi_span(av1, dim(5), dim<6>(), dim<4>());
|
||||||
(void) av2;
|
(void) av2;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(fixed_size_conversions)
|
TEST(fixed_size_conversions)
|
||||||
{
|
{
|
||||||
int arr[] = {1, 2, 3, 4};
|
int arr[] = {1, 2, 3, 4};
|
||||||
|
|
||||||
// converting to an multi_span from an equal size array is ok
|
// converting to an multi_span from an equal size array is ok
|
||||||
@ -1634,10 +1636,10 @@ SUITE(multi_span_tests)
|
|||||||
(void) av2;
|
(void) av2;
|
||||||
};
|
};
|
||||||
CHECK_THROW(f(), fail_fast);
|
CHECK_THROW(f(), fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(as_writeable_bytes)
|
TEST(as_writeable_bytes)
|
||||||
{
|
{
|
||||||
int a[] = {1, 2, 3, 4};
|
int a[] = {1, 2, 3, 4};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1662,10 +1664,10 @@ SUITE(multi_span_tests)
|
|||||||
CHECK(wav.data() == reinterpret_cast<byte*>(&a[0]));
|
CHECK(wav.data() == reinterpret_cast<byte*>(&a[0]));
|
||||||
CHECK(static_cast<std::size_t>(wav.length()) == sizeof(a));
|
CHECK(static_cast<std::size_t>(wav.length()) == sizeof(a));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(iterator)
|
TEST(iterator)
|
||||||
{
|
{
|
||||||
int a[] = {1, 2, 3, 4};
|
int a[] = {1, 2, 3, 4};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1688,7 +1690,7 @@ SUITE(multi_span_tests)
|
|||||||
CHECK(a[i] == 1);
|
CHECK(a[i] == 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int, const char* []) { return UnitTest::RunAllTests(); }
|
int main(int, const char* []) { return UnitTest::RunAllTests(); }
|
||||||
|
@ -15,19 +15,27 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <UnitTest++/UnitTest++.h>
|
#include <UnitTest++/UnitTest++.h>
|
||||||
|
|
||||||
#include <gsl/gsl>
|
#include <gsl/gsl>
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
|
|
||||||
struct MyBase {};
|
struct MyBase
|
||||||
struct MyDerived : public MyBase {};
|
{
|
||||||
struct Unrelated {};
|
};
|
||||||
|
struct MyDerived : public MyBase
|
||||||
|
{
|
||||||
|
};
|
||||||
|
struct Unrelated
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
// stand-in for a user-defined ref-counted class
|
// stand-in for a user-defined ref-counted class
|
||||||
template<typename T>
|
template <typename T>
|
||||||
struct RefCounted
|
struct RefCounted
|
||||||
{
|
{
|
||||||
RefCounted(T* p) : p_(p) {}
|
RefCounted(T* p) : p_(p) {}
|
||||||
@ -41,55 +49,56 @@ struct CustomPtr
|
|||||||
{
|
{
|
||||||
CustomPtr(T* p) : p_(p) {}
|
CustomPtr(T* p) : p_(p) {}
|
||||||
operator T*() { return p_; }
|
operator T*() { return p_; }
|
||||||
bool operator !=(std::nullptr_t)const { return p_ != nullptr; }
|
bool operator!=(std::nullptr_t) const { return p_ != nullptr; }
|
||||||
T* p_ = nullptr;
|
T* p_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
std::string operator==(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
std::string operator==(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<const void*>(lhs.p_) == reinterpret_cast<const void*>(rhs.p_) ? "true" : "false";
|
return reinterpret_cast<const void*>(lhs.p_) == reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||||
|
: "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
std::string operator!=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
std::string operator!=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<const void*>(lhs.p_) != reinterpret_cast<const void*>(rhs.p_) ? "true" : "false";
|
return reinterpret_cast<const void*>(lhs.p_) != reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||||
|
: "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
std::string operator<(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
std::string operator<(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<const void*>(lhs.p_) < reinterpret_cast<const void*>(rhs.p_) ? "true" : "false";
|
return reinterpret_cast<const void*>(lhs.p_) < reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||||
|
: "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
std::string operator>(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
std::string operator>(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<const void*>(lhs.p_) > reinterpret_cast<const void*>(rhs.p_) ? "true" : "false";
|
return reinterpret_cast<const void*>(lhs.p_) > reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||||
|
: "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
std::string operator<=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
std::string operator<=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<const void*>(lhs.p_) <= reinterpret_cast<const void*>(rhs.p_) ? "true" : "false";
|
return reinterpret_cast<const void*>(lhs.p_) <= reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||||
|
: "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
std::string operator>=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
std::string operator>=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<const void*>(lhs.p_) >= reinterpret_cast<const void*>(rhs.p_) ? "true" : "false";
|
return reinterpret_cast<const void*>(lhs.p_) >= reinterpret_cast<const void*>(rhs.p_) ? "true"
|
||||||
|
: "false";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SUITE(NotNullTests)
|
SUITE(NotNullTests)
|
||||||
{
|
{
|
||||||
|
|
||||||
bool helper(not_null<int*> p)
|
bool helper(not_null<int*> p) { return *p == 12; }
|
||||||
{
|
|
||||||
return *p == 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(TestNotNullConstructors)
|
TEST(TestNotNullConstructors)
|
||||||
{
|
{
|
||||||
@ -103,14 +112,15 @@ SUITE(NotNullTests)
|
|||||||
// Forbid non-nullptr assignable types
|
// Forbid non-nullptr assignable types
|
||||||
not_null<std::vector<int>> f(std::vector<int>{1});
|
not_null<std::vector<int>> f(std::vector<int>{1});
|
||||||
not_null<int> z(10);
|
not_null<int> z(10);
|
||||||
not_null<std::vector<int>> y({1,2});
|
not_null<std::vector<int>> y({1, 2});
|
||||||
#endif
|
#endif
|
||||||
int i = 12;
|
int i = 12;
|
||||||
auto rp = RefCounted<int>(&i);
|
auto rp = RefCounted<int>(&i);
|
||||||
not_null<int*> p(rp);
|
not_null<int*> p(rp);
|
||||||
CHECK(p.get() == &i);
|
CHECK(p.get() == &i);
|
||||||
|
|
||||||
not_null<std::shared_ptr<int>> x(std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
|
not_null<std::shared_ptr<int>> x(
|
||||||
|
std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TestNotNullCasting)
|
TEST(TestNotNullCasting)
|
||||||
@ -119,7 +129,7 @@ SUITE(NotNullTests)
|
|||||||
MyDerived derived;
|
MyDerived derived;
|
||||||
Unrelated unrelated;
|
Unrelated unrelated;
|
||||||
not_null<Unrelated*> u = &unrelated;
|
not_null<Unrelated*> u = &unrelated;
|
||||||
(void)u;
|
(void) u;
|
||||||
not_null<MyDerived*> p = &derived;
|
not_null<MyDerived*> p = &derived;
|
||||||
not_null<MyBase*> q = &base;
|
not_null<MyBase*> q = &base;
|
||||||
q = p; // allowed with heterogeneous copy ctor
|
q = p; // allowed with heterogeneous copy ctor
|
||||||
@ -211,7 +221,7 @@ SUITE(NotNullTests)
|
|||||||
|
|
||||||
TEST(TestNotNullCustomPtrComparison)
|
TEST(TestNotNullCustomPtrComparison)
|
||||||
{
|
{
|
||||||
int ints[2] = { 42, 43 };
|
int ints[2] = {42, 43};
|
||||||
CustomPtr<int> p1(&ints[0]);
|
CustomPtr<int> p1(&ints[0]);
|
||||||
CustomPtr<const int> p2(&ints[1]);
|
CustomPtr<const int> p2(&ints[1]);
|
||||||
|
|
||||||
@ -242,7 +252,4 @@ SUITE(NotNullTests)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int, const char *[])
|
int main(int, const char* []) { return UnitTest::RunAllTests(); }
|
||||||
{
|
|
||||||
return UnitTest::RunAllTests();
|
|
||||||
}
|
|
||||||
|
@ -15,17 +15,16 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <UnitTest++/UnitTest++.h>
|
#include <UnitTest++/UnitTest++.h>
|
||||||
|
|
||||||
#include <gsl/gsl>
|
#include <gsl/gsl>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
|
|
||||||
SUITE(owner_tests)
|
SUITE(owner_tests)
|
||||||
{
|
{
|
||||||
void f(int* i)
|
void f(int* i) { *i += 1; }
|
||||||
{
|
|
||||||
*i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(basic_test)
|
TEST(basic_test)
|
||||||
{
|
{
|
||||||
@ -37,7 +36,4 @@ SUITE(owner_tests)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int, const char *[])
|
int main(int, const char* []) { return UnitTest::RunAllTests(); }
|
||||||
{
|
|
||||||
return UnitTest::RunAllTests();
|
|
||||||
}
|
|
||||||
|
@ -15,15 +15,16 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <UnitTest++/UnitTest++.h>
|
#include <UnitTest++/UnitTest++.h>
|
||||||
|
|
||||||
#include <gsl/span>
|
#include <gsl/span>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <regex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <regex>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
@ -148,7 +149,9 @@ SUITE(span_tests)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto workaround_macro = []() { span<int, 1> s{ nullptr, static_cast<span<int>::index_type>(0) }; };
|
auto workaround_macro = []() {
|
||||||
|
span<int, 1> s{nullptr, static_cast<span<int>::index_type>(0)};
|
||||||
|
};
|
||||||
CHECK_THROW(workaround_macro(), fail_fast);
|
CHECK_THROW(workaround_macro(), fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,13 +268,13 @@ SUITE(span_tests)
|
|||||||
|
|
||||||
{
|
{
|
||||||
int* p = nullptr;
|
int* p = nullptr;
|
||||||
span<int> s{ p, p };
|
span<int> s{p, p};
|
||||||
CHECK(s.length() == 0 && s.data() == nullptr);
|
CHECK(s.length() == 0 && s.data() == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int* p = nullptr;
|
int* p = nullptr;
|
||||||
span<int, 0> s{ p, p };
|
span<int, 0> s{p, p};
|
||||||
CHECK(s.length() == 0 && s.data() == nullptr);
|
CHECK(s.length() == 0 && s.data() == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,7 +317,7 @@ SUITE(span_tests)
|
|||||||
CHECK(s.length() == 5 && s.data() == &arr[0]);
|
CHECK(s.length() == 5 && s.data() == &arr[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int arr2d[2][3] = { 1, 2, 3, 4, 5, 6 };
|
int arr2d[2][3] = {1, 2, 3, 4, 5, 6};
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
@ -338,11 +341,11 @@ SUITE(span_tests)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
span<int, 6> s{ arr2d };
|
span<int, 6> s{arr2d};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
span<int[3]> s{ &(arr2d[0]), 1 };
|
span<int[3]> s{&(arr2d[0]), 1};
|
||||||
CHECK(s.length() == 1 && s.data() == &arr2d[0]);
|
CHECK(s.length() == 1 && s.data() == &arr2d[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,7 +453,7 @@ SUITE(span_tests)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto get_an_array = []()->std::array<int, 4> { return{1, 2, 3, 4}; };
|
auto get_an_array = []() -> std::array<int, 4> { return {1, 2, 3, 4}; };
|
||||||
auto take_a_span = [](span<int> s) { static_cast<void>(s); };
|
auto take_a_span = [](span<int> s) { static_cast<void>(s); };
|
||||||
// try to take a temporary std::array
|
// try to take a temporary std::array
|
||||||
take_a_span(get_an_array());
|
take_a_span(get_an_array());
|
||||||
@ -458,7 +461,7 @@ SUITE(span_tests)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
auto get_an_array = []() -> std::array<int, 4> { return { 1, 2, 3, 4 }; };
|
auto get_an_array = []() -> std::array<int, 4> { return {1, 2, 3, 4}; };
|
||||||
auto take_a_span = [](span<const int> s) { static_cast<void>(s); };
|
auto take_a_span = [](span<const int> s) { static_cast<void>(s); };
|
||||||
// try to take a temporary std::array
|
// try to take a temporary std::array
|
||||||
take_a_span(get_an_array());
|
take_a_span(get_an_array());
|
||||||
@ -588,8 +591,7 @@ SUITE(span_tests)
|
|||||||
{
|
{
|
||||||
auto arr = std::make_unique<int[]>(4);
|
auto arr = std::make_unique<int[]>(4);
|
||||||
|
|
||||||
for (auto i = 0U; i < 4; i++)
|
for (auto i = 0U; i < 4; i++) arr[i] = gsl::narrow_cast<int>(i + 1);
|
||||||
arr[i] = gsl::narrow_cast<int>(i + 1);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
span<int> s{arr, 4};
|
span<int> s{arr, 4};
|
||||||
@ -695,14 +697,14 @@ SUITE(span_tests)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto get_temp_vector = []() -> std::vector<int> { return{}; };
|
auto get_temp_vector = []() -> std::vector<int> { return {}; };
|
||||||
auto use_span = [](span<const int> s) { static_cast<void>(s); };
|
auto use_span = [](span<const int> s) { static_cast<void>(s); };
|
||||||
use_span(get_temp_vector());
|
use_span(get_temp_vector());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
auto get_temp_string = []() -> std::string { return{}; };
|
auto get_temp_string = []() -> std::string { return {}; };
|
||||||
auto use_span = [](span<char> s) { static_cast<void>(s); };
|
auto use_span = [](span<char> s) { static_cast<void>(s); };
|
||||||
use_span(get_temp_string());
|
use_span(get_temp_string());
|
||||||
#endif
|
#endif
|
||||||
@ -744,45 +746,42 @@ SUITE(span_tests)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(from_convertible_span_constructor)
|
TEST(from_convertible_span_constructor){{span<DerivedClass> avd;
|
||||||
{
|
|
||||||
{
|
|
||||||
span<DerivedClass> avd;
|
|
||||||
span<const DerivedClass> avcd = avd;
|
span<const DerivedClass> avcd = avd;
|
||||||
static_cast<void>(avcd);
|
static_cast<void>(avcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
span<DerivedClass> avd;
|
span<DerivedClass> avd;
|
||||||
span<BaseClass> avb = avd;
|
span<BaseClass> avb = avd;
|
||||||
static_cast<void>(avb);
|
static_cast<void>(avb);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
span<int> s;
|
span<int> s;
|
||||||
span<unsigned int> s2 = s;
|
span<unsigned int> s2 = s;
|
||||||
static_cast<void>(s2);
|
static_cast<void>(s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
span<int> s;
|
span<int> s;
|
||||||
span<const unsigned int> s2 = s;
|
span<const unsigned int> s2 = s;
|
||||||
static_cast<void>(s2);
|
static_cast<void>(s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
span<int> s;
|
span<int> s;
|
||||||
span<short> s2 = s;
|
span<short> s2 = s;
|
||||||
static_cast<void>(s2);
|
static_cast<void>(s2);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(copy_move_and_assignment)
|
TEST(copy_move_and_assignment)
|
||||||
{
|
{
|
||||||
span<int> s1;
|
span<int> s1;
|
||||||
CHECK(s1.empty());
|
CHECK(s1.empty());
|
||||||
|
|
||||||
@ -800,10 +799,10 @@ SUITE(span_tests)
|
|||||||
|
|
||||||
s1 = get_temp_span();
|
s1 = get_temp_span();
|
||||||
CHECK(s1.length() == 2 && s1.data() == &arr[1]);
|
CHECK(s1.length() == 2 && s1.data() == &arr[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(first)
|
TEST(first)
|
||||||
{
|
{
|
||||||
int arr[5] = {1, 2, 3, 4, 5};
|
int arr[5] = {1, 2, 3, 4, 5};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -838,10 +837,10 @@ SUITE(span_tests)
|
|||||||
CHECK(av.first<0>().length() == 0);
|
CHECK(av.first<0>().length() == 0);
|
||||||
CHECK(av.first(0).length() == 0);
|
CHECK(av.first(0).length() == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(last)
|
TEST(last)
|
||||||
{
|
{
|
||||||
int arr[5] = {1, 2, 3, 4, 5};
|
int arr[5] = {1, 2, 3, 4, 5};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -875,10 +874,10 @@ SUITE(span_tests)
|
|||||||
CHECK(av.last<0>().length() == 0);
|
CHECK(av.last<0>().length() == 0);
|
||||||
CHECK(av.last(0).length() == 0);
|
CHECK(av.last(0).length() == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(subspan)
|
TEST(subspan)
|
||||||
{
|
{
|
||||||
int arr[5] = {1, 2, 3, 4, 5};
|
int arr[5] = {1, 2, 3, 4, 5};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -944,10 +943,10 @@ SUITE(span_tests)
|
|||||||
const auto av2 = av.subspan(1);
|
const auto av2 = av.subspan(1);
|
||||||
for (int i = 0; i < 4; ++i) CHECK(av2[i] == i + 2);
|
for (int i = 0; i < 4; ++i) CHECK(av2[i] == i + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(at_call)
|
TEST(at_call)
|
||||||
{
|
{
|
||||||
int arr[4] = {1, 2, 3, 4};
|
int arr[4] = {1, 2, 3, 4};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -961,12 +960,12 @@ SUITE(span_tests)
|
|||||||
span<int, 2> s = arr2d;
|
span<int, 2> s = arr2d;
|
||||||
CHECK(s.at(0) == 1);
|
CHECK(s.at(0) == 1);
|
||||||
CHECK(s.at(1) == 6);
|
CHECK(s.at(1) == 6);
|
||||||
CHECK_THROW(s.at(2) ,fail_fast);
|
CHECK_THROW(s.at(2), fail_fast);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(operator_function_call)
|
TEST(operator_function_call)
|
||||||
{
|
{
|
||||||
int arr[4] = {1, 2, 3, 4};
|
int arr[4] = {1, 2, 3, 4};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -980,31 +979,31 @@ SUITE(span_tests)
|
|||||||
span<int, 2> s = arr2d;
|
span<int, 2> s = arr2d;
|
||||||
CHECK(s(0) == 1);
|
CHECK(s(0) == 1);
|
||||||
CHECK(s(1) == 6);
|
CHECK(s(1) == 6);
|
||||||
CHECK_THROW(s(2) ,fail_fast);
|
CHECK_THROW(s(2), fail_fast);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(iterator_default_init)
|
TEST(iterator_default_init)
|
||||||
{
|
{
|
||||||
span<int>::iterator it1;
|
span<int>::iterator it1;
|
||||||
span<int>::iterator it2;
|
span<int>::iterator it2;
|
||||||
CHECK(it1 == it2);
|
CHECK(it1 == it2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(const_iterator_default_init)
|
TEST(const_iterator_default_init)
|
||||||
{
|
{
|
||||||
span<int>::const_iterator it1;
|
span<int>::const_iterator it1;
|
||||||
span<int>::const_iterator it2;
|
span<int>::const_iterator it2;
|
||||||
CHECK(it1 == it2);
|
CHECK(it1 == it2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(iterator_conversions)
|
TEST(iterator_conversions)
|
||||||
{
|
{
|
||||||
span<int>::iterator badIt;
|
span<int>::iterator badIt;
|
||||||
span<int>::const_iterator badConstIt;
|
span<int>::const_iterator badConstIt;
|
||||||
CHECK(badIt == badConstIt);
|
CHECK(badIt == badConstIt);
|
||||||
|
|
||||||
int a[] = { 1, 2, 3, 4 };
|
int a[] = {1, 2, 3, 4};
|
||||||
span<int> s = a;
|
span<int> s = a;
|
||||||
|
|
||||||
auto it = s.begin();
|
auto it = s.begin();
|
||||||
@ -1018,11 +1017,11 @@ SUITE(span_tests)
|
|||||||
|
|
||||||
span<int>::const_iterator cit3 = it + 4;
|
span<int>::const_iterator cit3 = it + 4;
|
||||||
CHECK(cit3 == s.cend());
|
CHECK(cit3 == s.cend());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(iterator_comparisons)
|
TEST(iterator_comparisons)
|
||||||
{
|
{
|
||||||
int a[] = { 1, 2, 3, 4 };
|
int a[] = {1, 2, 3, 4};
|
||||||
{
|
{
|
||||||
span<int> s = a;
|
span<int> s = a;
|
||||||
span<int>::iterator it = s.begin();
|
span<int>::iterator it = s.begin();
|
||||||
@ -1065,12 +1064,12 @@ SUITE(span_tests)
|
|||||||
CHECK(it2 > cit);
|
CHECK(it2 > cit);
|
||||||
CHECK(it2 >= cit);
|
CHECK(it2 >= cit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(begin_end)
|
TEST(begin_end)
|
||||||
|
{
|
||||||
{
|
{
|
||||||
{
|
int a[] = {1, 2, 3, 4};
|
||||||
int a[] = { 1, 2, 3, 4 };
|
|
||||||
span<int> s = a;
|
span<int> s = a;
|
||||||
|
|
||||||
span<int>::iterator it = s.begin();
|
span<int>::iterator it = s.begin();
|
||||||
@ -1083,7 +1082,7 @@ SUITE(span_tests)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int a[] = { 1, 2, 3, 4 };
|
int a[] = {1, 2, 3, 4};
|
||||||
span<int> s = a;
|
span<int> s = a;
|
||||||
|
|
||||||
auto it = s.begin();
|
auto it = s.begin();
|
||||||
@ -1108,8 +1107,7 @@ SUITE(span_tests)
|
|||||||
|
|
||||||
it = first;
|
it = first;
|
||||||
CHECK(it == first);
|
CHECK(it == first);
|
||||||
while (it != s.end())
|
while (it != s.end()) {
|
||||||
{
|
|
||||||
*it = 5;
|
*it = 5;
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
@ -1117,17 +1115,16 @@ SUITE(span_tests)
|
|||||||
CHECK(it == beyond);
|
CHECK(it == beyond);
|
||||||
CHECK(it - beyond == 0);
|
CHECK(it - beyond == 0);
|
||||||
|
|
||||||
for (const auto& n : s)
|
for (const auto& n : s) {
|
||||||
{
|
|
||||||
CHECK(n == 5);
|
CHECK(n == 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(cbegin_cend)
|
TEST(cbegin_cend)
|
||||||
|
{
|
||||||
{
|
{
|
||||||
{
|
int a[] = {1, 2, 3, 4};
|
||||||
int a[] = { 1, 2, 3, 4 };
|
|
||||||
span<int> s = a;
|
span<int> s = a;
|
||||||
|
|
||||||
span<int>::const_iterator cit = s.cbegin();
|
span<int>::const_iterator cit = s.cbegin();
|
||||||
@ -1164,8 +1161,7 @@ SUITE(span_tests)
|
|||||||
int last = 0;
|
int last = 0;
|
||||||
it = first;
|
it = first;
|
||||||
CHECK(it == first);
|
CHECK(it == first);
|
||||||
while (it != s.cend())
|
while (it != s.cend()) {
|
||||||
{
|
|
||||||
CHECK(*it == last + 1);
|
CHECK(*it == last + 1);
|
||||||
|
|
||||||
last = *it;
|
last = *it;
|
||||||
@ -1175,10 +1171,10 @@ SUITE(span_tests)
|
|||||||
CHECK(it == beyond);
|
CHECK(it == beyond);
|
||||||
CHECK(it - beyond == 0);
|
CHECK(it - beyond == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(rbegin_rend)
|
TEST(rbegin_rend)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
int a[] = {1, 2, 3, 4};
|
int a[] = {1, 2, 3, 4};
|
||||||
span<int> s = a;
|
span<int> s = a;
|
||||||
@ -1205,8 +1201,7 @@ SUITE(span_tests)
|
|||||||
|
|
||||||
it = first;
|
it = first;
|
||||||
CHECK(it == first);
|
CHECK(it == first);
|
||||||
while (it != s.rend())
|
while (it != s.rend()) {
|
||||||
{
|
|
||||||
*it = 5;
|
*it = 5;
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
@ -1214,15 +1209,14 @@ SUITE(span_tests)
|
|||||||
CHECK(it == beyond);
|
CHECK(it == beyond);
|
||||||
CHECK(it - beyond == 0);
|
CHECK(it - beyond == 0);
|
||||||
|
|
||||||
for (const auto& n : s)
|
for (const auto& n : s) {
|
||||||
{
|
|
||||||
CHECK(n == 5);
|
CHECK(n == 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(crbegin_crend)
|
TEST(crbegin_crend)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
int a[] = {1, 2, 3, 4};
|
int a[] = {1, 2, 3, 4};
|
||||||
span<int> s = a;
|
span<int> s = a;
|
||||||
@ -1248,8 +1242,7 @@ SUITE(span_tests)
|
|||||||
it = first;
|
it = first;
|
||||||
CHECK(it == first);
|
CHECK(it == first);
|
||||||
int last = 5;
|
int last = 5;
|
||||||
while (it != s.crend())
|
while (it != s.crend()) {
|
||||||
{
|
|
||||||
CHECK(*it == last - 1);
|
CHECK(*it == last - 1);
|
||||||
last = *it;
|
last = *it;
|
||||||
|
|
||||||
@ -1259,10 +1252,10 @@ SUITE(span_tests)
|
|||||||
CHECK(it == beyond);
|
CHECK(it == beyond);
|
||||||
CHECK(it - beyond == 0);
|
CHECK(it - beyond == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(comparison_operators)
|
TEST(comparison_operators)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
span<int> s1 = nullptr;
|
span<int> s1 = nullptr;
|
||||||
span<int> s2 = nullptr;
|
span<int> s2 = nullptr;
|
||||||
@ -1379,10 +1372,10 @@ SUITE(span_tests)
|
|||||||
CHECK(s2 >= s1);
|
CHECK(s2 >= s1);
|
||||||
CHECK(!(s1 >= s2));
|
CHECK(!(s1 >= s2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(as_bytes)
|
TEST(as_bytes)
|
||||||
{
|
{
|
||||||
int a[] = {1, 2, 3, 4};
|
int a[] = {1, 2, 3, 4};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1409,10 +1402,10 @@ SUITE(span_tests)
|
|||||||
CHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data()));
|
CHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data()));
|
||||||
CHECK(bs.length() == s.length_bytes());
|
CHECK(bs.length() == s.length_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(as_writeable_bytes)
|
TEST(as_writeable_bytes)
|
||||||
{
|
{
|
||||||
int a[] = {1, 2, 3, 4};
|
int a[] = {1, 2, 3, 4};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1442,10 +1435,10 @@ SUITE(span_tests)
|
|||||||
CHECK(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));
|
CHECK(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));
|
||||||
CHECK(bs.length() == s.length_bytes());
|
CHECK(bs.length() == s.length_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(fixed_size_conversions)
|
TEST(fixed_size_conversions)
|
||||||
{
|
{
|
||||||
int arr[] = {1, 2, 3, 4};
|
int arr[] = {1, 2, 3, 4};
|
||||||
|
|
||||||
// converting to an span from an equal size array is ok
|
// converting to an span from an equal size array is ok
|
||||||
@ -1526,11 +1519,11 @@ SUITE(span_tests)
|
|||||||
static_cast<void>(_s4);
|
static_cast<void>(_s4);
|
||||||
};
|
};
|
||||||
CHECK_THROW(f(), fail_fast);
|
CHECK_THROW(f(), fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(interop_with_std_regex)
|
TEST(interop_with_std_regex)
|
||||||
{
|
{
|
||||||
char lat[] = { '1', '2', '3', '4', '5', '6', 'E', 'F', 'G' };
|
char lat[] = {'1', '2', '3', '4', '5', '6', 'E', 'F', 'G'};
|
||||||
span<char> s = lat;
|
span<char> s = lat;
|
||||||
const auto f_it = s.begin() + 7;
|
const auto f_it = s.begin() + 7;
|
||||||
|
|
||||||
@ -1549,21 +1542,21 @@ SUITE(span_tests)
|
|||||||
CHECK(match[0].matched);
|
CHECK(match[0].matched);
|
||||||
CHECK(match[0].first == f_it);
|
CHECK(match[0].first == f_it);
|
||||||
CHECK(match[0].second == (f_it + 1));
|
CHECK(match[0].second == (f_it + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(interop_with_gsl_at)
|
TEST(interop_with_gsl_at)
|
||||||
{
|
{
|
||||||
int arr[5] = {1, 2, 3, 4, 5};
|
int arr[5] = {1, 2, 3, 4, 5};
|
||||||
span<int> s{arr};
|
span<int> s{arr};
|
||||||
CHECK(at(s,0) == 1 && at(s,1) == 2);
|
CHECK(at(s, 0) == 1 && at(s, 1) == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(default_constructible)
|
TEST(default_constructible)
|
||||||
{
|
{
|
||||||
CHECK((std::is_default_constructible<span<int>>::value));
|
CHECK((std::is_default_constructible<span<int>>::value));
|
||||||
CHECK((std::is_default_constructible<span<int, 0>>::value));
|
CHECK((std::is_default_constructible<span<int, 0>>::value));
|
||||||
CHECK((!std::is_default_constructible<span<int, 42>>::value));
|
CHECK((!std::is_default_constructible<span<int, 42>>::value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int, const char* []) { return UnitTest::RunAllTests(); }
|
int main(int, const char* []) { return UnitTest::RunAllTests(); }
|
||||||
|
@ -15,34 +15,39 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <UnitTest++/UnitTest++.h>
|
#include <UnitTest++/UnitTest++.h>
|
||||||
|
|
||||||
#include <gsl/multi_span>
|
#include <gsl/multi_span>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct BaseClass {};
|
struct BaseClass
|
||||||
struct DerivedClass : BaseClass {};
|
{
|
||||||
|
};
|
||||||
|
struct DerivedClass : BaseClass
|
||||||
|
{
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
SUITE(strided_span_tests)
|
SUITE(strided_span_tests)
|
||||||
{
|
{
|
||||||
TEST (span_section_test)
|
TEST(span_section_test)
|
||||||
{
|
{
|
||||||
int a[30][4][5];
|
int a[30][4][5];
|
||||||
|
|
||||||
const auto av = as_multi_span(a);
|
const auto av = as_multi_span(a);
|
||||||
const auto sub = av.section({15, 0, 0}, gsl::index<3>{2, 2, 2});
|
const auto sub = av.section({15, 0, 0}, gsl::index<3>{2, 2, 2});
|
||||||
const auto subsub = sub.section({1, 0, 0}, gsl::index<3>{1, 1, 1});
|
const auto subsub = sub.section({1, 0, 0}, gsl::index<3>{1, 1, 1});
|
||||||
(void)subsub;
|
(void) subsub;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(span_section)
|
TEST(span_section)
|
||||||
@ -51,13 +56,13 @@ SUITE(strided_span_tests)
|
|||||||
std::iota(begin(data), end(data), 0);
|
std::iota(begin(data), end(data), 0);
|
||||||
const multi_span<int, 5, 10> av = as_multi_span(multi_span<int>{data}, dim<5>(), dim<10>());
|
const multi_span<int, 5, 10> av = as_multi_span(multi_span<int>{data}, dim<5>(), dim<10>());
|
||||||
|
|
||||||
const strided_span<int, 2> av_section_1 = av.section({ 1, 2 }, { 3, 4 });
|
const strided_span<int, 2> av_section_1 = av.section({1, 2}, {3, 4});
|
||||||
CHECK((av_section_1[{0, 0}] == 12));
|
CHECK((av_section_1[{0, 0}] == 12));
|
||||||
CHECK((av_section_1[{0, 1}] == 13));
|
CHECK((av_section_1[{0, 1}] == 13));
|
||||||
CHECK((av_section_1[{1, 0}] == 22));
|
CHECK((av_section_1[{1, 0}] == 22));
|
||||||
CHECK((av_section_1[{2, 3}] == 35));
|
CHECK((av_section_1[{2, 3}] == 35));
|
||||||
|
|
||||||
const strided_span<int, 2> av_section_2 = av_section_1.section({ 1, 2 }, { 2,2 });
|
const strided_span<int, 2> av_section_2 = av_section_1.section({1, 2}, {2, 2});
|
||||||
CHECK((av_section_2[{0, 0}] == 24));
|
CHECK((av_section_2[{0, 0}] == 24));
|
||||||
CHECK((av_section_2[{0, 1}] == 25));
|
CHECK((av_section_2[{0, 1}] == 25));
|
||||||
CHECK((av_section_2[{1, 0}] == 34));
|
CHECK((av_section_2[{1, 0}] == 34));
|
||||||
@ -67,188 +72,197 @@ SUITE(strided_span_tests)
|
|||||||
{
|
{
|
||||||
// Check stride constructor
|
// Check stride constructor
|
||||||
{
|
{
|
||||||
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
const int carr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
const int carr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
|
|
||||||
strided_span<int, 1> sav1{ arr, {{9}, {1}} }; // T -> T
|
strided_span<int, 1> sav1{arr, {{9}, {1}}}; // T -> T
|
||||||
CHECK(sav1.bounds().index_bounds() == index<1>{ 9 });
|
CHECK(sav1.bounds().index_bounds() == index<1>{9});
|
||||||
CHECK(sav1.bounds().stride() == 1);
|
CHECK(sav1.bounds().stride() == 1);
|
||||||
CHECK(sav1[0] == 1 && sav1[8] == 9);
|
CHECK(sav1[0] == 1 && sav1[8] == 9);
|
||||||
|
|
||||||
|
strided_span<const int, 1> sav2{carr, {{4}, {2}}}; // const T -> const T
|
||||||
strided_span<const int, 1> sav2{ carr, {{ 4 }, { 2 }} }; // const T -> const T
|
CHECK(sav2.bounds().index_bounds() == index<1>{4});
|
||||||
CHECK(sav2.bounds().index_bounds() == index<1>{ 4 });
|
|
||||||
CHECK(sav2.bounds().strides() == index<1>{2});
|
CHECK(sav2.bounds().strides() == index<1>{2});
|
||||||
CHECK(sav2[0] == 1 && sav2[3] == 7);
|
CHECK(sav2[0] == 1 && sav2[3] == 7);
|
||||||
|
|
||||||
strided_span<int, 2> sav3{ arr, {{ 2, 2 },{ 6, 2 }} }; // T -> const T
|
strided_span<int, 2> sav3{arr, {{2, 2}, {6, 2}}}; // T -> const T
|
||||||
CHECK((sav3.bounds().index_bounds() == index<2>{ 2, 2 }));
|
CHECK((sav3.bounds().index_bounds() == index<2>{2, 2}));
|
||||||
CHECK((sav3.bounds().strides() == index<2>{ 6, 2 }));
|
CHECK((sav3.bounds().strides() == index<2>{6, 2}));
|
||||||
CHECK((sav3[{0, 0}] == 1 && sav3[{0, 1}] == 3 && sav3[{1, 0}] == 7));
|
CHECK((sav3[{0, 0}] == 1 && sav3[{0, 1}] == 3 && sav3[{1, 0}] == 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check multi_span constructor
|
// Check multi_span constructor
|
||||||
{
|
{
|
||||||
int arr[] = { 1, 2 };
|
int arr[] = {1, 2};
|
||||||
|
|
||||||
// From non-cv-qualified source
|
// From non-cv-qualified source
|
||||||
{
|
{
|
||||||
const multi_span<int> src = arr;
|
const multi_span<int> src = arr;
|
||||||
|
|
||||||
strided_span<int, 1> sav{ src, {2, 1} };
|
strided_span<int, 1> sav{src, {2, 1}};
|
||||||
CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
|
CHECK(sav.bounds().index_bounds() == index<1>{2});
|
||||||
CHECK(sav.bounds().strides() == index<1>{ 1 });
|
CHECK(sav.bounds().strides() == index<1>{1});
|
||||||
CHECK(sav[1] == 2);
|
CHECK(sav[1] == 2);
|
||||||
|
|
||||||
#if _MSC_VER > 1800
|
#if _MSC_VER > 1800
|
||||||
//strided_span<const int, 1> sav_c{ {src}, {2, 1} };
|
// strided_span<const int, 1> sav_c{ {src}, {2, 1} };
|
||||||
strided_span<const int, 1> sav_c{ multi_span<const int>{src}, strided_bounds<1>{2, 1} };
|
strided_span<const int, 1> sav_c{multi_span<const int>{src},
|
||||||
|
strided_bounds<1>{2, 1}};
|
||||||
#else
|
#else
|
||||||
strided_span<const int, 1> sav_c{ multi_span<const int>{src}, strided_bounds<1>{2, 1} };
|
strided_span<const int, 1> sav_c{multi_span<const int>{src},
|
||||||
|
strided_bounds<1>{2, 1}};
|
||||||
#endif
|
#endif
|
||||||
CHECK(sav_c.bounds().index_bounds() == index<1>{ 2 });
|
CHECK(sav_c.bounds().index_bounds() == index<1>{2});
|
||||||
CHECK(sav_c.bounds().strides() == index<1>{ 1 });
|
CHECK(sav_c.bounds().strides() == index<1>{1});
|
||||||
CHECK(sav_c[1] == 2);
|
CHECK(sav_c[1] == 2);
|
||||||
|
|
||||||
#if _MSC_VER > 1800
|
#if _MSC_VER > 1800
|
||||||
strided_span<volatile int, 1> sav_v{ src, {2, 1} };
|
strided_span<volatile int, 1> sav_v{src, {2, 1}};
|
||||||
#else
|
#else
|
||||||
strided_span<volatile int, 1> sav_v{ multi_span<volatile int>{src}, strided_bounds<1>{2, 1} };
|
strided_span<volatile int, 1> sav_v{multi_span<volatile int>{src},
|
||||||
|
strided_bounds<1>{2, 1}};
|
||||||
#endif
|
#endif
|
||||||
CHECK(sav_v.bounds().index_bounds() == index<1>{ 2 });
|
CHECK(sav_v.bounds().index_bounds() == index<1>{2});
|
||||||
CHECK(sav_v.bounds().strides() == index<1>{ 1 });
|
CHECK(sav_v.bounds().strides() == index<1>{1});
|
||||||
CHECK(sav_v[1] == 2);
|
CHECK(sav_v[1] == 2);
|
||||||
|
|
||||||
#if _MSC_VER > 1800
|
#if _MSC_VER > 1800
|
||||||
strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
|
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
|
||||||
#else
|
#else
|
||||||
strided_span<const volatile int, 1> sav_cv{ multi_span<const volatile int>{src}, strided_bounds<1>{2, 1} };
|
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
|
||||||
|
strided_bounds<1>{2, 1}};
|
||||||
#endif
|
#endif
|
||||||
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
|
CHECK(sav_cv.bounds().index_bounds() == index<1>{2});
|
||||||
CHECK(sav_cv.bounds().strides() == index<1>{ 1 });
|
CHECK(sav_cv.bounds().strides() == index<1>{1});
|
||||||
CHECK(sav_cv[1] == 2);
|
CHECK(sav_cv[1] == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// From const-qualified source
|
// From const-qualified source
|
||||||
{
|
{
|
||||||
const multi_span<const int> src{ arr };
|
const multi_span<const int> src{arr};
|
||||||
|
|
||||||
strided_span<const int, 1> sav_c{ src, {2, 1} };
|
strided_span<const int, 1> sav_c{src, {2, 1}};
|
||||||
CHECK(sav_c.bounds().index_bounds() == index<1>{ 2 });
|
CHECK(sav_c.bounds().index_bounds() == index<1>{2});
|
||||||
CHECK(sav_c.bounds().strides() == index<1>{ 1 });
|
CHECK(sav_c.bounds().strides() == index<1>{1});
|
||||||
CHECK(sav_c[1] == 2);
|
CHECK(sav_c[1] == 2);
|
||||||
|
|
||||||
#if _MSC_VER > 1800
|
#if _MSC_VER > 1800
|
||||||
strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
|
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
|
||||||
#else
|
#else
|
||||||
strided_span<const volatile int, 1> sav_cv{ multi_span<const volatile int>{src}, strided_bounds<1>{2, 1} };
|
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
|
||||||
|
strided_bounds<1>{2, 1}};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
|
CHECK(sav_cv.bounds().index_bounds() == index<1>{2});
|
||||||
CHECK(sav_cv.bounds().strides() == index<1>{ 1 });
|
CHECK(sav_cv.bounds().strides() == index<1>{1});
|
||||||
CHECK(sav_cv[1] == 2);
|
CHECK(sav_cv[1] == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// From volatile-qualified source
|
// From volatile-qualified source
|
||||||
{
|
{
|
||||||
const multi_span<volatile int> src{ arr };
|
const multi_span<volatile int> src{arr};
|
||||||
|
|
||||||
strided_span<volatile int, 1> sav_v{ src, {2, 1} };
|
strided_span<volatile int, 1> sav_v{src, {2, 1}};
|
||||||
CHECK(sav_v.bounds().index_bounds() == index<1>{ 2 });
|
CHECK(sav_v.bounds().index_bounds() == index<1>{2});
|
||||||
CHECK(sav_v.bounds().strides() == index<1>{ 1 });
|
CHECK(sav_v.bounds().strides() == index<1>{1});
|
||||||
CHECK(sav_v[1] == 2);
|
CHECK(sav_v[1] == 2);
|
||||||
|
|
||||||
#if _MSC_VER > 1800
|
#if _MSC_VER > 1800
|
||||||
strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
|
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
|
||||||
#else
|
#else
|
||||||
strided_span<const volatile int, 1> sav_cv{ multi_span<const volatile int>{src}, strided_bounds<1>{2, 1} };
|
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
|
||||||
|
strided_bounds<1>{2, 1}};
|
||||||
#endif
|
#endif
|
||||||
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
|
CHECK(sav_cv.bounds().index_bounds() == index<1>{2});
|
||||||
CHECK(sav_cv.bounds().strides() == index<1>{ 1 });
|
CHECK(sav_cv.bounds().strides() == index<1>{1});
|
||||||
CHECK(sav_cv[1] == 2);
|
CHECK(sav_cv[1] == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// From cv-qualified source
|
// From cv-qualified source
|
||||||
{
|
{
|
||||||
const multi_span<const volatile int> src{ arr };
|
const multi_span<const volatile int> src{arr};
|
||||||
|
|
||||||
strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
|
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
|
||||||
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
|
CHECK(sav_cv.bounds().index_bounds() == index<1>{2});
|
||||||
CHECK(sav_cv.bounds().strides() == index<1>{ 1 });
|
CHECK(sav_cv.bounds().strides() == index<1>{1});
|
||||||
CHECK(sav_cv[1] == 2);
|
CHECK(sav_cv[1] == 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check const-casting constructor
|
// Check const-casting constructor
|
||||||
{
|
{
|
||||||
int arr[2] = { 4, 5 };
|
int arr[2] = {4, 5};
|
||||||
|
|
||||||
const multi_span<int, 2> av(arr, 2);
|
const multi_span<int, 2> av(arr, 2);
|
||||||
multi_span<const int, 2> av2{ av };
|
multi_span<const int, 2> av2{av};
|
||||||
CHECK(av2[1] == 5);
|
CHECK(av2[1] == 5);
|
||||||
|
|
||||||
static_assert(std::is_convertible<const multi_span<int, 2>, multi_span<const int, 2>>::value, "ctor is not implicit!");
|
static_assert(
|
||||||
|
std::is_convertible<const multi_span<int, 2>, multi_span<const int, 2>>::value,
|
||||||
|
"ctor is not implicit!");
|
||||||
|
|
||||||
const strided_span<int, 1> src{ arr, {2, 1} };
|
const strided_span<int, 1> src{arr, {2, 1}};
|
||||||
strided_span<const int, 1> sav{ src };
|
strided_span<const int, 1> sav{src};
|
||||||
CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
|
CHECK(sav.bounds().index_bounds() == index<1>{2});
|
||||||
CHECK(sav.bounds().stride() == 1);
|
CHECK(sav.bounds().stride() == 1);
|
||||||
CHECK(sav[1] == 5);
|
CHECK(sav[1] == 5);
|
||||||
|
|
||||||
static_assert(std::is_convertible<const strided_span<int, 1>, strided_span<const int, 1>>::value, "ctor is not implicit!");
|
static_assert(
|
||||||
|
std::is_convertible<const strided_span<int, 1>, strided_span<const int, 1>>::value,
|
||||||
|
"ctor is not implicit!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check copy constructor
|
// Check copy constructor
|
||||||
{
|
{
|
||||||
int arr1[2] = { 3, 4 };
|
int arr1[2] = {3, 4};
|
||||||
const strided_span<int, 1> src1{ arr1, {2, 1} };
|
const strided_span<int, 1> src1{arr1, {2, 1}};
|
||||||
strided_span<int, 1> sav1{ src1 };
|
strided_span<int, 1> sav1{src1};
|
||||||
|
|
||||||
CHECK(sav1.bounds().index_bounds() == index<1>{ 2 });
|
CHECK(sav1.bounds().index_bounds() == index<1>{2});
|
||||||
CHECK(sav1.bounds().stride() == 1);
|
CHECK(sav1.bounds().stride() == 1);
|
||||||
CHECK(sav1[0] == 3);
|
CHECK(sav1[0] == 3);
|
||||||
|
|
||||||
int arr2[6] = { 1, 2, 3, 4, 5, 6 };
|
int arr2[6] = {1, 2, 3, 4, 5, 6};
|
||||||
const strided_span<const int, 2> src2{ arr2, {{ 3, 2 }, { 2, 1 }} };
|
const strided_span<const int, 2> src2{arr2, {{3, 2}, {2, 1}}};
|
||||||
strided_span<const int, 2> sav2{ src2 };
|
strided_span<const int, 2> sav2{src2};
|
||||||
CHECK((sav2.bounds().index_bounds() == index<2>{ 3, 2 }));
|
CHECK((sav2.bounds().index_bounds() == index<2>{3, 2}));
|
||||||
CHECK((sav2.bounds().strides() == index<2>{ 2, 1 }));
|
CHECK((sav2.bounds().strides() == index<2>{2, 1}));
|
||||||
CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5));
|
CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check const-casting assignment operator
|
// Check const-casting assignment operator
|
||||||
{
|
{
|
||||||
int arr1[2] = { 1, 2 };
|
int arr1[2] = {1, 2};
|
||||||
int arr2[6] = { 3, 4, 5, 6, 7, 8 };
|
int arr2[6] = {3, 4, 5, 6, 7, 8};
|
||||||
|
|
||||||
const strided_span<int, 1> src{ arr1, {{2}, {1}} };
|
const strided_span<int, 1> src{arr1, {{2}, {1}}};
|
||||||
strided_span<const int, 1> sav{ arr2, {{3}, {2}} };
|
strided_span<const int, 1> sav{arr2, {{3}, {2}}};
|
||||||
strided_span<const int, 1>& sav_ref = (sav = src);
|
strided_span<const int, 1>& sav_ref = (sav = src);
|
||||||
CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
|
CHECK(sav.bounds().index_bounds() == index<1>{2});
|
||||||
CHECK(sav.bounds().strides() == index<1>{ 1 });
|
CHECK(sav.bounds().strides() == index<1>{1});
|
||||||
CHECK(sav[0] == 1);
|
CHECK(sav[0] == 1);
|
||||||
CHECK(&sav_ref == &sav);
|
CHECK(&sav_ref == &sav);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check copy assignment operator
|
// Check copy assignment operator
|
||||||
{
|
{
|
||||||
int arr1[2] = { 3, 4 };
|
int arr1[2] = {3, 4};
|
||||||
int arr1b[1] = { 0 };
|
int arr1b[1] = {0};
|
||||||
const strided_span<int, 1> src1{ arr1, {2, 1} };
|
const strided_span<int, 1> src1{arr1, {2, 1}};
|
||||||
strided_span<int, 1> sav1{ arr1b, {1, 1} };
|
strided_span<int, 1> sav1{arr1b, {1, 1}};
|
||||||
strided_span<int, 1>& sav1_ref = (sav1 = src1);
|
strided_span<int, 1>& sav1_ref = (sav1 = src1);
|
||||||
CHECK(sav1.bounds().index_bounds() == index<1>{ 2 });
|
CHECK(sav1.bounds().index_bounds() == index<1>{2});
|
||||||
CHECK(sav1.bounds().strides() == index<1>{ 1 });
|
CHECK(sav1.bounds().strides() == index<1>{1});
|
||||||
CHECK(sav1[0] == 3);
|
CHECK(sav1[0] == 3);
|
||||||
CHECK(&sav1_ref == &sav1);
|
CHECK(&sav1_ref == &sav1);
|
||||||
|
|
||||||
const int arr2[6] = { 1, 2, 3, 4, 5, 6 };
|
const int arr2[6] = {1, 2, 3, 4, 5, 6};
|
||||||
const int arr2b[1] = { 0 };
|
const int arr2b[1] = {0};
|
||||||
const strided_span<const int, 2> src2{ arr2, {{ 3, 2 },{ 2, 1 }} };
|
const strided_span<const int, 2> src2{arr2, {{3, 2}, {2, 1}}};
|
||||||
strided_span<const int, 2> sav2{ arr2b, {{ 1, 1 },{ 1, 1 }} };
|
strided_span<const int, 2> sav2{arr2b, {{1, 1}, {1, 1}}};
|
||||||
strided_span<const int, 2>& sav2_ref = (sav2 = src2);
|
strided_span<const int, 2>& sav2_ref = (sav2 = src2);
|
||||||
CHECK((sav2.bounds().index_bounds() == index<2>{ 3, 2 }));
|
CHECK((sav2.bounds().index_bounds() == index<2>{3, 2}));
|
||||||
CHECK((sav2.bounds().strides() == index<2>{ 2, 1 }));
|
CHECK((sav2.bounds().strides() == index<2>{2, 1}));
|
||||||
CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5));
|
CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5));
|
||||||
CHECK(&sav2_ref == &sav2);
|
CHECK(&sav2_ref == &sav2);
|
||||||
}
|
}
|
||||||
@ -258,13 +272,15 @@ SUITE(strided_span_tests)
|
|||||||
{
|
{
|
||||||
std::vector<int> data(5 * 10);
|
std::vector<int> data(5 * 10);
|
||||||
std::iota(begin(data), end(data), 0);
|
std::iota(begin(data), end(data), 0);
|
||||||
const multi_span<int, 5, 10> src = as_multi_span(multi_span<int>{data}, dim<5>(), dim<10>());
|
const multi_span<int, 5, 10> src =
|
||||||
|
as_multi_span(multi_span<int>{data}, dim<5>(), dim<10>());
|
||||||
|
|
||||||
const strided_span<int, 2> sav{ src, {{5, 10}, {10, 1}} };
|
const strided_span<int, 2> sav{src, {{5, 10}, {10, 1}}};
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
const strided_span<const int, 2> csav{ {src},{ { 5, 10 },{ 10, 1 } } };
|
const strided_span<const int, 2> csav{{src}, {{5, 10}, {10, 1}}};
|
||||||
#endif
|
#endif
|
||||||
const strided_span<const int, 2> csav{ multi_span<const int, 5, 10>{ src }, { { 5, 10 },{ 10, 1 } } };
|
const strided_span<const int, 2> csav{multi_span<const int, 5, 10>{src},
|
||||||
|
{{5, 10}, {10, 1}}};
|
||||||
|
|
||||||
strided_span<int, 1> sav_sl = sav[2];
|
strided_span<int, 1> sav_sl = sav[2];
|
||||||
CHECK(sav_sl[0] == 20);
|
CHECK(sav_sl[0] == 20);
|
||||||
@ -284,12 +300,8 @@ SUITE(strided_span_tests)
|
|||||||
// use cases, such as column-major multidimensional array
|
// use cases, such as column-major multidimensional array
|
||||||
// (aka. "FORTRAN" layout).
|
// (aka. "FORTRAN" layout).
|
||||||
|
|
||||||
int cm_array[3 * 5] = {
|
int cm_array[3 * 5] = {1, 4, 7, 10, 13, 2, 5, 8, 11, 14, 3, 6, 9, 12, 15};
|
||||||
1, 4, 7, 10, 13,
|
strided_span<int, 2> cm_sav{cm_array, {{5, 3}, {1, 5}}};
|
||||||
2, 5, 8, 11, 14,
|
|
||||||
3, 6, 9, 12, 15
|
|
||||||
};
|
|
||||||
strided_span<int, 2> cm_sav{ cm_array, {{ 5, 3 },{ 1, 5 }} };
|
|
||||||
|
|
||||||
// Accessing elements
|
// Accessing elements
|
||||||
CHECK((cm_sav[{0, 0}] == 1));
|
CHECK((cm_sav[{0, 0}] == 1));
|
||||||
@ -305,7 +317,7 @@ SUITE(strided_span_tests)
|
|||||||
CHECK(cm_sl[2] == 12);
|
CHECK(cm_sl[2] == 12);
|
||||||
|
|
||||||
// Section
|
// Section
|
||||||
strided_span<int, 2> cm_sec = cm_sav.section( { 2, 1 }, { 3, 2 });
|
strided_span<int, 2> cm_sec = cm_sav.section({2, 1}, {3, 2});
|
||||||
|
|
||||||
CHECK((cm_sec.bounds().index_bounds() == index<2>{3, 2}));
|
CHECK((cm_sec.bounds().index_bounds() == index<2>{3, 2}));
|
||||||
CHECK((cm_sec[{0, 0}] == 8));
|
CHECK((cm_sec[{0, 0}] == 8));
|
||||||
@ -316,7 +328,7 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
TEST(strided_span_bounds)
|
TEST(strided_span_bounds)
|
||||||
{
|
{
|
||||||
int arr[] = { 0, 1, 2, 3 };
|
int arr[] = {0, 1, 2, 3};
|
||||||
multi_span<int> av(arr);
|
multi_span<int> av(arr);
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -335,7 +347,7 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
{
|
{
|
||||||
// zero stride
|
// zero stride
|
||||||
strided_span<int, 1> sav{ av,{ { 4 },{} } };
|
strided_span<int, 1> sav{av, {{4}, {}}};
|
||||||
CHECK(sav[0] == 0);
|
CHECK(sav[0] == 0);
|
||||||
CHECK(sav[3] == 0);
|
CHECK(sav[3] == 0);
|
||||||
CHECK_THROW(sav[4], fail_fast);
|
CHECK_THROW(sav[4], fail_fast);
|
||||||
@ -343,36 +355,36 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
{
|
{
|
||||||
// zero extent
|
// zero extent
|
||||||
strided_span<int, 1> sav{ av,{ {},{ 1 } } };
|
strided_span<int, 1> sav{av, {{}, {1}}};
|
||||||
CHECK_THROW(sav[0], fail_fast);
|
CHECK_THROW(sav[0], fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// zero extent and stride
|
// zero extent and stride
|
||||||
strided_span<int, 1> sav{ av,{ {},{} } };
|
strided_span<int, 1> sav{av, {{}, {}}};
|
||||||
CHECK_THROW(sav[0], fail_fast);
|
CHECK_THROW(sav[0], fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// strided array ctor with matching strided bounds
|
// strided array ctor with matching strided bounds
|
||||||
strided_span<int, 1> sav{ arr,{ 4, 1 } };
|
strided_span<int, 1> sav{arr, {4, 1}};
|
||||||
CHECK(sav.bounds().index_bounds() == index<1>{ 4 });
|
CHECK(sav.bounds().index_bounds() == index<1>{4});
|
||||||
CHECK(sav[3] == 3);
|
CHECK(sav[3] == 3);
|
||||||
CHECK_THROW(sav[4], fail_fast);
|
CHECK_THROW(sav[4], fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// strided array ctor with smaller strided bounds
|
// strided array ctor with smaller strided bounds
|
||||||
strided_span<int, 1> sav{ arr,{ 2, 1 } };
|
strided_span<int, 1> sav{arr, {2, 1}};
|
||||||
CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
|
CHECK(sav.bounds().index_bounds() == index<1>{2});
|
||||||
CHECK(sav[1] == 1);
|
CHECK(sav[1] == 1);
|
||||||
CHECK_THROW(sav[2], fail_fast);
|
CHECK_THROW(sav[2], fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// strided array ctor with fitting irregular bounds
|
// strided array ctor with fitting irregular bounds
|
||||||
strided_span<int, 1> sav{ arr,{ 2, 3 } };
|
strided_span<int, 1> sav{arr, {2, 3}};
|
||||||
CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
|
CHECK(sav.bounds().index_bounds() == index<1>{2});
|
||||||
CHECK(sav[0] == 0);
|
CHECK(sav[0] == 0);
|
||||||
CHECK(sav[1] == 3);
|
CHECK(sav[1] == 3);
|
||||||
CHECK_THROW(sav[2], fail_fast);
|
CHECK_THROW(sav[2], fail_fast);
|
||||||
@ -380,68 +392,69 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
{
|
{
|
||||||
// bounds cross data boundaries - from static arrays
|
// bounds cross data boundaries - from static arrays
|
||||||
CHECK_THROW((strided_span<int, 1> { arr, { 3, 2 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{arr, {3, 2}}), fail_fast);
|
||||||
CHECK_THROW((strided_span<int, 1> { arr, { 3, 3 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{arr, {3, 3}}), fail_fast);
|
||||||
CHECK_THROW((strided_span<int, 1> { arr, { 4, 5 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{arr, {4, 5}}), fail_fast);
|
||||||
CHECK_THROW((strided_span<int, 1> { arr, { 5, 1 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{arr, {5, 1}}), fail_fast);
|
||||||
CHECK_THROW((strided_span<int, 1> { arr, { 5, 5 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{arr, {5, 5}}), fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// bounds cross data boundaries - from array view
|
// bounds cross data boundaries - from array view
|
||||||
CHECK_THROW((strided_span<int, 1> { av, { 3, 2 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{av, {3, 2}}), fail_fast);
|
||||||
CHECK_THROW((strided_span<int, 1> { av, { 3, 3 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{av, {3, 3}}), fail_fast);
|
||||||
CHECK_THROW((strided_span<int, 1> { av, { 4, 5 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{av, {4, 5}}), fail_fast);
|
||||||
CHECK_THROW((strided_span<int, 1> { av, { 5, 1 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{av, {5, 1}}), fail_fast);
|
||||||
CHECK_THROW((strided_span<int, 1> { av, { 5, 5 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{av, {5, 5}}), fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// bounds cross data boundaries - from dynamic arrays
|
// bounds cross data boundaries - from dynamic arrays
|
||||||
CHECK_THROW((strided_span<int, 1> { av.data(), 4, { 3, 2 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{av.data(), 4, {3, 2}}), fail_fast);
|
||||||
CHECK_THROW((strided_span<int, 1> { av.data(), 4, { 3, 3 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{av.data(), 4, {3, 3}}), fail_fast);
|
||||||
CHECK_THROW((strided_span<int, 1> { av.data(), 4, { 4, 5 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{av.data(), 4, {4, 5}}), fail_fast);
|
||||||
CHECK_THROW((strided_span<int, 1> { av.data(), 4, { 5, 1 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{av.data(), 4, {5, 1}}), fail_fast);
|
||||||
CHECK_THROW((strided_span<int, 1> { av.data(), 4, { 5, 5 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{av.data(), 4, {5, 5}}), fail_fast);
|
||||||
CHECK_THROW((strided_span<int, 1> { av.data(), 2, { 2, 2 } }), fail_fast);
|
CHECK_THROW((strided_span<int, 1>{av.data(), 2, {2, 2}}), fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
strided_span<int, 1> sav0{ av.data(), { 3, 2 } };
|
strided_span<int, 1> sav0{av.data(), {3, 2}};
|
||||||
strided_span<int, 1> sav1{ arr, { 1 } };
|
strided_span<int, 1> sav1{arr, {1}};
|
||||||
strided_span<int, 1> sav2{ arr, { 1,1,1 } };
|
strided_span<int, 1> sav2{arr, {1, 1, 1}};
|
||||||
strided_span<int, 1> sav3{ av, { 1 } };
|
strided_span<int, 1> sav3{av, {1}};
|
||||||
strided_span<int, 1> sav4{ av, { 1,1,1 } };
|
strided_span<int, 1> sav4{av, {1, 1, 1}};
|
||||||
strided_span<int, 2> sav5{ av.as_multi_span(dim<2>(), dim<2>()), { 1 } };
|
strided_span<int, 2> sav5{av.as_multi_span(dim<2>(), dim<2>()), {1}};
|
||||||
strided_span<int, 2> sav6{ av.as_multi_span(dim<2>(), dim<2>()), { 1,1,1 } };
|
strided_span<int, 2> sav6{av.as_multi_span(dim<2>(), dim<2>()), {1, 1, 1}};
|
||||||
strided_span<int, 2> sav7{ av.as_multi_span(dim<2>(), dim<2>()), { { 1,1 },{ 1,1 },{ 1,1 } } };
|
strided_span<int, 2> sav7{av.as_multi_span(dim<2>(), dim<2>()),
|
||||||
|
{{1, 1}, {1, 1}, {1, 1}}};
|
||||||
|
|
||||||
index<1> index{ 0, 1 };
|
index<1> index{0, 1};
|
||||||
strided_span<int, 1> sav8{ arr,{ 1,{ 1,1 } } };
|
strided_span<int, 1> sav8{arr, {1, {1, 1}}};
|
||||||
strided_span<int, 1> sav9{ arr,{ { 1,1 },{ 1,1 } } };
|
strided_span<int, 1> sav9{arr, {{1, 1}, {1, 1}}};
|
||||||
strided_span<int, 1> sav10{ av,{ 1,{ 1,1 } } };
|
strided_span<int, 1> sav10{av, {1, {1, 1}}};
|
||||||
strided_span<int, 1> sav11{ av,{ { 1,1 },{ 1,1 } } };
|
strided_span<int, 1> sav11{av, {{1, 1}, {1, 1}}};
|
||||||
strided_span<int, 2> sav12{ av.as_multi_span(dim<2>(), dim<2>()),{ { 1 },{ 1 } } };
|
strided_span<int, 2> sav12{av.as_multi_span(dim<2>(), dim<2>()), {{1}, {1}}};
|
||||||
strided_span<int, 2> sav13{ av.as_multi_span(dim<2>(), dim<2>()),{ { 1 },{ 1,1,1 } } };
|
strided_span<int, 2> sav13{av.as_multi_span(dim<2>(), dim<2>()), {{1}, {1, 1, 1}}};
|
||||||
strided_span<int, 2> sav14{ av.as_multi_span(dim<2>(), dim<2>()),{ { 1,1,1 },{ 1 } } };
|
strided_span<int, 2> sav14{av.as_multi_span(dim<2>(), dim<2>()), {{1, 1, 1}, {1}}};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(strided_span_type_conversion)
|
TEST(strided_span_type_conversion)
|
||||||
{
|
{
|
||||||
int arr[] = { 0, 1, 2, 3 };
|
int arr[] = {0, 1, 2, 3};
|
||||||
multi_span<int> av(arr);
|
multi_span<int> av(arr);
|
||||||
|
|
||||||
{
|
{
|
||||||
strided_span<int, 1> sav{ av.data(), av.size(), { av.size() / 2, 2 } };
|
strided_span<int, 1> sav{av.data(), av.size(), {av.size() / 2, 2}};
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
strided_span<long, 1> lsav1 = sav.as_strided_span<long, 1>();
|
strided_span<long, 1> lsav1 = sav.as_strided_span<long, 1>();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
strided_span<int, 1> sav{ av, { av.size() / 2, 2 } };
|
strided_span<int, 1> sav{av, {av.size() / 2, 2}};
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
strided_span<long, 1> lsav1 = sav.as_strided_span<long, 1>();
|
strided_span<long, 1> lsav1 = sav.as_strided_span<long, 1>();
|
||||||
#endif
|
#endif
|
||||||
@ -451,8 +464,8 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
// retype strided array with regular strides - from raw data
|
// retype strided array with regular strides - from raw data
|
||||||
{
|
{
|
||||||
strided_bounds<2> bounds{ { 2, bytes.size() / 4 }, { bytes.size() / 2, 1 } };
|
strided_bounds<2> bounds{{2, bytes.size() / 4}, {bytes.size() / 2, 1}};
|
||||||
strided_span<const byte, 2> sav2{ bytes.data(), bytes.size(), bounds };
|
strided_span<const byte, 2> sav2{bytes.data(), bytes.size(), bounds};
|
||||||
strided_span<const int, 2> sav3 = sav2.as_strided_span<const int>();
|
strided_span<const int, 2> sav3 = sav2.as_strided_span<const int>();
|
||||||
CHECK(sav3[0][0] == 0);
|
CHECK(sav3[0][0] == 0);
|
||||||
CHECK(sav3[1][0] == 2);
|
CHECK(sav3[1][0] == 2);
|
||||||
@ -462,9 +475,10 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
// retype strided array with regular strides - from multi_span
|
// retype strided array with regular strides - from multi_span
|
||||||
{
|
{
|
||||||
strided_bounds<2> bounds{ { 2, bytes.size() / 4 }, { bytes.size() / 2, 1 } };
|
strided_bounds<2> bounds{{2, bytes.size() / 4}, {bytes.size() / 2, 1}};
|
||||||
multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
multi_span<const byte, 2, dynamic_range> bytes2 =
|
||||||
strided_span<const byte, 2> sav2{ bytes2, bounds };
|
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||||
|
strided_span<const byte, 2> sav2{bytes2, bounds};
|
||||||
strided_span<int, 2> sav3 = sav2.as_strided_span<int>();
|
strided_span<int, 2> sav3 = sav2.as_strided_span<int>();
|
||||||
CHECK(sav3[0][0] == 0);
|
CHECK(sav3[0][0] == 0);
|
||||||
CHECK(sav3[1][0] == 2);
|
CHECK(sav3[1][0] == 2);
|
||||||
@ -474,47 +488,53 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
// retype strided array with not enough elements - last dimension of the array is too small
|
// retype strided array with not enough elements - last dimension of the array is too small
|
||||||
{
|
{
|
||||||
strided_bounds<2> bounds{ { 4,2 },{ 4, 1 } };
|
strided_bounds<2> bounds{{4, 2}, {4, 1}};
|
||||||
multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
multi_span<const byte, 2, dynamic_range> bytes2 =
|
||||||
strided_span<const byte, 2> sav2{ bytes2, bounds };
|
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||||
|
strided_span<const byte, 2> sav2{bytes2, bounds};
|
||||||
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
|
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
// retype strided array with not enough elements - strides are too small
|
// retype strided array with not enough elements - strides are too small
|
||||||
{
|
{
|
||||||
strided_bounds<2> bounds{ { 4,2 },{ 2, 1 } };
|
strided_bounds<2> bounds{{4, 2}, {2, 1}};
|
||||||
multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
multi_span<const byte, 2, dynamic_range> bytes2 =
|
||||||
strided_span<const byte, 2> sav2{ bytes2, bounds };
|
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||||
|
strided_span<const byte, 2> sav2{bytes2, bounds};
|
||||||
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
|
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
// retype strided array with not enough elements - last dimension does not divide by the new typesize
|
// retype strided array with not enough elements - last dimension does not divide by the new
|
||||||
|
// typesize
|
||||||
{
|
{
|
||||||
strided_bounds<2> bounds{ { 2,6 },{ 4, 1 } };
|
strided_bounds<2> bounds{{2, 6}, {4, 1}};
|
||||||
multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
multi_span<const byte, 2, dynamic_range> bytes2 =
|
||||||
strided_span<const byte, 2> sav2{ bytes2, bounds };
|
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||||
|
strided_span<const byte, 2> sav2{bytes2, bounds};
|
||||||
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
|
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
// retype strided array with not enough elements - strides does not divide by the new typesize
|
// retype strided array with not enough elements - strides does not divide by the new
|
||||||
|
// typesize
|
||||||
{
|
{
|
||||||
strided_bounds<2> bounds{ { 2, 1 },{ 6, 1 } };
|
strided_bounds<2> bounds{{2, 1}, {6, 1}};
|
||||||
multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
multi_span<const byte, 2, dynamic_range> bytes2 =
|
||||||
strided_span<const byte, 2> sav2{ bytes2, bounds };
|
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||||
|
strided_span<const byte, 2> sav2{bytes2, bounds};
|
||||||
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
|
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
// retype strided array with irregular strides - from raw data
|
// retype strided array with irregular strides - from raw data
|
||||||
{
|
{
|
||||||
strided_bounds<1> bounds{ bytes.size() / 2, 2 };
|
strided_bounds<1> bounds{bytes.size() / 2, 2};
|
||||||
strided_span<const byte, 1> sav2{ bytes.data(), bytes.size(), bounds };
|
strided_span<const byte, 1> sav2{bytes.data(), bytes.size(), bounds};
|
||||||
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
|
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
// retype strided array with irregular strides - from multi_span
|
// retype strided array with irregular strides - from multi_span
|
||||||
{
|
{
|
||||||
strided_bounds<1> bounds{ bytes.size() / 2, 2 };
|
strided_bounds<1> bounds{bytes.size() / 2, 2};
|
||||||
strided_span<const byte, 1> sav2{ bytes, bounds };
|
strided_span<const byte, 1> sav2{bytes, bounds};
|
||||||
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
|
CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -523,31 +543,29 @@ SUITE(strided_span_tests)
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
multi_span<int, 0> empty_av(nullptr);
|
multi_span<int, 0> empty_av(nullptr);
|
||||||
strided_span<int, 1> empty_sav{ empty_av, { 0, 1 } };
|
strided_span<int, 1> empty_sav{empty_av, {0, 1}};
|
||||||
|
|
||||||
CHECK(empty_sav.bounds().index_bounds() == index<1>{ 0 });
|
CHECK(empty_sav.bounds().index_bounds() == index<1>{0});
|
||||||
CHECK_THROW(empty_sav[0], fail_fast);
|
CHECK_THROW(empty_sav[0], fail_fast);
|
||||||
CHECK_THROW(empty_sav.begin()[0], fail_fast);
|
CHECK_THROW(empty_sav.begin()[0], fail_fast);
|
||||||
CHECK_THROW(empty_sav.cbegin()[0], fail_fast);
|
CHECK_THROW(empty_sav.cbegin()[0], fail_fast);
|
||||||
|
|
||||||
for (const auto& v : empty_sav)
|
for (const auto& v : empty_sav) {
|
||||||
{
|
(void) v;
|
||||||
(void)v;
|
|
||||||
CHECK(false);
|
CHECK(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
strided_span<int, 1> empty_sav{ nullptr, 0, { 0, 1 } };
|
strided_span<int, 1> empty_sav{nullptr, 0, {0, 1}};
|
||||||
|
|
||||||
CHECK(empty_sav.bounds().index_bounds() == index<1>{ 0 });
|
CHECK(empty_sav.bounds().index_bounds() == index<1>{0});
|
||||||
CHECK_THROW(empty_sav[0], fail_fast);
|
CHECK_THROW(empty_sav[0], fail_fast);
|
||||||
CHECK_THROW(empty_sav.begin()[0], fail_fast);
|
CHECK_THROW(empty_sav.begin()[0], fail_fast);
|
||||||
CHECK_THROW(empty_sav.cbegin()[0], fail_fast);
|
CHECK_THROW(empty_sav.cbegin()[0], fail_fast);
|
||||||
|
|
||||||
for (const auto& v : empty_sav)
|
for (const auto& v : empty_sav) {
|
||||||
{
|
(void) v;
|
||||||
(void)v;
|
|
||||||
CHECK(false);
|
CHECK(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -561,20 +579,18 @@ SUITE(strided_span_tests)
|
|||||||
#if _MSC_VER > 1800
|
#if _MSC_VER > 1800
|
||||||
auto bounds = strided_bounds<1>({length}, {2});
|
auto bounds = strided_bounds<1>({length}, {2});
|
||||||
#else
|
#else
|
||||||
auto bounds = strided_bounds<1>(index<1>{ length }, index<1>{ 2 });
|
auto bounds = strided_bounds<1>(index<1>{length}, index<1>{2});
|
||||||
#endif
|
#endif
|
||||||
strided_span<int, 1> strided(&av.data()[1], av.size() - 1, bounds);
|
strided_span<int, 1> strided(&av.data()[1], av.size() - 1, bounds);
|
||||||
|
|
||||||
CHECK(strided.size() == length);
|
CHECK(strided.size() == length);
|
||||||
CHECK(strided.bounds().index_bounds()[0] == length);
|
CHECK(strided.bounds().index_bounds()[0] == length);
|
||||||
for (auto i = 0; i < strided.size(); ++i)
|
for (auto i = 0; i < strided.size(); ++i) {
|
||||||
{
|
|
||||||
CHECK(strided[i] == av[2 * i + 1]);
|
CHECK(strided[i] == av[2 * i + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (auto num : strided)
|
for (auto num : strided) {
|
||||||
{
|
|
||||||
CHECK(num == av[2 * idx + 1]);
|
CHECK(num == av[2 * idx + 1]);
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
@ -582,7 +598,7 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
TEST(strided_span_section_iteration)
|
TEST(strided_span_section_iteration)
|
||||||
{
|
{
|
||||||
int arr[8] = {4,0,5,1,6,2,7,3};
|
int arr[8] = {4, 0, 5, 1, 6, 2, 7, 3};
|
||||||
|
|
||||||
// static bounds
|
// static bounds
|
||||||
{
|
{
|
||||||
@ -600,8 +616,7 @@ SUITE(strided_span_tests)
|
|||||||
TEST(dynamic_strided_span_section_iteration)
|
TEST(dynamic_strided_span_section_iteration)
|
||||||
{
|
{
|
||||||
auto arr = new int[8];
|
auto arr = new int[8];
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i) {
|
||||||
{
|
|
||||||
arr[2 * i] = 4 + i;
|
arr[2 * i] = 4 + i;
|
||||||
arr[2 * i + 1] = i;
|
arr[2 * i + 1] = i;
|
||||||
}
|
}
|
||||||
@ -614,29 +629,25 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
void iterate_second_slice(multi_span<int, dynamic_range, dynamic_range, dynamic_range> av)
|
void iterate_second_slice(multi_span<int, dynamic_range, dynamic_range, dynamic_range> av)
|
||||||
{
|
{
|
||||||
const int expected[6] = {2,3,10,11,18,19};
|
const int expected[6] = {2, 3, 10, 11, 18, 19};
|
||||||
auto section = av.section({0,1,0}, {3,1,2});
|
auto section = av.section({0, 1, 0}, {3, 1, 2});
|
||||||
|
|
||||||
for (auto i = 0; i < section.extent<0>(); ++i)
|
for (auto i = 0; i < section.extent<0>(); ++i) {
|
||||||
{
|
|
||||||
for (auto j = 0; j < section.extent<1>(); ++j)
|
for (auto j = 0; j < section.extent<1>(); ++j)
|
||||||
for (auto k = 0; k < section.extent<2>(); ++k)
|
for (auto k = 0; k < section.extent<2>(); ++k) {
|
||||||
{
|
auto idx = index<3>{i, j, k}; // avoid braces in the CHECK macro
|
||||||
auto idx = index<3>{i,j,k}; // avoid braces in the CHECK macro
|
|
||||||
CHECK(section[idx] == expected[2 * i + 2 * j + k]);
|
CHECK(section[idx] == expected[2 * i + 2 * j + k]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto i = 0; i < section.extent<0>(); ++i)
|
for (auto i = 0; i < section.extent<0>(); ++i) {
|
||||||
{
|
|
||||||
for (auto j = 0; j < section.extent<1>(); ++j)
|
for (auto j = 0; j < section.extent<1>(); ++j)
|
||||||
for (auto k = 0; k < section.extent<2>(); ++k)
|
for (auto k = 0; k < section.extent<2>(); ++k)
|
||||||
CHECK(section[i][j][k] == expected[2 * i + 2 * j + k]);
|
CHECK(section[i][j][k] == expected[2 * i + 2 * j + k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const auto num : section)
|
for (const auto num : section) {
|
||||||
{
|
|
||||||
CHECK(num == expected[i]);
|
CHECK(num == expected[i]);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -645,11 +656,9 @@ SUITE(strided_span_tests)
|
|||||||
TEST(strided_span_section_iteration_3d)
|
TEST(strided_span_section_iteration_3d)
|
||||||
{
|
{
|
||||||
int arr[3][4][2]{};
|
int arr[3][4][2]{};
|
||||||
for (auto i = 0; i < 3; ++i)
|
for (auto i = 0; i < 3; ++i) {
|
||||||
{
|
|
||||||
for (auto j = 0; j < 4; ++j)
|
for (auto j = 0; j < 4; ++j)
|
||||||
for (auto k = 0; k < 2; ++k)
|
for (auto k = 0; k < 2; ++k) arr[i][j][k] = 8 * i + 2 * j + k;
|
||||||
arr[i][j][k] = 8 * i + 2 * j + k;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -664,8 +673,7 @@ SUITE(strided_span_tests)
|
|||||||
const auto size = height * width;
|
const auto size = height * width;
|
||||||
|
|
||||||
auto arr = new int[static_cast<std::size_t>(size)];
|
auto arr = new int[static_cast<std::size_t>(size)];
|
||||||
for (auto i = 0; i < size; ++i)
|
for (auto i = 0; i < size; ++i) {
|
||||||
{
|
|
||||||
arr[i] = i;
|
arr[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -695,9 +703,14 @@ SUITE(strided_span_tests)
|
|||||||
{
|
{
|
||||||
// get an multi_span of 'c' values from the list of X's
|
// get an multi_span of 'c' values from the list of X's
|
||||||
|
|
||||||
struct X { int a; int b; int c; };
|
struct X
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
int b;
|
||||||
|
int c;
|
||||||
|
};
|
||||||
|
|
||||||
X arr[4] = {{0,1,2},{3,4,5},{6,7,8},{9,10,11}};
|
X arr[4] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}};
|
||||||
|
|
||||||
int s = sizeof(int) / sizeof(byte);
|
int s = sizeof(int) / sizeof(byte);
|
||||||
auto d2 = 3 * s;
|
auto d2 = 3 * s;
|
||||||
@ -710,7 +723,9 @@ SUITE(strided_span_tests)
|
|||||||
CHECK(av.bounds().index_bounds()[1] == 12);
|
CHECK(av.bounds().index_bounds()[1] == 12);
|
||||||
|
|
||||||
// get the last 4 columns
|
// get the last 4 columns
|
||||||
auto section = av.section({0, 2 * s}, {4, s}); // { { arr[0].c[0], arr[0].c[1], arr[0].c[2], arr[0].c[3] } , { arr[1].c[0], ... } , ... }
|
auto section = av.section({0, 2 * s}, {4, s}); // { { arr[0].c[0], arr[0].c[1], arr[0].c[2],
|
||||||
|
// arr[0].c[3] } , { arr[1].c[0], ... } , ...
|
||||||
|
// }
|
||||||
|
|
||||||
// convert to array 4x1 array of integers
|
// convert to array 4x1 array of integers
|
||||||
auto cs = section.as_strided_span<int>(); // { { arr[0].c }, {arr[1].c } , ... }
|
auto cs = section.as_strided_span<int>(); // { { arr[0].c }, {arr[1].c } , ... }
|
||||||
@ -720,9 +735,8 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
// transpose to 1x4 array
|
// transpose to 1x4 array
|
||||||
strided_bounds<2> reverse_bounds{
|
strided_bounds<2> reverse_bounds{
|
||||||
{cs.bounds().index_bounds()[1] , cs.bounds().index_bounds()[0]},
|
{cs.bounds().index_bounds()[1], cs.bounds().index_bounds()[0]},
|
||||||
{cs.bounds().strides()[1], cs.bounds().strides()[0]}
|
{cs.bounds().strides()[1], cs.bounds().strides()[0]}};
|
||||||
};
|
|
||||||
|
|
||||||
strided_span<int, 2> transposed{cs.data(), cs.bounds().total_size(), reverse_bounds};
|
strided_span<int, 2> transposed{cs.data(), cs.bounds().total_size(), reverse_bounds};
|
||||||
|
|
||||||
@ -733,16 +747,11 @@ SUITE(strided_span_tests)
|
|||||||
CHECK_THROW(result.bounds().index_bounds()[1], fail_fast);
|
CHECK_THROW(result.bounds().index_bounds()[1], fail_fast);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (auto& num : result)
|
for (auto& num : result) {
|
||||||
{
|
|
||||||
CHECK(num == arr[i].c);
|
CHECK(num == arr[i].c);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int, const char *[])
|
int main(int, const char* []) { return UnitTest::RunAllTests(); }
|
||||||
{
|
|
||||||
return UnitTest::RunAllTests();
|
|
||||||
}
|
|
||||||
|
@ -15,16 +15,17 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <UnitTest++/UnitTest++.h>
|
#include <UnitTest++/UnitTest++.h>
|
||||||
#include <cstdlib>
|
|
||||||
#include <gsl/string_span>
|
|
||||||
#include <gsl/gsl> //owner
|
#include <gsl/gsl> //owner
|
||||||
#include <vector>
|
#include <gsl/string_span>
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
|
|
||||||
|
|
||||||
SUITE(string_span_tests)
|
SUITE(string_span_tests)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ SUITE(string_span_tests)
|
|||||||
TEST(TestConstructFromStdVector)
|
TEST(TestConstructFromStdVector)
|
||||||
{
|
{
|
||||||
std::vector<char> vec(5, 'h');
|
std::vector<char> vec(5, 'h');
|
||||||
string_span<> v {vec};
|
string_span<> v{vec};
|
||||||
CHECK(v.length() == static_cast<string_span<>::index_type>(vec.size()));
|
CHECK(v.length() == static_cast<string_span<>::index_type>(vec.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +97,7 @@ SUITE(string_span_tests)
|
|||||||
{
|
{
|
||||||
char stack_string[] = "Hello";
|
char stack_string[] = "Hello";
|
||||||
cstring_span<> v = ensure_z(stack_string);
|
cstring_span<> v = ensure_z(stack_string);
|
||||||
(void)v;
|
(void) v;
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
string_span<> v2 = v;
|
string_span<> v2 = v;
|
||||||
string_span<> v3 = "Hello";
|
string_span<> v3 = "Hello";
|
||||||
@ -117,12 +118,13 @@ SUITE(string_span_tests)
|
|||||||
|
|
||||||
TEST(TestToBasicString)
|
TEST(TestToBasicString)
|
||||||
{
|
{
|
||||||
auto s = gsl::to_basic_string<char,std::char_traits<char>,::std::allocator<char>>(cstring_span<>{});
|
auto s = gsl::to_basic_string<char, std::char_traits<char>, ::std::allocator<char>>(
|
||||||
|
cstring_span<>{});
|
||||||
CHECK(s.length() == 0);
|
CHECK(s.length() == 0);
|
||||||
|
|
||||||
char stack_string[] = "Hello";
|
char stack_string[] = "Hello";
|
||||||
cstring_span<> v = ensure_z(stack_string);
|
cstring_span<> v = ensure_z(stack_string);
|
||||||
auto s2 = gsl::to_basic_string<char,std::char_traits<char>,::std::allocator<char>>(v);
|
auto s2 = gsl::to_basic_string<char, std::char_traits<char>, ::std::allocator<char>>(v);
|
||||||
CHECK(static_cast<cstring_span<>::index_type>(s2.length()) == v.length());
|
CHECK(static_cast<cstring_span<>::index_type>(s2.length()) == v.length());
|
||||||
CHECK(s2.length() == 5);
|
CHECK(s2.length() == 5);
|
||||||
}
|
}
|
||||||
@ -150,12 +152,12 @@ SUITE(string_span_tests)
|
|||||||
{
|
{
|
||||||
cstring_span<> span = "Hello";
|
cstring_span<> span = "Hello";
|
||||||
|
|
||||||
const char ar[] = { 'H', 'e', 'l', 'l', 'o' };
|
const char ar[] = {'H', 'e', 'l', 'l', 'o'};
|
||||||
const char ar1[] = "Hello";
|
const char ar1[] = "Hello";
|
||||||
const char ar2[10] = "Hello";
|
const char ar2[10] = "Hello";
|
||||||
const char* ptr = "Hello";
|
const char* ptr = "Hello";
|
||||||
const std::string str = "Hello";
|
const std::string str = "Hello";
|
||||||
const std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
gsl::span<const char> sp = ensure_z("Hello");
|
gsl::span<const char> sp = ensure_z("Hello");
|
||||||
|
|
||||||
// comparison to literal
|
// comparison to literal
|
||||||
@ -187,7 +189,7 @@ SUITE(string_span_tests)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
char ar[] = { 'H', 'e', 'l', 'l', 'o' };
|
char ar[] = {'H', 'e', 'l', 'l', 'o'};
|
||||||
|
|
||||||
string_span<> span = ar;
|
string_span<> span = ar;
|
||||||
|
|
||||||
@ -195,7 +197,7 @@ SUITE(string_span_tests)
|
|||||||
char ar2[10] = "Hello";
|
char ar2[10] = "Hello";
|
||||||
char* ptr = ar;
|
char* ptr = ar;
|
||||||
std::string str = "Hello";
|
std::string str = "Hello";
|
||||||
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
gsl::span<char> sp = ensure_z(ar1);
|
gsl::span<char> sp = ensure_z(ar1);
|
||||||
|
|
||||||
// comparison to static array with no null termination
|
// comparison to static array with no null termination
|
||||||
@ -223,13 +225,12 @@ SUITE(string_span_tests)
|
|||||||
CHECK(span == span);
|
CHECK(span == span);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const char ar[] = { 'H', 'e', 'l', 'l', 'o' };
|
const char ar[] = {'H', 'e', 'l', 'l', 'o'};
|
||||||
const char ar1[] = "Hello";
|
const char ar1[] = "Hello";
|
||||||
const char ar2[10] = "Hello";
|
const char ar2[10] = "Hello";
|
||||||
const std::string str = "Hello";
|
const std::string str = "Hello";
|
||||||
const std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
const gsl::span<const char> sp = ensure_z("Hello");
|
const gsl::span<const char> sp = ensure_z("Hello");
|
||||||
|
|
||||||
cstring_span<> span = "Hello";
|
cstring_span<> span = "Hello";
|
||||||
@ -261,13 +262,13 @@ SUITE(string_span_tests)
|
|||||||
|
|
||||||
// const span, non-const other type
|
// const span, non-const other type
|
||||||
|
|
||||||
char _ar[] = { 'H', 'e', 'l', 'l', 'o' };
|
char _ar[] = {'H', 'e', 'l', 'l', 'o'};
|
||||||
char _ar1[] = "Hello";
|
char _ar1[] = "Hello";
|
||||||
char _ar2[10] = "Hello";
|
char _ar2[10] = "Hello";
|
||||||
char* _ptr = _ar;
|
char* _ptr = _ar;
|
||||||
std::string _str = "Hello";
|
std::string _str = "Hello";
|
||||||
std::vector<char> _vec = { 'H', 'e', 'l', 'l', 'o' };
|
std::vector<char> _vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
gsl::span<char> _sp{ _ar, 5 };
|
gsl::span<char> _sp{_ar, 5};
|
||||||
|
|
||||||
CHECK(span == _ar);
|
CHECK(span == _ar);
|
||||||
CHECK(span == _ar1);
|
CHECK(span == _ar1);
|
||||||
@ -289,7 +290,7 @@ SUITE(string_span_tests)
|
|||||||
CHECK(_vec == span);
|
CHECK(_vec == span);
|
||||||
CHECK(_sp == span);
|
CHECK(_sp == span);
|
||||||
|
|
||||||
string_span<> _span{ _ptr, 5 };
|
string_span<> _span{_ptr, 5};
|
||||||
|
|
||||||
// non-const span, non-const other type
|
// non-const span, non-const other type
|
||||||
|
|
||||||
@ -344,7 +345,7 @@ SUITE(string_span_tests)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::vector<char> str1 = { 'H', 'e', 'l', 'l', 'o' };
|
std::vector<char> str1 = {'H', 'e', 'l', 'l', 'o'};
|
||||||
cstring_span<> span1 = str1;
|
cstring_span<> span1 = str1;
|
||||||
std::vector<char> str2 = std::move(str1);
|
std::vector<char> str2 = std::move(str1);
|
||||||
cstring_span<> span2 = str2;
|
cstring_span<> span2 = str2;
|
||||||
@ -359,12 +360,12 @@ SUITE(string_span_tests)
|
|||||||
{
|
{
|
||||||
cstring_span<> span = "Hello";
|
cstring_span<> span = "Hello";
|
||||||
|
|
||||||
const char ar[] = { 'H', 'e', 'l', 'l', 'o' };
|
const char ar[] = {'H', 'e', 'l', 'l', 'o'};
|
||||||
const char ar1[] = "Hello";
|
const char ar1[] = "Hello";
|
||||||
const char ar2[10] = "Hello";
|
const char ar2[10] = "Hello";
|
||||||
const char* ptr = "Hello";
|
const char* ptr = "Hello";
|
||||||
const std::string str = "Hello";
|
const std::string str = "Hello";
|
||||||
const std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
|
|
||||||
// comparison to literal
|
// comparison to literal
|
||||||
CHECK(span < cstring_span<>("Helloo"));
|
CHECK(span < cstring_span<>("Helloo"));
|
||||||
@ -390,7 +391,7 @@ SUITE(string_span_tests)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
char ar[] = { 'H', 'e', 'l', 'l', 'o' };
|
char ar[] = {'H', 'e', 'l', 'l', 'o'};
|
||||||
|
|
||||||
string_span<> span = ar;
|
string_span<> span = ar;
|
||||||
|
|
||||||
@ -401,8 +402,7 @@ SUITE(string_span_tests)
|
|||||||
char ar2[10] = "Hello";
|
char ar2[10] = "Hello";
|
||||||
char* ptr = ar;
|
char* ptr = ar;
|
||||||
std::string str = "Hello";
|
std::string str = "Hello";
|
||||||
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
|
|
||||||
|
|
||||||
// comparison to static array with no null termination
|
// comparison to static array with no null termination
|
||||||
CHECK(span <= string_span<>(ar));
|
CHECK(span <= string_span<>(ar));
|
||||||
@ -466,7 +466,7 @@ SUITE(string_span_tests)
|
|||||||
CHECK(span.length() == 6);
|
CHECK(span.length() == 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
// from const span of a final extent to non-const string_span
|
// from const span of a final extent to non-const string_span
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
span<const char, 6> sp = "Hello";
|
span<const char, 6> sp = "Hello";
|
||||||
@ -475,7 +475,7 @@ SUITE(string_span_tests)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// from string temporary
|
// from string temporary
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
{
|
{
|
||||||
cstring_span<> span = std::string("Hello");
|
cstring_span<> span = std::string("Hello");
|
||||||
@ -502,14 +502,14 @@ SUITE(string_span_tests)
|
|||||||
|
|
||||||
// from const static array
|
// from const static array
|
||||||
{
|
{
|
||||||
const char ar[] = { 'H', 'e', 'l', 'l', 'o' };
|
const char ar[] = {'H', 'e', 'l', 'l', 'o'};
|
||||||
cstring_span<> span = ar;
|
cstring_span<> span = ar;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// from non-const static array
|
// from non-const static array
|
||||||
{
|
{
|
||||||
char ar[] = { 'H', 'e', 'l', 'l', 'o' };
|
char ar[] = {'H', 'e', 'l', 'l', 'o'};
|
||||||
cstring_span<> span = ar;
|
cstring_span<> span = ar;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
}
|
}
|
||||||
@ -517,37 +517,37 @@ SUITE(string_span_tests)
|
|||||||
// from const ptr and length
|
// from const ptr and length
|
||||||
{
|
{
|
||||||
const char* ptr = "Hello";
|
const char* ptr = "Hello";
|
||||||
cstring_span<> span{ ptr, 5 };
|
cstring_span<> span{ptr, 5};
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// from const ptr and length, include 0
|
// from const ptr and length, include 0
|
||||||
{
|
{
|
||||||
const char* ptr = "Hello";
|
const char* ptr = "Hello";
|
||||||
cstring_span<> span{ ptr, 6 };
|
cstring_span<> span{ptr, 6};
|
||||||
CHECK(span.length() == 6);
|
CHECK(span.length() == 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
// from const ptr and length, 0 inside
|
// from const ptr and length, 0 inside
|
||||||
{
|
{
|
||||||
const char* ptr = "He\0lo";
|
const char* ptr = "He\0lo";
|
||||||
cstring_span<> span{ ptr, 5 };
|
cstring_span<> span{ptr, 5};
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// from non-const ptr and length
|
// from non-const ptr and length
|
||||||
{
|
{
|
||||||
char ar[] = { 'H', 'e', 'l', 'l', 'o' };
|
char ar[] = {'H', 'e', 'l', 'l', 'o'};
|
||||||
char* ptr = ar;
|
char* ptr = ar;
|
||||||
cstring_span<> span{ ptr, 5 };
|
cstring_span<> span{ptr, 5};
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// from non-const ptr and length, 0 inside
|
// from non-const ptr and length, 0 inside
|
||||||
{
|
{
|
||||||
char ar[] = { 'H', 'e', '\0', 'l', 'o' };
|
char ar[] = {'H', 'e', '\0', 'l', 'o'};
|
||||||
char* ptr = ar;
|
char* ptr = ar;
|
||||||
cstring_span<> span{ ptr, 5 };
|
cstring_span<> span{ptr, 5};
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,21 +567,21 @@ SUITE(string_span_tests)
|
|||||||
|
|
||||||
// from const vector
|
// from const vector
|
||||||
{
|
{
|
||||||
const std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
const cstring_span<> span = vec;
|
const cstring_span<> span = vec;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// from non-const vector
|
// from non-const vector
|
||||||
{
|
{
|
||||||
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
const cstring_span<> span = vec;
|
const cstring_span<> span = vec;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// from const span
|
// from const span
|
||||||
{
|
{
|
||||||
const std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
const span<const char> inner = vec;
|
const span<const char> inner = vec;
|
||||||
const cstring_span<> span = inner;
|
const cstring_span<> span = inner;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
@ -589,7 +589,7 @@ SUITE(string_span_tests)
|
|||||||
|
|
||||||
// from non-const span
|
// from non-const span
|
||||||
{
|
{
|
||||||
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
const span<char> inner = vec;
|
const span<char> inner = vec;
|
||||||
const cstring_span<> span = inner;
|
const cstring_span<> span = inner;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
@ -597,7 +597,7 @@ SUITE(string_span_tests)
|
|||||||
|
|
||||||
// from const string_span
|
// from const string_span
|
||||||
{
|
{
|
||||||
const std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
const cstring_span<> tmp = vec;
|
const cstring_span<> tmp = vec;
|
||||||
const cstring_span<> span = tmp;
|
const cstring_span<> span = tmp;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
@ -605,7 +605,7 @@ SUITE(string_span_tests)
|
|||||||
|
|
||||||
// from non-const string_span
|
// from non-const string_span
|
||||||
{
|
{
|
||||||
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
string_span<> tmp = vec;
|
string_span<> tmp = vec;
|
||||||
cstring_span<> span = tmp;
|
cstring_span<> span = tmp;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
@ -623,7 +623,7 @@ SUITE(string_span_tests)
|
|||||||
// from const static array
|
// from const static array
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
const char ar[] = { 'H', 'e', 'l', 'l', 'o' };
|
const char ar[] = {'H', 'e', 'l', 'l', 'o'};
|
||||||
string_span<> span = ar;
|
string_span<> span = ar;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
#endif
|
#endif
|
||||||
@ -631,7 +631,7 @@ SUITE(string_span_tests)
|
|||||||
|
|
||||||
// from non-const static array
|
// from non-const static array
|
||||||
{
|
{
|
||||||
char ar[] = { 'H', 'e', 'l', 'l', 'o' };
|
char ar[] = {'H', 'e', 'l', 'l', 'o'};
|
||||||
string_span<> span = ar;
|
string_span<> span = ar;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
}
|
}
|
||||||
@ -640,16 +640,16 @@ SUITE(string_span_tests)
|
|||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
const char* ptr = "Hello";
|
const char* ptr = "Hello";
|
||||||
string_span<> span{ ptr, 5 };
|
string_span<> span{ptr, 5};
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// from non-const ptr and length
|
// from non-const ptr and length
|
||||||
{
|
{
|
||||||
char ar[] = { 'H', 'e', 'l', 'l', 'o' };
|
char ar[] = {'H', 'e', 'l', 'l', 'o'};
|
||||||
char* ptr = ar;
|
char* ptr = ar;
|
||||||
string_span<> span{ ptr, 5 };
|
string_span<> span{ptr, 5};
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -672,7 +672,7 @@ SUITE(string_span_tests)
|
|||||||
// from const vector
|
// from const vector
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
const std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
string_span<> span = vec;
|
string_span<> span = vec;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
#endif
|
#endif
|
||||||
@ -680,7 +680,7 @@ SUITE(string_span_tests)
|
|||||||
|
|
||||||
// from non-const vector
|
// from non-const vector
|
||||||
{
|
{
|
||||||
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
string_span<> span = vec;
|
string_span<> span = vec;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
}
|
}
|
||||||
@ -688,7 +688,7 @@ SUITE(string_span_tests)
|
|||||||
// from const span
|
// from const span
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
const span<const char> inner = vec;
|
const span<const char> inner = vec;
|
||||||
string_span<> span = inner;
|
string_span<> span = inner;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
@ -697,7 +697,7 @@ SUITE(string_span_tests)
|
|||||||
|
|
||||||
// from non-const span
|
// from non-const span
|
||||||
{
|
{
|
||||||
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
span<char> inner = vec;
|
span<char> inner = vec;
|
||||||
string_span<> span = inner;
|
string_span<> span = inner;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
@ -706,7 +706,7 @@ SUITE(string_span_tests)
|
|||||||
// from non-const span of non-const data from const vector
|
// from non-const span of non-const data from const vector
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
const std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
const span<char> inner = vec;
|
const span<char> inner = vec;
|
||||||
string_span<> span = inner;
|
string_span<> span = inner;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
@ -716,7 +716,7 @@ SUITE(string_span_tests)
|
|||||||
// from const string_span
|
// from const string_span
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
cstring_span<> tmp = vec;
|
cstring_span<> tmp = vec;
|
||||||
string_span<> span = tmp;
|
string_span<> span = tmp;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
@ -725,7 +725,7 @@ SUITE(string_span_tests)
|
|||||||
|
|
||||||
// from non-const string_span
|
// from non-const string_span
|
||||||
{
|
{
|
||||||
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
const string_span<> tmp = vec;
|
const string_span<> tmp = vec;
|
||||||
const string_span<> span = tmp;
|
const string_span<> span = tmp;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
@ -734,7 +734,7 @@ SUITE(string_span_tests)
|
|||||||
// from non-const string_span from const vector
|
// from non-const string_span from const vector
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
const std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
const std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
string_span<> tmp = vec;
|
string_span<> tmp = vec;
|
||||||
string_span<> span = tmp;
|
string_span<> span = tmp;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
@ -743,24 +743,29 @@ SUITE(string_span_tests)
|
|||||||
|
|
||||||
// from const string_span of non-const data
|
// from const string_span of non-const data
|
||||||
{
|
{
|
||||||
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
const string_span<> tmp = vec;
|
const string_span<> tmp = vec;
|
||||||
const string_span<> span = tmp;
|
const string_span<> span = tmp;
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T move_wrapper(T&& t)
|
T move_wrapper(T && t)
|
||||||
{
|
{
|
||||||
return std::move(t);
|
return std::move(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
T create() { return T{}; }
|
T create()
|
||||||
|
{
|
||||||
|
return T{};
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void use(basic_string_span<T, gsl::dynamic_extent>) {}
|
void use(basic_string_span<T, gsl::dynamic_extent>)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
TEST(MoveConstructors)
|
TEST(MoveConstructors)
|
||||||
{
|
{
|
||||||
@ -817,14 +822,14 @@ SUITE(string_span_tests)
|
|||||||
// move container
|
// move container
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
string_span<> span = std::move(vec);
|
string_span<> span = std::move(vec);
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
std::vector<char> vec = { 'H', 'e', 'l', 'l', 'o' };
|
std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
|
||||||
string_span<> span = move_wrapper<std::vector<char>>(std::move(vec));
|
string_span<> span = move_wrapper<std::vector<char>>(std::move(vec));
|
||||||
CHECK(span.length() == 5);
|
CHECK(span.length() == 5);
|
||||||
#endif
|
#endif
|
||||||
@ -840,7 +845,7 @@ SUITE(string_span_tests)
|
|||||||
{
|
{
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
cstring_span<> span = "Hello";
|
cstring_span<> span = "Hello";
|
||||||
cwstring_span<> wspan{ span };
|
cwstring_span<> wspan{span};
|
||||||
CHECK(wspan.length() == 5);
|
CHECK(wspan.length() == 5);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -850,8 +855,7 @@ SUITE(string_span_tests)
|
|||||||
Expects(span.size() > 1);
|
Expects(span.size() > 1);
|
||||||
|
|
||||||
int last = 0;
|
int last = 0;
|
||||||
if (span.size() > 4)
|
if (span.size() > 4) {
|
||||||
{
|
|
||||||
span[0] = 't';
|
span[0] = 't';
|
||||||
span[1] = 'm';
|
span[1] = 'm';
|
||||||
span[2] = 'p';
|
span[2] = 'p';
|
||||||
@ -860,7 +864,7 @@ SUITE(string_span_tests)
|
|||||||
span[last] = '\0';
|
span[last] = '\0';
|
||||||
|
|
||||||
auto ret = span.subspan(0, 4);
|
auto ret = span.subspan(0, 4);
|
||||||
return{ ret };
|
return {ret};
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(zstring)
|
TEST(zstring)
|
||||||
@ -871,7 +875,7 @@ SUITE(string_span_tests)
|
|||||||
char buf[1];
|
char buf[1];
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
|
|
||||||
zstring_span<> zspan({ buf, 1 });
|
zstring_span<> zspan({buf, 1});
|
||||||
|
|
||||||
CHECK(strlen(zspan.assume_z()) == 0);
|
CHECK(strlen(zspan.assume_z()) == 0);
|
||||||
CHECK(zspan.as_string_span().size() == 0);
|
CHECK(zspan.as_string_span().size() == 0);
|
||||||
@ -883,7 +887,7 @@ SUITE(string_span_tests)
|
|||||||
char buf[1];
|
char buf[1];
|
||||||
buf[0] = 'a';
|
buf[0] = 'a';
|
||||||
|
|
||||||
auto workaround_macro = [&]() { zstring_span<> zspan({ buf, 1 }); };
|
auto workaround_macro = [&]() { zstring_span<> zspan({buf, 1}); };
|
||||||
CHECK_THROW(workaround_macro(), fail_fast);
|
CHECK_THROW(workaround_macro(), fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -891,15 +895,13 @@ SUITE(string_span_tests)
|
|||||||
{
|
{
|
||||||
char buf[10];
|
char buf[10];
|
||||||
|
|
||||||
auto name = CreateTempName({ buf, 10 });
|
auto name = CreateTempName({buf, 10});
|
||||||
if (!name.empty())
|
if (!name.empty()) {
|
||||||
{
|
|
||||||
czstring<> str = name.assume_z();
|
czstring<> str = name.assume_z();
|
||||||
CHECK(strlen(str) == 3);
|
CHECK(strlen(str) == 3);
|
||||||
CHECK(*(str+3) == '\0');
|
CHECK(*(str + 3) == '\0');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cwzstring_span<> CreateTempNameW(wstring_span<> span)
|
cwzstring_span<> CreateTempNameW(wstring_span<> span)
|
||||||
@ -907,8 +909,7 @@ SUITE(string_span_tests)
|
|||||||
Expects(span.size() > 1);
|
Expects(span.size() > 1);
|
||||||
|
|
||||||
int last = 0;
|
int last = 0;
|
||||||
if (span.size() > 4)
|
if (span.size() > 4) {
|
||||||
{
|
|
||||||
span[0] = L't';
|
span[0] = L't';
|
||||||
span[1] = L'm';
|
span[1] = L'm';
|
||||||
span[2] = L'p';
|
span[2] = L'p';
|
||||||
@ -917,7 +918,7 @@ SUITE(string_span_tests)
|
|||||||
span[last] = L'\0';
|
span[last] = L'\0';
|
||||||
|
|
||||||
auto ret = span.subspan(0, 4);
|
auto ret = span.subspan(0, 4);
|
||||||
return{ ret };
|
return {ret};
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(wzstring)
|
TEST(wzstring)
|
||||||
@ -928,7 +929,7 @@ SUITE(string_span_tests)
|
|||||||
wchar_t buf[1];
|
wchar_t buf[1];
|
||||||
buf[0] = L'\0';
|
buf[0] = L'\0';
|
||||||
|
|
||||||
wzstring_span<> zspan({ buf, 1 });
|
wzstring_span<> zspan({buf, 1});
|
||||||
|
|
||||||
CHECK(wcsnlen(zspan.assume_z(), 1) == 0);
|
CHECK(wcsnlen(zspan.assume_z(), 1) == 0);
|
||||||
CHECK(zspan.as_string_span().size() == 0);
|
CHECK(zspan.as_string_span().size() == 0);
|
||||||
@ -940,7 +941,7 @@ SUITE(string_span_tests)
|
|||||||
wchar_t buf[1];
|
wchar_t buf[1];
|
||||||
buf[0] = L'a';
|
buf[0] = L'a';
|
||||||
|
|
||||||
const auto workaround_macro = [&]() { wzstring_span<> zspan({ buf, 1 }); };
|
const auto workaround_macro = [&]() { wzstring_span<> zspan({buf, 1}); };
|
||||||
CHECK_THROW(workaround_macro(), fail_fast);
|
CHECK_THROW(workaround_macro(), fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -948,9 +949,8 @@ SUITE(string_span_tests)
|
|||||||
{
|
{
|
||||||
wchar_t buf[10];
|
wchar_t buf[10];
|
||||||
|
|
||||||
const auto name = CreateTempNameW({ buf, 10 });
|
const auto name = CreateTempNameW({buf, 10});
|
||||||
if (!name.empty())
|
if (!name.empty()) {
|
||||||
{
|
|
||||||
cwzstring<> str = name.assume_z();
|
cwzstring<> str = name.assume_z();
|
||||||
CHECK(wcsnlen(str, 10) == 3);
|
CHECK(wcsnlen(str, 10) == 3);
|
||||||
CHECK(*(str + 3) == L'\0');
|
CHECK(*(str + 3) == L'\0');
|
||||||
@ -960,13 +960,10 @@ SUITE(string_span_tests)
|
|||||||
|
|
||||||
TEST(Issue305)
|
TEST(Issue305)
|
||||||
{
|
{
|
||||||
std::map<gsl::cstring_span<>, int> foo = { { "foo", 0 },{ "bar", 1 } };
|
std::map<gsl::cstring_span<>, int> foo = {{"foo", 0}, {"bar", 1}};
|
||||||
CHECK(foo["foo"] == 0);
|
CHECK(foo["foo"] == 0);
|
||||||
CHECK(foo["bar"] == 1);
|
CHECK(foo["bar"] == 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int, const char *[])
|
int main(int, const char* []) { return UnitTest::RunAllTests(); }
|
||||||
{
|
|
||||||
return UnitTest::RunAllTests();
|
|
||||||
}
|
|
||||||
|
@ -15,23 +15,22 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <UnitTest++/UnitTest++.h>
|
#include <UnitTest++/UnitTest++.h>
|
||||||
|
|
||||||
#include <gsl/gsl>
|
#include <gsl/gsl>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
using namespace gsl;
|
using namespace gsl;
|
||||||
|
|
||||||
SUITE(utils_tests)
|
SUITE(utils_tests)
|
||||||
{
|
{
|
||||||
void f(int& i)
|
void f(int& i) { i += 1; }
|
||||||
{
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(finally_lambda)
|
TEST(finally_lambda)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
{
|
{
|
||||||
auto _ = finally([&]() {f(i);});
|
auto _ = finally([&]() { f(i); });
|
||||||
CHECK(i == 0);
|
CHECK(i == 0);
|
||||||
}
|
}
|
||||||
CHECK(i == 1);
|
CHECK(i == 1);
|
||||||
@ -41,7 +40,7 @@ SUITE(utils_tests)
|
|||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
{
|
{
|
||||||
auto _1 = finally([&]() {f(i);});
|
auto _1 = finally([&]() { f(i); });
|
||||||
{
|
{
|
||||||
auto _2 = std::move(_1);
|
auto _2 = std::move(_1);
|
||||||
CHECK(i == 0);
|
CHECK(i == 0);
|
||||||
@ -113,7 +112,4 @@ SUITE(utils_tests)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int, const char *[])
|
int main(int, const char* []) { return UnitTest::RunAllTests(); }
|
||||||
{
|
|
||||||
return UnitTest::RunAllTests();
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user