Merge branch 'master' of https://github.com/neilmacintosh/GSL into dev/neilmac/fix_mismatched_pragma

This commit is contained in:
Neil MacIntosh
2016-08-02 18:10:07 -07:00
17 changed files with 5742 additions and 3569 deletions
+1 -1
View File
@@ -16,6 +16,6 @@ AllowShortLoopsOnASingleLine: true
PointerAlignment: Left
AlignConsecutiveAssignments: false
AlignTrailingComments: false
AlignTrailingComments: true
SpaceAfterCStyleCast: true
+3
View File
@@ -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
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
## Supported Platforms
The test suite that exercises GSL has been built and passes successfully on the following platforms:
+53 -49
View File
@@ -1,17 +1,17 @@
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
///////////////////////////////////////////////////////////////////////////////
#pragma once
@@ -21,36 +21,36 @@
#include "gsl_assert.h" // Ensures/Expects
#include "gsl_util.h" // finally()/narrow()/narrow_cast()...
#include "span.h" // span, strided_span...
#include "string_span.h" // zstring, string_span, zstring_builder...
#include "multi_span.h" // multi_span, strided_span...
#include "span.h" // span
#include "string_span.h" // zstring, string_span, zstring_builder...
#include <memory>
#ifdef _MSC_VER
// No MSVC does constexpr fully yet
#pragma push_macro("constexpr")
#define constexpr
#define constexpr
// MSVC 2013 workarounds
#if _MSC_VER <= 1800
// noexcept is not understood
// noexcept is not understood
#pragma push_macro("noexcept")
#define noexcept
#define noexcept
// turn off some misguided warnings
#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
namespace gsl
{
//
// GSL.owner: ownership pointers
// GSL.owner: ownership pointers
//
using std::unique_ptr;
using std::shared_ptr;
@@ -58,67 +58,74 @@ using std::shared_ptr;
template <class T>
using owner = T;
//
// not_null
//
// Restricts a pointer or smart pointer to only hold non-null values.
//
//
// Has zero size overhead over T.
//
// If T is a pointer (i.e. T == U*) then
// - allow construction from U* or U&
// If T is a pointer (i.e. T == U*) then
// - allow construction from U* or U&
// - disallow construction from nullptr_t
// - disallow default construction
// - ensure construction from U* fails with nullptr
// - allow implicit conversion to U*
//
template<class T>
template <class T>
class not_null
{
static_assert(std::is_assignable<T&, std::nullptr_t>::value, "T cannot be assigned nullptr.");
public:
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& operator=(const not_null &other) = default;
not_null(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>>
not_null(const not_null<U> &other)
not_null(const not_null<U>& other)
{
*this = other;
}
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();
return *this;
}
// prevents compilation when someone attempts to assign a nullptr
// prevents compilation when someone attempts to assign a nullptr
not_null(std::nullptr_t) = delete;
not_null(int) = delete;
not_null<T>& operator=(std::nullptr_t) = delete;
not_null<T>& operator=(int) = delete;
T get() const {
not_null<T>& operator=(int) = delete;
T get() const
{
#ifdef _MSC_VER
__assume(ptr_ != nullptr);
#endif
return ptr_;
} // the assume() should help the optimizer
operator T() const { return get(); }
operator T() const { return get(); }
T operator->() const { return get(); }
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 ptr_ == rhs; }
bool operator!=(const T& rhs) const { return !(*this == rhs); }
private:
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
void ensure_invariant() const { Expects(ptr_ != nullptr); }
@@ -138,14 +145,11 @@ private:
namespace std
{
template<class T>
struct hash<gsl::not_null<T>>
{
size_t operator()(const gsl::not_null<T> & value) const
{
return hash<T>{}(value);
}
};
template <class T>
struct hash<gsl::not_null<T>>
{
size_t operator()(const gsl::not_null<T>& value) const { return hash<T>{}(value); }
};
} // namespace std
@@ -158,7 +162,7 @@ namespace std
#undef noexcept
#pragma pop_macro("noexcept")
#pragma warning(pop)
#endif // _MSC_VER <= 1800
+34 -34
View File
@@ -1,17 +1,17 @@
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
///////////////////////////////////////////////////////////////////////////////
#pragma once
@@ -28,50 +28,50 @@
//
// 1. GSL_TERMINATE_ON_CONTRACT_VIOLATION: std::terminate will be called (default)
// 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))
#define GSL_TERMINATE_ON_CONTRACT_VIOLATION
#if !(defined(GSL_THROW_ON_CONTRACT_VIOLATION) ^ defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) ^ \
defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION))
#define GSL_TERMINATE_ON_CONTRACT_VIOLATION
#endif
#define GSL_STRINGIFY_DETAIL(x) #x
#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x)
//
// GSL.assert: assertions
//
namespace gsl
{
struct fail_fast : public std::runtime_error
struct fail_fast : public std::runtime_error
{
explicit fail_fast(char const* const message) : std::runtime_error(message) {}
explicit fail_fast(char const* const message) : std::runtime_error(message) {}
};
}
#if defined(GSL_THROW_ON_CONTRACT_VIOLATION)
#define Expects(cond) if (!(cond)) \
throw gsl::fail_fast("GSL: Precondition failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__));
#define Ensures(cond) if (!(cond)) \
throw gsl::fail_fast("GSL: Postcondition failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__));
#define Expects(cond) \
if (!(cond)) \
throw gsl::fail_fast("GSL: Precondition failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__));
#define Ensures(cond) \
if (!(cond)) \
throw gsl::fail_fast("GSL: Postcondition failure at " __FILE__ \
": " GSL_STRINGIFY(__LINE__));
#elif defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
#define Expects(cond) if (!(cond)) std::terminate();
#define Ensures(cond) if (!(cond)) std::terminate();
#define Expects(cond) \
if (!(cond)) std::terminate();
#define Ensures(cond) \
if (!(cond)) std::terminate();
#elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)
#define Expects(cond)
#define Ensures(cond)
#endif
#define Expects(cond)
#define Ensures(cond)
#endif
#endif // GSL_CONTRACTS_H
+125
View 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
+53 -32
View File
@@ -19,11 +19,11 @@
#ifndef GSL_UTIL_H
#define GSL_UTIL_H
#include "gsl_assert.h" // Ensures/Expects
#include "gsl_assert.h" // Ensures/Expects
#include <array>
#include <utility>
#include <type_traits>
#include <exception>
#include <type_traits>
#include <utility>
#ifdef _MSC_VER
@@ -32,7 +32,7 @@
#define constexpr
#pragma warning(push)
#pragma warning(disable: 4127) // conditional expression is constant
#pragma warning(disable : 4127) // conditional expression is constant
// MSVC 2013 workarounds
#if _MSC_VER <= 1800
@@ -42,13 +42,12 @@
// turn off some misguided warnings
#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
namespace gsl
{
//
@@ -60,18 +59,20 @@ template <class F>
class final_act
{
public:
explicit final_act(F f) noexcept
: f_(std::move(f)), invoke_(true)
{}
explicit final_act(F f) noexcept : f_(std::move(f)), invoke_(true) {}
final_act(final_act&& other) noexcept
: f_(std::move(other.f_)), invoke_(other.invoke_)
{ other.invoke_ = false; }
final_act(final_act&& other) noexcept : f_(std::move(other.f_)), invoke_(other.invoke_)
{
other.invoke_ = false;
}
final_act(const final_act&) = delete;
final_act& operator=(const final_act&) = delete;
~final_act() noexcept { if (invoke_) f_(); }
~final_act() noexcept
{
if (invoke_) f_();
}
private:
F f_;
@@ -80,34 +81,43 @@ private:
// finally() - convenience function to generate a final_act
template <class F>
inline final_act<F> finally(const F &f)
noexcept { return final_act<F>(f); }
inline final_act<F> finally(const F& f) noexcept
{
return final_act<F>(f);
}
template <class F>
inline final_act<F> finally(F &&f) noexcept
{ return final_act<F>(std::forward<F>(f)); }
inline final_act<F> finally(F&& f) noexcept
{
return final_act<F>(std::forward<F>(f));
}
// 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
{ return static_cast<T>(u); }
{
return static_cast<T>(u);
}
struct narrowing_error : public std::exception {};
struct narrowing_error : public std::exception
{
};
namespace details
{
template<class T, class U>
struct is_same_signedness : public std::integral_constant<bool, std::is_signed<T>::value == std::is_signed<U>::value>
{};
template <class T, class U>
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
template<class T, class U>
template <class T, class U>
inline T narrow(U u)
{
T t = narrow_cast<T>(u);
if (static_cast<U>(t) != u)
throw narrowing_error();
if (static_cast<U>(t) != u) throw narrowing_error();
if (!details::is_same_signedness<T, U>::value && ((t < T{}) != (u < U{})))
throw narrowing_error();
return t;
@@ -117,24 +127,35 @@ inline T narrow(U u)
// at() - Bounds-checked way of accessing static arrays, std::array, std::vector
//
template <class T, size_t N>
constexpr T& at(T(&arr)[N], size_t index)
{ Expects(index < N); return arr[index]; }
constexpr T& at(T (&arr)[N], size_t index)
{
Expects(index < N);
return arr[index];
}
template <class T, size_t N>
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>
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>
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
#ifdef _MSC_VER
#pragma warning(pop)
+2229
View File
File diff suppressed because it is too large Load Diff
+671 -2078
View File
File diff suppressed because it is too large Load Diff
+268 -413
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -33,7 +33,7 @@ else()
endif()
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++)
install(TARGETS ${name}
RUNTIME DESTINATION bin
@@ -45,6 +45,7 @@ function(add_gsl_test name)
endfunction()
add_gsl_test(span_tests)
add_gsl_test(multi_span_tests)
add_gsl_test(strided_span_tests)
add_gsl_test(string_span_tests)
add_gsl_test(at_tests)
@@ -53,3 +54,4 @@ add_gsl_test(notnull_tests)
add_gsl_test(assertion_tests)
add_gsl_test(utils_tests)
add_gsl_test(owner_tests)
add_gsl_test(byte_tests)
+2 -2
View File
@@ -15,7 +15,7 @@
///////////////////////////////////////////////////////////////////////////////
#include <UnitTest++/UnitTest++.h>
#include <span.h>
#include <multi_span.h>
#include <vector>
using namespace std;
@@ -58,7 +58,7 @@ SUITE(bounds_test)
auto itr = bounds.begin();
(void)itr;
#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();
+93
View 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(); }
File diff suppressed because it is too large Load Diff
+474 -905
View File
File diff suppressed because it is too large Load Diff
+48 -48
View File
@@ -15,7 +15,7 @@
///////////////////////////////////////////////////////////////////////////////
#include <UnitTest++/UnitTest++.h>
#include <span.h>
#include <multi_span.h>
#include <string>
#include <vector>
@@ -39,7 +39,7 @@ SUITE(strided_span_tests)
{
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 subsub = sub.section({1, 0, 0}, gsl::index<3>{1, 1, 1});
(void)subsub;
@@ -49,7 +49,7 @@ SUITE(strided_span_tests)
{
std::vector<int> data(5 * 10);
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 });
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 span constructor
// Check multi_span constructor
{
int arr[] = { 1, 2 };
// From non-cv-qualified source
{
const span<int> src = arr;
const multi_span<int> src = arr;
strided_span<int, 1> sav{ src, {2, 1} };
CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
@@ -102,9 +102,9 @@ SUITE(strided_span_tests)
#if _MSC_VER > 1800
//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
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
CHECK(sav_c.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav_c.bounds().strides() == index<1>{ 1 });
@@ -113,7 +113,7 @@ SUITE(strided_span_tests)
#if _MSC_VER > 1800
strided_span<volatile int, 1> sav_v{ src, {2, 1} };
#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
CHECK(sav_v.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav_v.bounds().strides() == index<1>{ 1 });
@@ -122,7 +122,7 @@ SUITE(strided_span_tests)
#if _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
#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
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav_cv.bounds().strides() == index<1>{ 1 });
@@ -131,7 +131,7 @@ SUITE(strided_span_tests)
// 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} };
CHECK(sav_c.bounds().index_bounds() == index<1>{ 2 });
@@ -141,7 +141,7 @@ SUITE(strided_span_tests)
#if _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
#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
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
@@ -151,7 +151,7 @@ SUITE(strided_span_tests)
// 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} };
CHECK(sav_v.bounds().index_bounds() == index<1>{ 2 });
@@ -161,7 +161,7 @@ SUITE(strided_span_tests)
#if _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
#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
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
CHECK(sav_cv.bounds().strides() == index<1>{ 1 });
@@ -170,7 +170,7 @@ SUITE(strided_span_tests)
// 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} };
CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
@@ -183,11 +183,11 @@ SUITE(strided_span_tests)
{
int arr[2] = { 4, 5 };
const span<int, 2> av(arr, 2);
span<const int, 2> av2{ av };
const multi_span<int, 2> av(arr, 2);
multi_span<const int, 2> av2{ av };
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} };
strided_span<const int, 1> sav{ src };
@@ -258,13 +258,13 @@ SUITE(strided_span_tests)
{
std::vector<int> data(5 * 10);
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}} };
#ifdef CONFIRM_COMPILATION_ERRORS
const strided_span<const int, 2> csav{ {src},{ { 5, 10 },{ 10, 1 } } };
#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];
CHECK(sav_sl[0] == 20);
@@ -317,7 +317,7 @@ SUITE(strided_span_tests)
TEST(strided_span_bounds)
{
int arr[] = { 0, 1, 2, 3 };
span<int> av(arr);
multi_span<int> av(arr);
{
// incorrect sections
@@ -413,18 +413,18 @@ SUITE(strided_span_tests)
strided_span<int, 1> sav2{ arr, { 1,1,1 } };
strided_span<int, 1> sav3{ av, { 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> sav6{ av.as_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> 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> sav7{ av.as_multi_span(dim<2>(), dim<2>()), { { 1,1 },{ 1,1 },{ 1,1 } } };
index<1> index{ 0, 1 };
strided_span<int, 1> sav8{ arr,{ 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> sav11{ av,{ { 1,1 },{ 1,1 } } };
strided_span<int, 2> sav12{ av.as_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> sav14{ av.as_span(dim<2>(), dim<2>()),{ { 1,1,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> sav14{ av.as_multi_span(dim<2>(), dim<2>()),{ { 1,1,1 },{ 1 } } };
}
#endif
}
@@ -432,7 +432,7 @@ SUITE(strided_span_tests)
TEST(strided_span_type_conversion)
{
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 } };
@@ -447,7 +447,7 @@ SUITE(strided_span_tests)
#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
{
@@ -460,10 +460,10 @@ SUITE(strided_span_tests)
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 } };
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<int, 2> sav3 = sav2.as_strided_span<int>();
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
{
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 };
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
{
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 };
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
{
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 };
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
{
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 };
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);
}
// 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_span<const byte, 1> sav2{ bytes, bounds };
@@ -522,7 +522,7 @@ SUITE(strided_span_tests)
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 } };
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
@@ -586,13 +586,13 @@ SUITE(strided_span_tests)
// static bounds
{
span<int, 8> av(arr, 8);
multi_span<int, 8> av(arr, 8);
iterate_every_other_element(av);
}
// dynamic bounds
{
span<int, dynamic_range> av(arr, 8);
multi_span<int, dynamic_range> av(arr, 8);
iterate_every_other_element(av);
}
}
@@ -606,13 +606,13 @@ SUITE(strided_span_tests)
arr[2 * i + 1] = i;
}
auto av = as_span(arr, 8);
auto av = as_multi_span(arr, 8);
iterate_every_other_element(av);
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};
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);
}
}
@@ -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);
}
{
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);
}
{
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);
}
{
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);
}
delete[] arr;
@@ -693,7 +693,7 @@ SUITE(strided_span_tests)
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; };
@@ -704,7 +704,7 @@ SUITE(strided_span_tests)
auto d1 = sizeof(int) * 12 / d2;
// 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()[1] == 12);
+5 -5
View File
@@ -40,14 +40,14 @@ SUITE(string_span_tests)
{
std::string s = "Hello there world";
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)
{
std::vector<char> vec(5, 'h');
string_span<> v = vec;
CHECK(v.length() == static_cast<string_span<>::size_type>(vec.size()));
string_span<> v {vec};
CHECK(v.length() == static_cast<string_span<>::index_type>(vec.size()));
}
TEST(TestStackArrayConstruction)
@@ -109,7 +109,7 @@ SUITE(string_span_tests)
char stack_string[] = "Hello";
cstring_span<> v = ensure_z(stack_string);
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);
}
@@ -746,7 +746,7 @@ SUITE(string_span_tests)
T create() { return 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)
{
+1 -1
View File
@@ -103,7 +103,7 @@ SUITE(utils_tests)
CHECK(narrow<uint32_t>(int32_t(0)) == 0);
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_min), narrowing_error);