mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
commit
70e735b911
15
.gitignore
vendored
15
.gitignore
vendored
@ -1 +1,14 @@
|
||||
tests/unittest-cpp
|
||||
tests/unittest-cpp
|
||||
CMakeFiles
|
||||
tests/CMakeFiles
|
||||
tests/Debug
|
||||
*.opensdf
|
||||
*.sdf
|
||||
tests/*tests.dir
|
||||
*.vcxproj
|
||||
*.vcxproj.filters
|
||||
*.sln
|
||||
*.tlog
|
||||
Testing/Temporary/*.*
|
||||
CMakeCache.txt
|
||||
*.suo
|
||||
|
@ -4,11 +4,11 @@ The Guidelines Support Library (GSL) contains functions and types that are sugge
|
||||
[C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines) maintained by the [Standard C++ Foundation](https://isocpp.org).
|
||||
This repo contains Microsoft's implementation of GSL.
|
||||
|
||||
The library includes types like `array_view<>`, `string_view<>`, `owner<>` and others.
|
||||
The library includes types like `span<T>`, `string_span`, `owner<>` and others.
|
||||
|
||||
The entire implementation is provided inline in the headers under the [include](./include) directory.
|
||||
The entire implementation is provided inline in the headers under the [include](./include) directory. The implementation generally assumes a platform that implements C++14 support. There are specific workarounds to support MSVC 2013 and 2015.
|
||||
|
||||
While some types have been broken out into their own headers (e.g. [include/array_view.h](./include/array_view.h)),
|
||||
While some types have been broken out into their own headers (e.g. [include/span.h](./include/span.h)),
|
||||
it is simplest to just include [gsl.h](./include/gsl.h) and gain access to the entire library.
|
||||
|
||||
> NOTE: We encourage contributions that improve or refine any of the types in this library as well as ports to
|
||||
|
1998
include/array_view.h
1998
include/array_view.h
File diff suppressed because it is too large
Load Diff
@ -19,8 +19,8 @@
|
||||
#ifndef GSL_GSL_H
|
||||
#define GSL_GSL_H
|
||||
|
||||
#include "array_view.h" // array_view, strided_array_view...
|
||||
#include "string_view.h" // zstring, string_view, zstring_builder...
|
||||
#include "span.h" // span, strided_span...
|
||||
#include "string_span.h" // zstring, string_span, zstring_builder...
|
||||
#include <memory>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
1992
include/span.h
Normal file
1992
include/span.h
Normal file
File diff suppressed because it is too large
Load Diff
227
include/string_span.h
Normal file
227
include/string_span.h
Normal file
@ -0,0 +1,227 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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_STRING_SPAN_H
|
||||
#define GSL_STRING_SPAN_H
|
||||
|
||||
#include "span.h"
|
||||
#include <cstring>
|
||||
|
||||
// VS 2013 workarounds
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER <= 1800
|
||||
|
||||
#pragma push_macro("GSL_MSVC_HAS_TYPE_DEDUCTION_BUG")
|
||||
#define GSL_MSVC_HAS_TYPE_DEDUCTION_BUG
|
||||
|
||||
#endif // _MSC_VER <= 1800
|
||||
#endif // _MSC_VER
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
//
|
||||
// czstring and wzstring
|
||||
//
|
||||
// These are "tag" typedef's for C-style strings (i.e. null-terminated character arrays)
|
||||
// that allow static analysis to help find bugs.
|
||||
//
|
||||
// There are no additional features/semantics that we can find a way to add inside the
|
||||
// type system for these types that will not either incur significant runtime costs or
|
||||
// (sometimes needlessly) break existing programs when introduced.
|
||||
//
|
||||
template<std::ptrdiff_t Extent = dynamic_range>
|
||||
using czstring = const char*;
|
||||
|
||||
template<std::ptrdiff_t Extent = dynamic_range>
|
||||
using cwzstring = const wchar_t*;
|
||||
|
||||
template<std::ptrdiff_t Extent = dynamic_range>
|
||||
using zstring = char*;
|
||||
|
||||
template<std::ptrdiff_t Extent = dynamic_range>
|
||||
using wzstring = wchar_t*;
|
||||
|
||||
//
|
||||
// string_span and relatives
|
||||
//
|
||||
// Note that Extent is always single-dimension only
|
||||
//
|
||||
template <class CharT, std::ptrdiff_t Extent = dynamic_range>
|
||||
using basic_string_span = span<CharT, Extent>;
|
||||
|
||||
template<std::ptrdiff_t Extent = dynamic_range>
|
||||
using string_span = basic_string_span<char, Extent>;
|
||||
|
||||
template<std::ptrdiff_t Extent = dynamic_range>
|
||||
using cstring_span = basic_string_span<const char, Extent>;
|
||||
|
||||
template<std::ptrdiff_t Extent = dynamic_range>
|
||||
using wstring_span = basic_string_span<wchar_t, Extent>;
|
||||
|
||||
template<std::ptrdiff_t Extent = dynamic_range>
|
||||
using cwstring_span = basic_string_span<const wchar_t, Extent>;
|
||||
|
||||
|
||||
//
|
||||
// ensure_sentinel()
|
||||
//
|
||||
// Provides a way to obtain an span from a contiguous sequence
|
||||
// that ends with a (non-inclusive) sentinel value.
|
||||
//
|
||||
// Will fail-fast if sentinel cannot be found before max elements are examined.
|
||||
//
|
||||
template<class T, const T Sentinel>
|
||||
span<T, dynamic_range> ensure_sentinel(const T* seq, std::ptrdiff_t max = PTRDIFF_MAX)
|
||||
{
|
||||
auto cur = seq;
|
||||
while ((cur - seq) < max && *cur != Sentinel) ++cur;
|
||||
fail_fast_assert(*cur == Sentinel);
|
||||
return{ seq, cur - seq };
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ensure_z - creates a string_span for a czstring or cwzstring.
|
||||
// Will fail fast if a null-terminator cannot be found before
|
||||
// the limit of size_type.
|
||||
//
|
||||
template<class T>
|
||||
inline basic_string_span<T, dynamic_range> ensure_z(T* const & sz, std::ptrdiff_t max = PTRDIFF_MAX)
|
||||
{
|
||||
return ensure_sentinel<T, 0>(sz, max);
|
||||
}
|
||||
|
||||
// TODO (neilmac) there is probably a better template-magic way to get the const and non-const overloads to share an implementation
|
||||
inline basic_string_span<char, dynamic_range> ensure_z(char* const& sz, std::ptrdiff_t max)
|
||||
{
|
||||
auto len = strnlen(sz, max);
|
||||
fail_fast_assert(sz[len] == 0);
|
||||
return{ sz, static_cast<std::ptrdiff_t>(len) };
|
||||
}
|
||||
|
||||
inline basic_string_span<const char, dynamic_range> ensure_z(const char* const& sz, std::ptrdiff_t max)
|
||||
{
|
||||
auto len = strnlen(sz, max);
|
||||
fail_fast_assert(sz[len] == 0); return{ sz, static_cast<std::ptrdiff_t>(len) };
|
||||
}
|
||||
|
||||
inline basic_string_span<wchar_t, dynamic_range> ensure_z(wchar_t* const& sz, std::ptrdiff_t max)
|
||||
{
|
||||
auto len = wcsnlen(sz, max);
|
||||
fail_fast_assert(sz[len] == 0); return{ sz, static_cast<std::ptrdiff_t>(len) };
|
||||
}
|
||||
|
||||
inline basic_string_span<const wchar_t, dynamic_range> ensure_z(const wchar_t* const& sz, std::ptrdiff_t max)
|
||||
{
|
||||
auto len = wcsnlen(sz, max);
|
||||
fail_fast_assert(sz[len] == 0); return{ sz, static_cast<std::ptrdiff_t>(len) };
|
||||
}
|
||||
|
||||
template<class T, size_t N>
|
||||
basic_string_span<T, dynamic_range> ensure_z(T(&sz)[N]) { return ensure_z(&sz[0], static_cast<std::ptrdiff_t>(N)); }
|
||||
|
||||
template<class Cont>
|
||||
basic_string_span<typename std::remove_pointer<typename Cont::pointer>::type, dynamic_range> ensure_z(Cont& cont)
|
||||
{
|
||||
return ensure_z(cont.data(), static_cast<std::ptrdiff_t>(cont.length()));
|
||||
}
|
||||
|
||||
//
|
||||
// to_string() allow (explicit) conversions from string_span to string
|
||||
//
|
||||
#ifndef GSL_MSVC_HAS_TYPE_DEDUCTION_BUG
|
||||
|
||||
template<class CharT, ptrdiff_t Extent>
|
||||
std::basic_string<typename std::remove_const<CharT>::type> to_string(basic_string_span<CharT, Extent> view)
|
||||
{
|
||||
return{ view.data(), static_cast<size_t>(view.length()) };
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline std::string to_string(cstring_span<> view)
|
||||
{
|
||||
return{ view.data(), view.length() };
|
||||
}
|
||||
|
||||
inline std::string to_string(string_span<> view)
|
||||
{
|
||||
return{ view.data(), view.length() };
|
||||
}
|
||||
|
||||
inline std::wstring to_string(cwstring_span<> view)
|
||||
{
|
||||
return{ view.data(), view.length() };
|
||||
}
|
||||
|
||||
inline std::wstring to_string(wstring_span<> view)
|
||||
{
|
||||
return{ view.data(), view.length() };
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class CharT, size_t Extent = dynamic_range>
|
||||
class basic_zstring_builder
|
||||
{
|
||||
public:
|
||||
using string_span_type = basic_string_span<CharT, Extent>;
|
||||
using value_type = CharT;
|
||||
using pointer = CharT*;
|
||||
using size_type = typename string_span_type::size_type;
|
||||
using iterator = typename string_span_type::iterator;
|
||||
|
||||
basic_zstring_builder(CharT* data, size_type length) : sv_(data, length) {}
|
||||
|
||||
template<size_t Size>
|
||||
basic_zstring_builder(CharT(&arr)[Size]) : sv_(arr) {}
|
||||
|
||||
pointer data() const { return sv_.data(); }
|
||||
string_span_type view() const { return sv_; }
|
||||
|
||||
size_type length() const { return sv_.length(); }
|
||||
|
||||
pointer assume0() const { return data(); }
|
||||
string_span_type ensure_z() const { return gsl::ensure_z(sv_); }
|
||||
|
||||
iterator begin() const { return sv_.begin(); }
|
||||
iterator end() const { return sv_.end(); }
|
||||
|
||||
private:
|
||||
string_span_type sv_;
|
||||
};
|
||||
|
||||
template <size_t Max = dynamic_range>
|
||||
using zstring_builder = basic_zstring_builder<char, Max>;
|
||||
|
||||
template <size_t Max = dynamic_range>
|
||||
using wzstring_builder = basic_zstring_builder<wchar_t, Max>;
|
||||
}
|
||||
|
||||
// VS 2013 workarounds
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER <= 1800
|
||||
|
||||
#pragma pop_macro("GSL_MSVC_HAS_TYPE_DEDUCTION_BUG")
|
||||
#undef GSL_MSVC_HAS_TYPE_DEDUCTION_BUG
|
||||
|
||||
#endif // _MSC_VER <= 1800
|
||||
#endif // _MSC_VER
|
||||
|
||||
|
||||
#endif // GSL_STRING_SPAN_H
|
@ -1,183 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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_STRING_VIEW_H
|
||||
#define GSL_STRING_VIEW_H
|
||||
|
||||
#include "array_view.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
//
|
||||
// czstring and wzstring
|
||||
//
|
||||
// These are "tag" typedef's for C-style strings (i.e. null-terminated character arrays)
|
||||
// that allow static analysis to help find bugs.
|
||||
//
|
||||
// There are no additional features/semantics that we can find a way to add inside the
|
||||
// type system for these types that will not either incur significant runtime costs or
|
||||
// (sometimes needlessly) break existing programs when introduced.
|
||||
//
|
||||
template<size_t Max = dynamic_range>
|
||||
using czstring = const char*;
|
||||
|
||||
template<size_t Max = dynamic_range>
|
||||
using cwzstring = const wchar_t*;
|
||||
|
||||
template<size_t Max = dynamic_range>
|
||||
using zstring = char*;
|
||||
|
||||
template<size_t Max = dynamic_range>
|
||||
using wzstring = wchar_t*;
|
||||
|
||||
//
|
||||
// string_view and relatives
|
||||
//
|
||||
// Note that Extent is always single-dimension only
|
||||
// Note that SizeType is defaulted to be smaller than size_t which is the array_view default
|
||||
//
|
||||
// TODO (neilmac) once array_view regains configurable size_type, update these typedef's
|
||||
//
|
||||
template <class CharT, size_t Extent = dynamic_range>
|
||||
using basic_string_view = array_view<CharT, Extent>;
|
||||
|
||||
template<size_t Extent = dynamic_range>
|
||||
using string_view = basic_string_view<char, Extent>;
|
||||
|
||||
template<size_t Extent = dynamic_range>
|
||||
using cstring_view = basic_string_view<const char, Extent>;
|
||||
|
||||
template<size_t Extent = dynamic_range>
|
||||
using wstring_view = basic_string_view<wchar_t, Extent>;
|
||||
|
||||
template<size_t Extent = dynamic_range>
|
||||
using cwstring_view = basic_string_view<const wchar_t, Extent>;
|
||||
|
||||
|
||||
//
|
||||
// ensure_sentinel()
|
||||
//
|
||||
// Provides a way to obtain an array_view from a contiguous sequence
|
||||
// that ends with a (non-inclusive) sentinel value.
|
||||
//
|
||||
// Will fail-fast if sentinel cannot be found before max elements are examined.
|
||||
//
|
||||
template<class T, class SizeType, const T Sentinel>
|
||||
array_view<T, dynamic_range> ensure_sentinel(const T* seq, SizeType max = std::numeric_limits<SizeType>::max())
|
||||
{
|
||||
auto cur = seq;
|
||||
while ((cur - seq) < max && *cur != Sentinel) ++cur;
|
||||
fail_fast_assert(*cur == Sentinel);
|
||||
return{ seq, cur - seq };
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ensure_z - creates a string_view for a czstring or cwzstring.
|
||||
// Will fail fast if a null-terminator cannot be found before
|
||||
// the limit of size_type.
|
||||
//
|
||||
template<class T>
|
||||
inline basic_string_view<T, dynamic_range> ensure_z(T* const & sz, size_t max = std::numeric_limits<size_t>::max())
|
||||
{
|
||||
return ensure_sentinel<0>(sz, max);
|
||||
}
|
||||
|
||||
// TODO (neilmac) there is probably a better template-magic way to get the const and non-const overloads to share an implementation
|
||||
inline basic_string_view<char, dynamic_range> ensure_z(char* const & sz, size_t max)
|
||||
{
|
||||
auto len = strnlen(sz, max);
|
||||
fail_fast_assert(sz[len] == 0); return{ sz, len };
|
||||
}
|
||||
|
||||
inline basic_string_view<const char, dynamic_range> ensure_z(const char* const& sz, size_t max)
|
||||
{
|
||||
auto len = strnlen(sz, max);
|
||||
fail_fast_assert(sz[len] == 0); return{ sz, len };
|
||||
}
|
||||
|
||||
inline basic_string_view<wchar_t, dynamic_range> ensure_z(wchar_t* const & sz, size_t max)
|
||||
{
|
||||
auto len = wcsnlen(sz, max);
|
||||
fail_fast_assert(sz[len] == 0); return{ sz, len };
|
||||
}
|
||||
|
||||
inline basic_string_view<const wchar_t, dynamic_range> ensure_z(const wchar_t* const & sz, size_t max)
|
||||
{
|
||||
auto len = wcsnlen(sz, max);
|
||||
fail_fast_assert(sz[len] == 0); return{ sz, len };
|
||||
}
|
||||
|
||||
template<class T, size_t N>
|
||||
basic_string_view<T, dynamic_range> ensure_z(T(&sz)[N]) { return ensure_z(&sz[0], N); }
|
||||
|
||||
template<class Cont>
|
||||
basic_string_view<typename std::remove_pointer<typename Cont::pointer>::type, dynamic_range> ensure_z(Cont& cont)
|
||||
{
|
||||
return ensure_z(cont.data(), cont.length());
|
||||
}
|
||||
|
||||
//
|
||||
// to_string() allow (explicit) conversions from string_view to string
|
||||
//
|
||||
template<class CharT, size_t Extent>
|
||||
std::basic_string<typename std::remove_const<CharT>::type> to_string(basic_string_view<CharT, Extent> view)
|
||||
{
|
||||
return{ view.data(), view.length() };
|
||||
}
|
||||
|
||||
|
||||
template<class CharT, size_t Extent = dynamic_range>
|
||||
class basic_zstring_builder
|
||||
{
|
||||
public:
|
||||
using string_view_type = basic_string_view<CharT, Extent>;
|
||||
using value_type = CharT;
|
||||
using pointer = CharT*;
|
||||
using size_type = typename string_view_type::size_type;
|
||||
using iterator = typename string_view_type::iterator;
|
||||
|
||||
basic_zstring_builder(CharT* data, size_type length) : sv_(data, length) {}
|
||||
|
||||
template<size_t Size>
|
||||
basic_zstring_builder(CharT(&arr)[Size]) : sv_(arr) {}
|
||||
|
||||
pointer data() const { return sv_.data(); }
|
||||
string_view_type view() const { return sv_; }
|
||||
|
||||
size_type length() const { return sv_.length(); }
|
||||
|
||||
pointer assume0() const { return data(); }
|
||||
string_view_type ensure_z() const { return gsl::ensure_z(sv_); }
|
||||
|
||||
iterator begin() const { return sv_.begin(); }
|
||||
iterator end() const { return sv_.end(); }
|
||||
|
||||
private:
|
||||
string_view_type sv_;
|
||||
};
|
||||
|
||||
template <size_t Max = dynamic_range>
|
||||
using zstring_builder = basic_zstring_builder<char, Max>;
|
||||
|
||||
template <size_t Max = dynamic_range>
|
||||
using wzstring_builder = basic_zstring_builder<wchar_t, Max>;
|
||||
}
|
||||
|
||||
#endif // GSL_STRING_VIEW_H
|
@ -14,14 +14,15 @@ add_definitions(-DGSL_THROWS_FOR_TESTING)
|
||||
if(MSVC14 OR MSVC12) # has the support we need
|
||||
# remove unnecessary warnings about unchecked iterators
|
||||
add_definitions(-D_SCL_SECURE_NO_WARNINGS)
|
||||
add_compile_options(/W4)
|
||||
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} -std=c++14")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -Wno-missing-braces")
|
||||
elseif(COMPILER_SUPPORTS_CXX11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wno-missing-braces")
|
||||
else()
|
||||
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
|
||||
endif()
|
||||
@ -43,8 +44,8 @@ function(add_gsl_test name)
|
||||
)
|
||||
endfunction()
|
||||
|
||||
add_gsl_test(array_view_tests)
|
||||
add_gsl_test(string_view_tests)
|
||||
add_gsl_test(span_tests)
|
||||
add_gsl_test(string_span_tests)
|
||||
add_gsl_test(at_tests)
|
||||
add_gsl_test(bounds_tests)
|
||||
add_gsl_test(notnull_tests)
|
||||
|
@ -15,7 +15,7 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <UnitTest++/UnitTest++.h>
|
||||
#include <array_view.h>
|
||||
#include <span.h>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
@ -23,16 +23,18 @@ using namespace gsl;;
|
||||
|
||||
namespace
|
||||
{
|
||||
void use(unsigned int&) {}
|
||||
void use(std::ptrdiff_t&) {}
|
||||
}
|
||||
|
||||
SUITE(bounds_test)
|
||||
{
|
||||
TEST(basic_bounds)
|
||||
{
|
||||
for (auto point : static_bounds <unsigned int, dynamic_range, 3, 4 > { 2 })
|
||||
for (auto point : static_bounds<dynamic_range, 3, 4 > { 2 })
|
||||
{
|
||||
for (unsigned int j = 0; j < decltype(point)::rank; j++)
|
||||
for (decltype(point)::size_type j = 0;
|
||||
j < static_cast<decltype(point)::size_type>(decltype(point)::rank);
|
||||
j++)
|
||||
{
|
||||
use(j);
|
||||
use(point[j]);
|
||||
@ -42,24 +44,25 @@ SUITE(bounds_test)
|
||||
|
||||
TEST(bounds_basic)
|
||||
{
|
||||
static_bounds<size_t, 3, 4, 5> b;
|
||||
static_bounds<3, 4, 5> b;
|
||||
auto a = b.slice();
|
||||
static_bounds<size_t, 4, dynamic_range, 2> x{ 4 };
|
||||
(void)a;
|
||||
static_bounds<4, dynamic_range, 2> x{ 4 };
|
||||
x.slice().slice();
|
||||
}
|
||||
|
||||
TEST (arrayview_iterator)
|
||||
{
|
||||
static_bounds<size_t, 4, dynamic_range, 2> bounds{ 3 };
|
||||
static_bounds<4, dynamic_range, 2> bounds{ 3 };
|
||||
|
||||
auto itr = bounds.begin();
|
||||
|
||||
(void)itr;
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
array_view< int, 4, dynamic_range, 2> av(nullptr, bounds);
|
||||
span<int, 4, dynamic_range, 2> av(nullptr, bounds);
|
||||
|
||||
auto itr2 = av.cbegin();
|
||||
|
||||
for (auto & v : av) {
|
||||
for (auto& v : av) {
|
||||
v = 4;
|
||||
}
|
||||
fill(av.begin(), av.end(), 0);
|
||||
@ -68,24 +71,25 @@ SUITE(bounds_test)
|
||||
|
||||
TEST (bounds_convertible)
|
||||
{
|
||||
static_bounds<size_t, 7, 4, 2> b1;
|
||||
static_bounds<size_t, 7, dynamic_range, 2> b2 = b1;
|
||||
|
||||
static_bounds<7, 4, 2> b1;
|
||||
static_bounds<7, dynamic_range, 2> b2 = b1;
|
||||
(void)b2;
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
static_bounds<size_t, 7, dynamic_range, 1> b4 = b2;
|
||||
static_bounds<7, dynamic_range, 1> b4 = b2;
|
||||
#endif
|
||||
|
||||
static_bounds<size_t, dynamic_range, dynamic_range, dynamic_range> b3 = b1;
|
||||
static_bounds<int, 7, 4, 2> b4 = b3;
|
||||
static_bounds<dynamic_range, dynamic_range, dynamic_range> b3 = b1;
|
||||
static_bounds<7, 4, 2> b4 = b3;
|
||||
(void)b4;
|
||||
|
||||
static_bounds<size_t, dynamic_range> b11;
|
||||
static_bounds<dynamic_range> b11;
|
||||
|
||||
static_bounds<size_t, dynamic_range> b5;
|
||||
static_bounds<size_t, 34> b6;
|
||||
static_bounds<dynamic_range> b5;
|
||||
static_bounds<34> b6;
|
||||
|
||||
b5 = static_bounds<size_t, 20>();
|
||||
b5 = static_bounds<20>();
|
||||
CHECK_THROW(b6 = b5, fail_fast);
|
||||
b5 = static_bounds<size_t, 34>();
|
||||
b5 = static_bounds<34>();
|
||||
b6 = b5;
|
||||
|
||||
CHECK(b5 == b6);
|
||||
|
@ -69,7 +69,8 @@ SUITE(NotNullTests)
|
||||
MyDerived derived;
|
||||
Unrelated unrelated;
|
||||
not_null<Unrelated*> u = &unrelated;
|
||||
not_null<MyDerived*> p = &derived;
|
||||
(void)u;
|
||||
not_null<MyDerived*> p = &derived;
|
||||
not_null<MyBase*> q = &base;
|
||||
q = p; // allowed with heterogeneous copy ctor
|
||||
CHECK(q == p);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -15,39 +15,40 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <UnitTest++/UnitTest++.h>
|
||||
#include <string_view.h>
|
||||
#include <string_span.h>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsl;
|
||||
|
||||
SUITE(string_view_tests)
|
||||
|
||||
SUITE(string_span_tests)
|
||||
{
|
||||
|
||||
TEST(TestLiteralConstruction)
|
||||
{
|
||||
cwstring_view<> v = ensure_z(L"Hello");
|
||||
cwstring_span<> v = ensure_z(L"Hello");
|
||||
|
||||
CHECK(5 == v.length());
|
||||
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
wstring_view<> v2 = ensure0(L"Hello");
|
||||
wstring_span<> v2 = ensure0(L"Hello");
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(TestConstructFromStdString)
|
||||
{
|
||||
std::string s = "Hello there world";
|
||||
cstring_view<> v = s;
|
||||
CHECK(v.length() == s.length());
|
||||
cstring_span<> v = s;
|
||||
CHECK(v.length() == static_cast<cstring_span<>::size_type>(s.length()));
|
||||
}
|
||||
|
||||
TEST(TestConstructFromStdVector)
|
||||
{
|
||||
std::vector<char> vec(5, 'h');
|
||||
string_view<> v = vec;
|
||||
CHECK(v.length() == vec.size());
|
||||
string_span<> v = vec;
|
||||
CHECK(v.length() == static_cast<string_span<>::size_type>(vec.size()));
|
||||
}
|
||||
|
||||
TEST(TestStackArrayConstruction)
|
||||
@ -55,47 +56,68 @@ SUITE(string_view_tests)
|
||||
wchar_t stack_string[] = L"Hello";
|
||||
|
||||
{
|
||||
cwstring_view<> v = ensure_z(stack_string);
|
||||
cwstring_span<> v = ensure_z(stack_string);
|
||||
CHECK(v.length() == 5);
|
||||
CHECK(v.used_length() == v.length());
|
||||
}
|
||||
|
||||
{
|
||||
cwstring_view<> v = stack_string;
|
||||
cwstring_span<> v = stack_string;
|
||||
CHECK(v.length() == 6);
|
||||
CHECK(v.used_length() == v.length());
|
||||
}
|
||||
|
||||
{
|
||||
wstring_view<> v = ensure_z(stack_string);
|
||||
wstring_span<> v = ensure_z(stack_string);
|
||||
CHECK(v.length() == 5);
|
||||
CHECK(v.used_length() == v.length());
|
||||
}
|
||||
|
||||
{
|
||||
wstring_view<> v = stack_string;
|
||||
wstring_span<> v = stack_string;
|
||||
CHECK(v.length() == 6);
|
||||
CHECK(v.used_length() == v.length());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TestConstructFromConstCharPointer)
|
||||
{
|
||||
const char* s = "Hello";
|
||||
cstring_span<> v = ensure_z(s);
|
||||
CHECK(v.length() == 5);
|
||||
CHECK(v.used_length() == v.length());
|
||||
}
|
||||
|
||||
TEST(TestConversionToConst)
|
||||
{
|
||||
char stack_string[] = "Hello";
|
||||
string_view<> v = ensure_z(stack_string);
|
||||
cstring_view<> v2 = v;
|
||||
string_span<> v = ensure_z(stack_string);
|
||||
cstring_span<> v2 = v;
|
||||
CHECK(v.length() == v2.length());
|
||||
}
|
||||
|
||||
TEST(TestConversionFromConst)
|
||||
{
|
||||
char stack_string[] = "Hello";
|
||||
cstring_view<> v = ensure_z(stack_string);
|
||||
cstring_span<> v = ensure_z(stack_string);
|
||||
(void)v;
|
||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||
string_view<> v2 = v;
|
||||
string_view<> v3 = "Hello";
|
||||
string_span<> v2 = v;
|
||||
string_span<> v3 = "Hello";
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(TestToString)
|
||||
{
|
||||
auto s = gsl::to_string(cstring_span<>{});
|
||||
CHECK(s.length() == 0);
|
||||
|
||||
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(s2.length() == 5);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int, const char *[])
|
Loading…
Reference in New Issue
Block a user