mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
Merge changes from Microsoft\GSL.
This commit is contained in:
commit
6e2e3cb0ac
@ -16,6 +16,6 @@ AllowShortLoopsOnASingleLine: true
|
|||||||
|
|
||||||
PointerAlignment: Left
|
PointerAlignment: Left
|
||||||
AlignConsecutiveAssignments: false
|
AlignConsecutiveAssignments: false
|
||||||
AlignTrailingComments: false
|
AlignTrailingComments: true
|
||||||
|
|
||||||
SpaceAfterCStyleCast: true
|
SpaceAfterCStyleCast: true
|
||||||
|
@ -2,10 +2,21 @@ cmake_minimum_required(VERSION 2.8.7)
|
|||||||
|
|
||||||
project(GSL CXX)
|
project(GSL CXX)
|
||||||
|
|
||||||
|
set(GSL_HEADERS
|
||||||
|
"include/gsl.h"
|
||||||
|
"include/gsl_assert.h"
|
||||||
|
"include/span.h"
|
||||||
|
"include/string_span.h"
|
||||||
|
)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
install(FILES ${GSL_HEADERS}
|
||||||
|
DESTINATION include/gsl
|
||||||
|
)
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
|
@ -14,6 +14,9 @@ it is simplest to just include [gsl.h](./include/gsl.h) and gain access to the e
|
|||||||
> NOTE: We encourage contributions that improve or refine any of the types in this library as well as ports to
|
> NOTE: We encourage contributions that improve or refine any of the types in this library as well as ports to
|
||||||
other platforms. Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for more information about contributing.
|
other platforms. Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for more information about contributing.
|
||||||
|
|
||||||
|
# Project Code of Conduct
|
||||||
|
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||||
|
|
||||||
# Quick Start
|
# Quick Start
|
||||||
## Supported Platforms
|
## Supported Platforms
|
||||||
The test suite that exercises GSL has been built and passes successfully on the following platforms:
|
The test suite that exercises GSL has been built and passes successfully on the following platforms:
|
||||||
|
@ -21,8 +21,9 @@
|
|||||||
|
|
||||||
#include "gsl_assert.h" // Ensures/Expects
|
#include "gsl_assert.h" // Ensures/Expects
|
||||||
#include "gsl_util.h" // finally()/narrow()/narrow_cast()...
|
#include "gsl_util.h" // finally()/narrow()/narrow_cast()...
|
||||||
#include "span.h" // span, strided_span...
|
#include "multi_span.h" // multi_span, strided_span...
|
||||||
#include "string_span.h" // zstring, string_span, zstring_builder...
|
#include "span.h" // span
|
||||||
|
#include "string_span.h" // zstring, string_span, zstring_builder...
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -39,13 +40,12 @@
|
|||||||
|
|
||||||
// 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 // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
|
||||||
namespace gsl
|
namespace gsl
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -58,7 +58,6 @@ using std::shared_ptr;
|
|||||||
template <class T>
|
template <class T>
|
||||||
using owner = T;
|
using owner = T;
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// not_null
|
// not_null
|
||||||
//
|
//
|
||||||
@ -73,25 +72,31 @@ using owner = T;
|
|||||||
// - ensure construction from U* fails with nullptr
|
// - ensure construction from U* fails with nullptr
|
||||||
// - allow implicit conversion to U*
|
// - allow implicit conversion to U*
|
||||||
//
|
//
|
||||||
template<class T>
|
template <class T>
|
||||||
class not_null
|
class not_null
|
||||||
{
|
{
|
||||||
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.");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
not_null(T t) : ptr_(t) { ensure_invariant(); }
|
not_null(T t) : ptr_(t) { ensure_invariant(); }
|
||||||
not_null& operator=(const T& t) { ptr_ = t; ensure_invariant(); return *this; }
|
not_null& operator=(const T& t)
|
||||||
|
{
|
||||||
|
ptr_ = t;
|
||||||
|
ensure_invariant();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
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>>
|
||||||
not_null(const not_null<U> &other)
|
not_null(const not_null<U>& other)
|
||||||
{
|
{
|
||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
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>>
|
||||||
not_null& operator=(const not_null<U> &other)
|
not_null& operator=(const not_null<U>& other)
|
||||||
{
|
{
|
||||||
ptr_ = other.get();
|
ptr_ = other.get();
|
||||||
return *this;
|
return *this;
|
||||||
@ -101,24 +106,26 @@ public:
|
|||||||
not_null(std::nullptr_t) = delete;
|
not_null(std::nullptr_t) = delete;
|
||||||
not_null(int) = delete;
|
not_null(int) = delete;
|
||||||
not_null<T>& operator=(std::nullptr_t) = delete;
|
not_null<T>& operator=(std::nullptr_t) = delete;
|
||||||
not_null<T>& operator=(int) = delete;
|
not_null<T>& operator=(int) = delete;
|
||||||
|
|
||||||
T get() const {
|
T get() const
|
||||||
|
{
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
__assume(ptr_ != nullptr);
|
__assume(ptr_ != nullptr);
|
||||||
#endif
|
#endif
|
||||||
return ptr_;
|
return ptr_;
|
||||||
} // the assume() should help the optimizer
|
} // the assume() should help the optimizer
|
||||||
|
|
||||||
operator T() const { return get(); }
|
operator T() const { return get(); }
|
||||||
T operator->() const { return get(); }
|
T operator->() const { return get(); }
|
||||||
|
|
||||||
bool operator==(const T& rhs) const { return ptr_ == rhs; }
|
bool operator==(const T& rhs) const { return ptr_ == rhs; }
|
||||||
bool operator!=(const T& rhs) const { return !(*this == rhs); }
|
bool operator!=(const T& rhs) const { return !(*this == rhs); }
|
||||||
private:
|
private:
|
||||||
T ptr_;
|
T ptr_;
|
||||||
|
|
||||||
// we assume that the compiler can hoist/prove away most of the checks inlined from this function
|
// we assume that the compiler can hoist/prove away most of the checks inlined from this
|
||||||
|
// function
|
||||||
// if not, we could make them optional via conditional compilation
|
// if not, we could make them optional via conditional compilation
|
||||||
void ensure_invariant() const { Expects(ptr_ != nullptr); }
|
void ensure_invariant() const { Expects(ptr_ != nullptr); }
|
||||||
|
|
||||||
@ -138,14 +145,11 @@ private:
|
|||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
template<class T>
|
template <class T>
|
||||||
struct hash<gsl::not_null<T>>
|
struct hash<gsl::not_null<T>>
|
||||||
{
|
{
|
||||||
size_t operator()(const gsl::not_null<T> & value) const
|
size_t operator()(const gsl::not_null<T>& value) const { return hash<T>{}(value); }
|
||||||
{
|
};
|
||||||
return hash<T>{}(value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
||||||
|
@ -42,15 +42,14 @@
|
|||||||
// 2. GSL_THROW_ON_CONTRACT_VIOLATION: a gsl::fail_fast exception will be thrown
|
// 2. GSL_THROW_ON_CONTRACT_VIOLATION: a gsl::fail_fast exception will be thrown
|
||||||
// 3. GSL_UNENFORCED_ON_CONTRACT_VIOLATION: nothing happens
|
// 3. GSL_UNENFORCED_ON_CONTRACT_VIOLATION: nothing happens
|
||||||
//
|
//
|
||||||
#if !(defined(GSL_THROW_ON_CONTRACT_VIOLATION) ^ defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) ^ defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION))
|
#if !(defined(GSL_THROW_ON_CONTRACT_VIOLATION) ^ defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) ^ \
|
||||||
|
defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION))
|
||||||
#define GSL_TERMINATE_ON_CONTRACT_VIOLATION
|
#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)
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// GSL.assert: assertions
|
// GSL.assert: assertions
|
||||||
//
|
//
|
||||||
@ -78,18 +77,19 @@ namespace details
|
|||||||
|
|
||||||
#if defined(GSL_THROW_ON_CONTRACT_VIOLATION)
|
#if defined(GSL_THROW_ON_CONTRACT_VIOLATION)
|
||||||
|
|
||||||
#define Expects(cond) if (!(cond)) \
|
#define Expects(cond) \
|
||||||
throw gsl::details::contract_violation<std::logic_error>("GSL: Precondition failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__));
|
if (!(cond)) \
|
||||||
#define Ensures(cond) if (!(cond)) \
|
throw gsl::details::contract_violation<std::logic_error>("GSL: Precondition failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__));
|
||||||
throw gsl::details::contract_violation<std::runtime_error>("GSL: Postcondition failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__));
|
#define Ensures(cond) \
|
||||||
|
if (!(cond)) \
|
||||||
|
throw gsl::details::contract_violation<std::runtime_error>("GSL: Postcondition failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__));
|
||||||
|
|
||||||
#elif defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
|
#elif defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
|
||||||
|
|
||||||
|
#define Expects(cond) \
|
||||||
#define Expects(cond) if (!(cond)) std::terminate();
|
if (!(cond)) std::terminate();
|
||||||
#define Ensures(cond) if (!(cond)) std::terminate();
|
#define Ensures(cond) \
|
||||||
|
if (!(cond)) std::terminate();
|
||||||
|
|
||||||
#elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)
|
#elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)
|
||||||
|
|
||||||
@ -98,7 +98,6 @@ namespace details
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
#if _MSC_VER <= 1800
|
#if _MSC_VER <= 1800
|
||||||
|
125
include/gsl_byte.h
Normal file
125
include/gsl_byte.h
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// This code is licensed under the MIT License (MIT).
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef GSL_BYTE_H
|
||||||
|
#define GSL_BYTE_H
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
// MSVC 2013 workarounds
|
||||||
|
#if _MSC_VER <= 1800
|
||||||
|
|
||||||
|
// constexpr is not understood
|
||||||
|
#pragma push_macro("constexpr")
|
||||||
|
#define constexpr
|
||||||
|
|
||||||
|
// noexcept is not understood
|
||||||
|
#pragma push_macro("noexcept")
|
||||||
|
#define noexcept
|
||||||
|
|
||||||
|
#endif // _MSC_VER <= 1800
|
||||||
|
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
namespace gsl
|
||||||
|
{
|
||||||
|
// This is a simple definition for now that allows
|
||||||
|
// use of byte within span<> to be standards-compliant
|
||||||
|
enum class byte : unsigned char
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
|
||||||
|
constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept
|
||||||
|
{
|
||||||
|
return b = byte(static_cast<unsigned char>(b) << shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
|
||||||
|
constexpr byte operator<<(byte b, IntegerType shift) noexcept
|
||||||
|
{
|
||||||
|
return byte(static_cast<unsigned char>(b) << shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
|
||||||
|
constexpr byte& operator>>=(byte& b, IntegerType shift) noexcept
|
||||||
|
{
|
||||||
|
return b = byte(static_cast<unsigned char>(b) >> shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
|
||||||
|
constexpr byte operator>>(byte b, IntegerType shift) noexcept
|
||||||
|
{
|
||||||
|
return byte(static_cast<unsigned char>(b) >> shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr byte& operator|=(byte& l, byte r) noexcept
|
||||||
|
{
|
||||||
|
return l = byte(static_cast<unsigned char>(l) | static_cast<unsigned char>(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr byte operator|(byte l, byte r) noexcept
|
||||||
|
{
|
||||||
|
return byte(static_cast<unsigned char>(l) + static_cast<unsigned char>(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr byte& operator&=(byte& l, byte r) noexcept
|
||||||
|
{
|
||||||
|
return l = byte(static_cast<unsigned char>(l) & static_cast<unsigned char>(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr byte operator&(byte l, byte r) noexcept
|
||||||
|
{
|
||||||
|
return byte(static_cast<unsigned char>(l) & static_cast<unsigned char>(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr byte& operator^=(byte& l, byte r) noexcept
|
||||||
|
{
|
||||||
|
return l = byte(static_cast<unsigned char>(l) ^ static_cast<unsigned char>(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr byte operator^(byte l, byte r) noexcept
|
||||||
|
{
|
||||||
|
return byte(static_cast<unsigned char>(l) ^ static_cast<unsigned char>(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr byte operator~(byte b) noexcept { return byte(~static_cast<unsigned char>(b)); }
|
||||||
|
|
||||||
|
template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>>
|
||||||
|
constexpr IntegerType to_integer(byte b) noexcept
|
||||||
|
{
|
||||||
|
return {b};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace gsl
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
#if _MSC_VER <= 1800
|
||||||
|
|
||||||
|
#undef constexpr
|
||||||
|
#pragma pop_macro("constexpr")
|
||||||
|
|
||||||
|
#undef noexcept
|
||||||
|
#pragma pop_macro("noexcept")
|
||||||
|
|
||||||
|
#endif // _MSC_VER <= 1800
|
||||||
|
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
#endif // GSL_BYTE_H
|
@ -19,11 +19,11 @@
|
|||||||
#ifndef GSL_UTIL_H
|
#ifndef GSL_UTIL_H
|
||||||
#define GSL_UTIL_H
|
#define GSL_UTIL_H
|
||||||
|
|
||||||
#include "gsl_assert.h" // Ensures/Expects
|
#include "gsl_assert.h" // Ensures/Expects
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <utility>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
@ -32,7 +32,7 @@
|
|||||||
#define constexpr
|
#define constexpr
|
||||||
|
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable: 4127) // conditional expression is constant
|
#pragma warning(disable : 4127) // conditional expression is constant
|
||||||
|
|
||||||
// MSVC 2013 workarounds
|
// MSVC 2013 workarounds
|
||||||
#if _MSC_VER <= 1800
|
#if _MSC_VER <= 1800
|
||||||
@ -42,13 +42,12 @@
|
|||||||
|
|
||||||
// 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 // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
|
||||||
namespace gsl
|
namespace gsl
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@ -60,18 +59,20 @@ template <class F>
|
|||||||
class final_act
|
class final_act
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit final_act(F f) noexcept
|
explicit final_act(F f) noexcept : f_(std::move(f)), invoke_(true) {}
|
||||||
: f_(std::move(f)), invoke_(true)
|
|
||||||
{}
|
|
||||||
|
|
||||||
final_act(final_act&& other) noexcept
|
final_act(final_act&& other) noexcept : f_(std::move(other.f_)), invoke_(other.invoke_)
|
||||||
: f_(std::move(other.f_)), invoke_(other.invoke_)
|
{
|
||||||
{ other.invoke_ = false; }
|
other.invoke_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
final_act(const final_act&) = delete;
|
final_act(const final_act&) = delete;
|
||||||
final_act& operator=(const final_act&) = delete;
|
final_act& operator=(const final_act&) = delete;
|
||||||
|
|
||||||
~final_act() noexcept { if (invoke_) f_(); }
|
~final_act() noexcept
|
||||||
|
{
|
||||||
|
if (invoke_) f_();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
F f_;
|
F f_;
|
||||||
@ -80,34 +81,43 @@ private:
|
|||||||
|
|
||||||
// finally() - convenience function to generate a final_act
|
// finally() - convenience function to generate a final_act
|
||||||
template <class F>
|
template <class F>
|
||||||
inline final_act<F> finally(const F &f)
|
inline final_act<F> finally(const F& f) noexcept
|
||||||
noexcept { return final_act<F>(f); }
|
{
|
||||||
|
return final_act<F>(f);
|
||||||
|
}
|
||||||
|
|
||||||
template <class F>
|
template <class F>
|
||||||
inline final_act<F> finally(F &&f) noexcept
|
inline final_act<F> finally(F&& f) noexcept
|
||||||
{ return final_act<F>(std::forward<F>(f)); }
|
{
|
||||||
|
return final_act<F>(std::forward<F>(f));
|
||||||
|
}
|
||||||
|
|
||||||
// narrow_cast(): a searchable way to do narrowing casts of values
|
// narrow_cast(): a searchable way to do narrowing casts of values
|
||||||
template<class T, class U>
|
template <class T, class U>
|
||||||
inline constexpr T narrow_cast(U u) noexcept
|
inline constexpr T narrow_cast(U u) noexcept
|
||||||
{ return static_cast<T>(u); }
|
{
|
||||||
|
return static_cast<T>(u);
|
||||||
|
}
|
||||||
|
|
||||||
struct narrowing_error : public std::exception {};
|
struct narrowing_error : public std::exception
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
namespace details
|
namespace details
|
||||||
{
|
{
|
||||||
template<class T, class U>
|
template <class T, class U>
|
||||||
struct is_same_signedness : public std::integral_constant<bool, std::is_signed<T>::value == std::is_signed<U>::value>
|
struct is_same_signedness
|
||||||
{};
|
: public std::integral_constant<bool, std::is_signed<T>::value == std::is_signed<U>::value>
|
||||||
|
{
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// narrow() : a checked version of narrow_cast() that throws if the cast changed the value
|
// narrow() : a checked version of narrow_cast() that throws if the cast changed the value
|
||||||
template<class T, class U>
|
template <class T, class U>
|
||||||
inline T narrow(U u)
|
inline T narrow(U u)
|
||||||
{
|
{
|
||||||
T t = narrow_cast<T>(u);
|
T t = narrow_cast<T>(u);
|
||||||
if (static_cast<U>(t) != u)
|
if (static_cast<U>(t) != u) throw narrowing_error();
|
||||||
throw narrowing_error();
|
|
||||||
if (!details::is_same_signedness<T, U>::value && ((t < T{}) != (u < U{})))
|
if (!details::is_same_signedness<T, U>::value && ((t < T{}) != (u < U{})))
|
||||||
throw narrowing_error();
|
throw narrowing_error();
|
||||||
return t;
|
return t;
|
||||||
@ -117,24 +127,35 @@ inline T narrow(U u)
|
|||||||
// at() - Bounds-checked way of accessing static arrays, std::array, std::vector
|
// at() - Bounds-checked way of accessing static arrays, std::array, std::vector
|
||||||
//
|
//
|
||||||
template <class T, size_t N>
|
template <class T, size_t N>
|
||||||
constexpr T& at(T(&arr)[N], size_t index)
|
constexpr T& at(T (&arr)[N], size_t index)
|
||||||
{ Expects(index < N); return arr[index]; }
|
{
|
||||||
|
Expects(index < N);
|
||||||
|
return arr[index];
|
||||||
|
}
|
||||||
|
|
||||||
template <class T, size_t N>
|
template <class T, size_t N>
|
||||||
constexpr T& at(std::array<T, N>& arr, size_t index)
|
constexpr T& at(std::array<T, N>& arr, size_t index)
|
||||||
{ Expects(index < N); return arr[index]; }
|
{
|
||||||
|
Expects(index < N);
|
||||||
|
return arr[index];
|
||||||
|
}
|
||||||
|
|
||||||
template <class Cont>
|
template <class Cont>
|
||||||
constexpr typename Cont::value_type& at(Cont& cont, size_t index)
|
constexpr typename Cont::value_type& at(Cont& cont, size_t index)
|
||||||
{ Expects(index < cont.size()); return cont[index]; }
|
{
|
||||||
|
Expects(index < cont.size());
|
||||||
|
return cont[index];
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
constexpr const T& at(std::initializer_list<T> cont, size_t index)
|
constexpr const T& at(std::initializer_list<T> cont, size_t index)
|
||||||
{ Expects(index < cont.size()); return *(cont.begin() + index); }
|
{
|
||||||
|
Expects(index < cont.size());
|
||||||
|
return *(cont.begin() + index);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace gsl
|
} // namespace gsl
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
2239
include/multi_span.h
Normal file
2239
include/multi_span.h
Normal file
File diff suppressed because it is too large
Load Diff
2747
include/span.h
2747
include/span.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -33,7 +33,7 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
function(add_gsl_test name)
|
function(add_gsl_test name)
|
||||||
add_executable(${name} ${name}.cpp ../include/gsl.h ../include/gsl_assert.h ../include/gsl_util.h ../include/span.h ../include/string_span.h)
|
add_executable(${name} ${name}.cpp ../include/gsl.h ../include/gsl_assert.h ../include/gsl_util.h ../include/multi_span.h ../include/span.h ../include/string_span.h)
|
||||||
target_link_libraries(${name} UnitTest++)
|
target_link_libraries(${name} UnitTest++)
|
||||||
install(TARGETS ${name}
|
install(TARGETS ${name}
|
||||||
RUNTIME DESTINATION bin
|
RUNTIME DESTINATION bin
|
||||||
@ -45,6 +45,7 @@ function(add_gsl_test name)
|
|||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
add_gsl_test(span_tests)
|
add_gsl_test(span_tests)
|
||||||
|
add_gsl_test(multi_span_tests)
|
||||||
add_gsl_test(strided_span_tests)
|
add_gsl_test(strided_span_tests)
|
||||||
add_gsl_test(string_span_tests)
|
add_gsl_test(string_span_tests)
|
||||||
add_gsl_test(at_tests)
|
add_gsl_test(at_tests)
|
||||||
@ -53,3 +54,4 @@ add_gsl_test(notnull_tests)
|
|||||||
add_gsl_test(assertion_tests)
|
add_gsl_test(assertion_tests)
|
||||||
add_gsl_test(utils_tests)
|
add_gsl_test(utils_tests)
|
||||||
add_gsl_test(owner_tests)
|
add_gsl_test(owner_tests)
|
||||||
|
add_gsl_test(byte_tests)
|
@ -15,7 +15,7 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <UnitTest++/UnitTest++.h>
|
#include <UnitTest++/UnitTest++.h>
|
||||||
#include <span.h>
|
#include <multi_span.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -58,7 +58,7 @@ SUITE(bounds_test)
|
|||||||
auto itr = bounds.begin();
|
auto itr = bounds.begin();
|
||||||
(void)itr;
|
(void)itr;
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
span<int, 4, dynamic_range, 2> av(nullptr, bounds);
|
multi_span<int, 4, dynamic_range, 2> av(nullptr, bounds);
|
||||||
|
|
||||||
auto itr2 = av.cbegin();
|
auto itr2 = av.cbegin();
|
||||||
|
|
||||||
|
93
tests/byte_tests.cpp
Normal file
93
tests/byte_tests.cpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// This code is licensed under the MIT License (MIT).
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <UnitTest++/UnitTest++.h>
|
||||||
|
#include <gsl_byte.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace gsl;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
SUITE(byte_tests)
|
||||||
|
{
|
||||||
|
TEST(construction)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
byte b = static_cast<byte>(4);
|
||||||
|
CHECK(static_cast<unsigned char>(b) == 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
byte b = byte(12);
|
||||||
|
CHECK(static_cast<unsigned char>(b) == 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
// waiting for C++17 enum class direct initializer support
|
||||||
|
//{
|
||||||
|
// byte b { 14 };
|
||||||
|
// CHECK(static_cast<unsigned char>(b) == 14);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(bitwise_operations)
|
||||||
|
{
|
||||||
|
byte b = byte(0xFF);
|
||||||
|
|
||||||
|
byte a = byte(0x00);
|
||||||
|
CHECK((b | a) == byte(0xFF));
|
||||||
|
CHECK(a == byte(0x00));
|
||||||
|
|
||||||
|
a |= b;
|
||||||
|
CHECK(a == byte(0xFF));
|
||||||
|
|
||||||
|
a = byte(0x01);
|
||||||
|
CHECK((b & a) == byte(0x01));
|
||||||
|
|
||||||
|
a &= b;
|
||||||
|
CHECK(a == byte(0x01));
|
||||||
|
|
||||||
|
CHECK((b ^ a) == byte(0xFE));
|
||||||
|
|
||||||
|
CHECK(a == byte(0x01));
|
||||||
|
a ^= b;
|
||||||
|
CHECK(a == byte(0xFE));
|
||||||
|
|
||||||
|
a = byte(0x01);
|
||||||
|
CHECK(~a == byte(0xFE));
|
||||||
|
|
||||||
|
a = byte(0xFF);
|
||||||
|
CHECK((a << 4) == byte(0xF0));
|
||||||
|
CHECK((a >> 4) == byte(0x0F));
|
||||||
|
|
||||||
|
a <<= 4;
|
||||||
|
CHECK(a == byte(0xF0));
|
||||||
|
a >>= 4;
|
||||||
|
CHECK(a == byte(0x0F));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, const char* []) { return UnitTest::RunAllTests(); }
|
1679
tests/multi_span_tests.cpp
Normal file
1679
tests/multi_span_tests.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1379
tests/span_tests.cpp
1379
tests/span_tests.cpp
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,7 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <UnitTest++/UnitTest++.h>
|
#include <UnitTest++/UnitTest++.h>
|
||||||
#include <span.h>
|
#include <multi_span.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -39,7 +39,7 @@ SUITE(strided_span_tests)
|
|||||||
{
|
{
|
||||||
int a[30][4][5];
|
int a[30][4][5];
|
||||||
|
|
||||||
auto av = as_span(a);
|
auto av = as_multi_span(a);
|
||||||
auto sub = av.section({15, 0, 0}, gsl::index<3>{2, 2, 2});
|
auto sub = av.section({15, 0, 0}, gsl::index<3>{2, 2, 2});
|
||||||
auto subsub = sub.section({1, 0, 0}, gsl::index<3>{1, 1, 1});
|
auto subsub = sub.section({1, 0, 0}, gsl::index<3>{1, 1, 1});
|
||||||
(void)subsub;
|
(void)subsub;
|
||||||
@ -49,7 +49,7 @@ 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 span<int, 5, 10> av = as_span(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>());
|
||||||
|
|
||||||
strided_span<int, 2> av_section_1 = av.section({ 1, 2 }, { 3, 4 });
|
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));
|
||||||
@ -87,13 +87,13 @@ SUITE(strided_span_tests)
|
|||||||
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 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 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 });
|
||||||
@ -102,9 +102,9 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
#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{ 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{ 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 });
|
||||||
@ -113,7 +113,7 @@ SUITE(strided_span_tests)
|
|||||||
#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{ 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 });
|
||||||
@ -122,7 +122,7 @@ SUITE(strided_span_tests)
|
|||||||
#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{ 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 });
|
||||||
@ -131,7 +131,7 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
// From const-qualified source
|
// From const-qualified source
|
||||||
{
|
{
|
||||||
const 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 });
|
||||||
@ -141,7 +141,7 @@ SUITE(strided_span_tests)
|
|||||||
#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{ 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 });
|
||||||
@ -151,7 +151,7 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
// From volatile-qualified source
|
// From volatile-qualified source
|
||||||
{
|
{
|
||||||
const 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 });
|
||||||
@ -161,7 +161,7 @@ SUITE(strided_span_tests)
|
|||||||
#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{ 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 });
|
||||||
@ -170,7 +170,7 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
// From cv-qualified source
|
// From cv-qualified source
|
||||||
{
|
{
|
||||||
const 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 });
|
||||||
@ -183,11 +183,11 @@ SUITE(strided_span_tests)
|
|||||||
{
|
{
|
||||||
int arr[2] = { 4, 5 };
|
int arr[2] = { 4, 5 };
|
||||||
|
|
||||||
const span<int, 2> av(arr, 2);
|
const multi_span<int, 2> av(arr, 2);
|
||||||
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 span<int, 2>, 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 };
|
||||||
@ -258,13 +258,13 @@ 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 span<int, 5, 10> src = as_span(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{ 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);
|
||||||
@ -317,7 +317,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 };
|
||||||
span<int> av(arr);
|
multi_span<int> av(arr);
|
||||||
|
|
||||||
{
|
{
|
||||||
// incorrect sections
|
// incorrect sections
|
||||||
@ -413,18 +413,18 @@ SUITE(strided_span_tests)
|
|||||||
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_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_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_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_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_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_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
|
||||||
}
|
}
|
||||||
@ -432,7 +432,7 @@ SUITE(strided_span_tests)
|
|||||||
TEST(strided_span_type_conversion)
|
TEST(strided_span_type_conversion)
|
||||||
{
|
{
|
||||||
int arr[] = { 0, 1, 2, 3 };
|
int arr[] = { 0, 1, 2, 3 };
|
||||||
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 } };
|
||||||
@ -447,7 +447,7 @@ SUITE(strided_span_tests)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
span<const byte, dynamic_range> bytes = as_bytes(av);
|
multi_span<const byte, dynamic_range> bytes = as_bytes(av);
|
||||||
|
|
||||||
// retype strided array with regular strides - from raw data
|
// retype strided array with regular strides - from raw data
|
||||||
{
|
{
|
||||||
@ -460,10 +460,10 @@ SUITE(strided_span_tests)
|
|||||||
CHECK_THROW(sav3[0][1], fail_fast);
|
CHECK_THROW(sav3[0][1], fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
// retype strided array with regular strides - from 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 } };
|
||||||
span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2));
|
multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||||
strided_span<const byte, 2> sav2{ bytes2, bounds };
|
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);
|
||||||
@ -475,7 +475,7 @@ 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 } };
|
||||||
span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2));
|
multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||||
strided_span<const byte, 2> sav2{ bytes2, bounds };
|
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);
|
||||||
}
|
}
|
||||||
@ -483,7 +483,7 @@ SUITE(strided_span_tests)
|
|||||||
// 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 } };
|
||||||
span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2));
|
multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||||
strided_span<const byte, 2> sav2{ bytes2, bounds };
|
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);
|
||||||
}
|
}
|
||||||
@ -491,7 +491,7 @@ SUITE(strided_span_tests)
|
|||||||
// 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 } };
|
||||||
span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2));
|
multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||||
strided_span<const byte, 2> sav2{ bytes2, bounds };
|
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);
|
||||||
}
|
}
|
||||||
@ -499,7 +499,7 @@ SUITE(strided_span_tests)
|
|||||||
// 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 } };
|
||||||
span<const byte, 2, dynamic_range> bytes2 = as_span(bytes, dim<2>(), dim<>(bytes.size() / 2));
|
multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
|
||||||
strided_span<const byte, 2> sav2{ bytes2, bounds };
|
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);
|
||||||
}
|
}
|
||||||
@ -511,7 +511,7 @@ SUITE(strided_span_tests)
|
|||||||
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 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 };
|
||||||
@ -522,7 +522,7 @@ SUITE(strided_span_tests)
|
|||||||
TEST(empty_strided_spans)
|
TEST(empty_strided_spans)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
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 });
|
||||||
@ -553,7 +553,7 @@ SUITE(strided_span_tests)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void iterate_every_other_element(span<int, dynamic_range> av)
|
void iterate_every_other_element(multi_span<int, dynamic_range> av)
|
||||||
{
|
{
|
||||||
// pick every other element
|
// pick every other element
|
||||||
|
|
||||||
@ -586,13 +586,13 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
// static bounds
|
// static bounds
|
||||||
{
|
{
|
||||||
span<int, 8> av(arr, 8);
|
multi_span<int, 8> av(arr, 8);
|
||||||
iterate_every_other_element(av);
|
iterate_every_other_element(av);
|
||||||
}
|
}
|
||||||
|
|
||||||
// dynamic bounds
|
// dynamic bounds
|
||||||
{
|
{
|
||||||
span<int, dynamic_range> av(arr, 8);
|
multi_span<int, dynamic_range> av(arr, 8);
|
||||||
iterate_every_other_element(av);
|
iterate_every_other_element(av);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -606,13 +606,13 @@ SUITE(strided_span_tests)
|
|||||||
arr[2 * i + 1] = i;
|
arr[2 * i + 1] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto av = as_span(arr, 8);
|
auto av = as_multi_span(arr, 8);
|
||||||
iterate_every_other_element(av);
|
iterate_every_other_element(av);
|
||||||
|
|
||||||
delete[] arr;
|
delete[] arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void iterate_second_slice(span<int, dynamic_range, dynamic_range, dynamic_range> av)
|
void iterate_second_slice(multi_span<int, dynamic_range, dynamic_range, dynamic_range> av)
|
||||||
{
|
{
|
||||||
int expected[6] = {2,3,10,11,18,19};
|
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});
|
||||||
@ -653,7 +653,7 @@ SUITE(strided_span_tests)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
span<int, 3, 4, 2> av = arr;
|
multi_span<int, 3, 4, 2> av = arr;
|
||||||
iterate_second_slice(av);
|
iterate_second_slice(av);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -670,22 +670,22 @@ SUITE(strided_span_tests)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto av = as_span(as_span(arr, 24), dim<3>(), dim<4>(), dim<2>());
|
auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<4>(), dim<2>());
|
||||||
iterate_second_slice(av);
|
iterate_second_slice(av);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto av = as_span(as_span(arr, 24), dim<>(3), dim<4>(), dim<2>());
|
auto av = as_multi_span(as_multi_span(arr, 24), dim(3), dim<4>(), dim<2>());
|
||||||
iterate_second_slice(av);
|
iterate_second_slice(av);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto av = as_span(as_span(arr, 24), dim<3>(), dim<>(4), dim<2>());
|
auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim(4), dim<2>());
|
||||||
iterate_second_slice(av);
|
iterate_second_slice(av);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto av = as_span(as_span(arr, 24), dim<3>(), dim<4>(), dim<>(2));
|
auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<4>(), dim(2));
|
||||||
iterate_second_slice(av);
|
iterate_second_slice(av);
|
||||||
}
|
}
|
||||||
delete[] arr;
|
delete[] arr;
|
||||||
@ -693,7 +693,7 @@ SUITE(strided_span_tests)
|
|||||||
|
|
||||||
TEST(strided_span_conversion)
|
TEST(strided_span_conversion)
|
||||||
{
|
{
|
||||||
// get an 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; };
|
||||||
|
|
||||||
@ -704,7 +704,7 @@ SUITE(strided_span_tests)
|
|||||||
auto d1 = sizeof(int) * 12 / d2;
|
auto d1 = sizeof(int) * 12 / d2;
|
||||||
|
|
||||||
// convert to 4x12 array of bytes
|
// convert to 4x12 array of bytes
|
||||||
auto av = as_span(as_bytes(as_span(arr, 4)), dim<>(d1), dim<>(d2));
|
auto av = as_multi_span(as_bytes(as_multi_span(arr, 4)), dim(d1), dim(d2));
|
||||||
|
|
||||||
CHECK(av.bounds().index_bounds()[0] == 4);
|
CHECK(av.bounds().index_bounds()[0] == 4);
|
||||||
CHECK(av.bounds().index_bounds()[1] == 12);
|
CHECK(av.bounds().index_bounds()[1] == 12);
|
||||||
|
@ -40,14 +40,14 @@ SUITE(string_span_tests)
|
|||||||
{
|
{
|
||||||
std::string s = "Hello there world";
|
std::string s = "Hello there world";
|
||||||
cstring_span<> v = s;
|
cstring_span<> v = s;
|
||||||
CHECK(v.length() == static_cast<cstring_span<>::size_type>(s.length()));
|
CHECK(v.length() == static_cast<cstring_span<>::index_type>(s.length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
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<>::size_type>(vec.size()));
|
CHECK(v.length() == static_cast<string_span<>::index_type>(vec.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TestStackArrayConstruction)
|
TEST(TestStackArrayConstruction)
|
||||||
@ -109,7 +109,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);
|
||||||
auto s2 = gsl::to_string(v);
|
auto s2 = gsl::to_string(v);
|
||||||
CHECK(static_cast<cstring_span<>::size_type>(s2.length()) == v.length());
|
CHECK(static_cast<cstring_span<>::index_type>(s2.length()) == v.length());
|
||||||
CHECK(s2.length() == 5);
|
CHECK(s2.length() == 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -746,7 +746,7 @@ SUITE(string_span_tests)
|
|||||||
T create() { return T{}; }
|
T create() { return T{}; }
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void use(basic_string_span<T, gsl::dynamic_range> s) {}
|
void use(basic_string_span<T, gsl::dynamic_extent> s) {}
|
||||||
|
|
||||||
TEST(MoveConstructors)
|
TEST(MoveConstructors)
|
||||||
{
|
{
|
||||||
|
@ -103,7 +103,7 @@ SUITE(utils_tests)
|
|||||||
|
|
||||||
CHECK(narrow<uint32_t>(int32_t(0)) == 0);
|
CHECK(narrow<uint32_t>(int32_t(0)) == 0);
|
||||||
CHECK(narrow<uint32_t>(int32_t(1)) == 1);
|
CHECK(narrow<uint32_t>(int32_t(1)) == 1);
|
||||||
CHECK(narrow<uint32_t>(int32_max) == int32_max);
|
CHECK(narrow<uint32_t>(int32_max) == static_cast<uint32_t>(int32_max));
|
||||||
|
|
||||||
CHECK_THROW(narrow<uint32_t>(int32_t(-1)), narrowing_error);
|
CHECK_THROW(narrow<uint32_t>(int32_t(-1)), narrowing_error);
|
||||||
CHECK_THROW(narrow<uint32_t>(int32_min), narrowing_error);
|
CHECK_THROW(narrow<uint32_t>(int32_min), narrowing_error);
|
||||||
|
Loading…
Reference in New Issue
Block a user