[base] Implement Extent in base::span
This change implements static extents in base::span. These spans can be automatically created from array types, where the size is known at compile time. Furthermore, they allow for compile time checks when invoking templated first(), last() and subspan(). Bug: 828324 Change-Id: Ice309ab8d377a91331170bfba8ac82a31dad7cd1 Reviewed-on: https://chromium-review.googlesource.com/1021735 Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org> Reviewed-by: David Benjamin <davidben@chromium.org> Reviewed-by: Jochen Eisinger <jochen@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Cr-Commit-Position: refs/heads/master@{#555333}
This commit is contained in:
base/containers
chrome/browser/extensions
components
crx_file
policy
core
common
variations
content/browser/web_package
crypto
extensions/browser
net/quic/chromium/crypto
@ -18,7 +18,10 @@
|
||||
|
||||
namespace base {
|
||||
|
||||
template <typename T>
|
||||
// [views.constants]
|
||||
constexpr size_t dynamic_extent = -1;
|
||||
|
||||
template <typename T, size_t Extent = dynamic_extent>
|
||||
class span;
|
||||
|
||||
namespace internal {
|
||||
@ -26,8 +29,8 @@ namespace internal {
|
||||
template <typename T>
|
||||
struct IsSpanImpl : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct IsSpanImpl<span<T>> : std::true_type {};
|
||||
template <typename T, size_t Extent>
|
||||
struct IsSpanImpl<span<T, Extent>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
using IsSpan = IsSpanImpl<std::decay_t<T>>;
|
||||
@ -45,10 +48,10 @@ template <typename T>
|
||||
using IsCArray = std::is_array<std::remove_reference_t<T>>;
|
||||
|
||||
template <typename From, typename To>
|
||||
using IsLegalSpanConversion = std::is_convertible<From (*)[], To (*)[]>;
|
||||
using IsLegalDataConversion = std::is_convertible<From (*)[], To (*)[]>;
|
||||
|
||||
template <typename Container, typename T>
|
||||
using ContainerHasConvertibleData = IsLegalSpanConversion<
|
||||
using ContainerHasConvertibleData = IsLegalDataConversion<
|
||||
std::remove_pointer_t<decltype(base::data(std::declval<Container>()))>,
|
||||
T>;
|
||||
|
||||
@ -56,14 +59,16 @@ template <typename Container>
|
||||
using ContainerHasIntegralSize =
|
||||
std::is_integral<decltype(base::size(std::declval<Container>()))>;
|
||||
|
||||
template <typename From, typename To>
|
||||
template <typename From, size_t FromExtent, typename To, size_t ToExtent>
|
||||
using EnableIfLegalSpanConversion =
|
||||
std::enable_if_t<IsLegalSpanConversion<From, To>::value>;
|
||||
std::enable_if_t<(ToExtent == dynamic_extent || ToExtent == FromExtent) &&
|
||||
IsLegalDataConversion<From, To>::value>;
|
||||
|
||||
// SFINAE check if Array can be converted to a span<T>.
|
||||
template <typename Array, typename T>
|
||||
template <typename Array, size_t N, typename T, size_t Extent>
|
||||
using EnableIfSpanCompatibleArray =
|
||||
std::enable_if_t<ContainerHasConvertibleData<Array, T>::value>;
|
||||
std::enable_if_t<(Extent == dynamic_extent || Extent == N) &&
|
||||
ContainerHasConvertibleData<Array, T>::value>;
|
||||
|
||||
// SFINAE check if Container can be converted to a span<T>.
|
||||
template <typename Container, typename T>
|
||||
@ -135,26 +140,17 @@ using EnableIfSpanCompatibleContainer =
|
||||
// -------------------------------------------
|
||||
//
|
||||
// https://wg21.link/P0122 is the latest working group proposal, Chromium
|
||||
// currently implements R7. The biggest difference is span does not support a
|
||||
// static extent template parameter. Other differences are documented in
|
||||
// subsections below.
|
||||
//
|
||||
// Differences from [views.constants]:
|
||||
// - no dynamic_extent constant
|
||||
// currently implements R7. Differences between the proposal and the
|
||||
// implementation are documented in subsections below.
|
||||
//
|
||||
// Differences from [span.objectrep]:
|
||||
// - as_bytes() and as_writable_bytes() return spans of uint8_t instead of
|
||||
// std::byte
|
||||
//
|
||||
// Differences in constants and types:
|
||||
// - no index_type type alias
|
||||
// - no different_type type alias
|
||||
// - no extent constant
|
||||
// - index_type is aliased to size_t
|
||||
//
|
||||
// Differences from [span.sub]:
|
||||
// - no templated first()
|
||||
// - no templated last()
|
||||
// - no templated subspan()
|
||||
// - using size_t instead of ptrdiff_t for indexing
|
||||
//
|
||||
// Differences from [span.obs]:
|
||||
@ -162,101 +158,174 @@ using EnableIfSpanCompatibleContainer =
|
||||
//
|
||||
// Differences from [span.elem]:
|
||||
// - using size_t instead of ptrdiff_t for indexing
|
||||
//
|
||||
// Furthermore, all constructors and methods are marked noexcept due to the lack
|
||||
// of exceptions in Chromium.
|
||||
//
|
||||
// Due to the lack of class template argument deduction guides in C++14
|
||||
// appropriate make_span() utility functions are provided.
|
||||
|
||||
// [span], class template span
|
||||
template <typename T>
|
||||
template <typename T, size_t Extent>
|
||||
class span {
|
||||
public:
|
||||
using element_type = T;
|
||||
using value_type = std::remove_cv_t<T>;
|
||||
using index_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = T*;
|
||||
using reference = T&;
|
||||
using iterator = T*;
|
||||
using const_iterator = const T*;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
static constexpr index_type extent = Extent;
|
||||
|
||||
// [span.cons], span constructors, copy, assignment, and destructor
|
||||
constexpr span() noexcept : data_(nullptr), size_(0) {}
|
||||
constexpr span(T* data, size_t size) noexcept : data_(data), size_(size) {}
|
||||
constexpr span() noexcept : data_(nullptr), size_(0) {
|
||||
static_assert(Extent == dynamic_extent || Extent == 0, "Invalid Extent");
|
||||
}
|
||||
|
||||
constexpr span(T* data, size_t size) noexcept : data_(data), size_(size) {
|
||||
CHECK(Extent == dynamic_extent || Extent == size);
|
||||
}
|
||||
|
||||
// Artificially templatized to break ambiguity for span(ptr, 0).
|
||||
template <typename = void>
|
||||
constexpr span(T* begin, T* end)
|
||||
: data_(begin), size_(std::distance(begin, end)) {
|
||||
CHECK_LE(begin, end);
|
||||
constexpr span(T* begin, T* end) noexcept : span(begin, end - begin) {
|
||||
// Note: CHECK_LE is not constexpr, hence regular CHECK must be used.
|
||||
CHECK(begin <= end);
|
||||
}
|
||||
template <size_t N,
|
||||
typename = internal::EnableIfSpanCompatibleArray<T (&)[N], T>>
|
||||
|
||||
template <
|
||||
size_t N,
|
||||
typename = internal::EnableIfSpanCompatibleArray<T (&)[N], N, T, Extent>>
|
||||
constexpr span(T (&array)[N]) noexcept : span(base::data(array), N) {}
|
||||
|
||||
template <
|
||||
size_t N,
|
||||
typename =
|
||||
internal::EnableIfSpanCompatibleArray<std::array<value_type, N>&, T>>
|
||||
typename = internal::
|
||||
EnableIfSpanCompatibleArray<std::array<value_type, N>&, N, T, Extent>>
|
||||
constexpr span(std::array<value_type, N>& array) noexcept
|
||||
: span(base::data(array), N) {}
|
||||
|
||||
template <size_t N,
|
||||
typename = internal::EnableIfSpanCompatibleArray<
|
||||
const std::array<value_type, N>&,
|
||||
T>>
|
||||
N,
|
||||
T,
|
||||
Extent>>
|
||||
constexpr span(const std::array<value_type, N>& array) noexcept
|
||||
: span(base::data(array), N) {}
|
||||
// Conversion from a container that provides |T* data()| and |integral_type
|
||||
// size()|.
|
||||
|
||||
// Conversion from a container that has compatible base::data() and integral
|
||||
// base::size().
|
||||
template <typename Container,
|
||||
typename = internal::EnableIfSpanCompatibleContainer<Container&, T>>
|
||||
constexpr span(Container& container)
|
||||
constexpr span(Container& container) noexcept
|
||||
: span(base::data(container), base::size(container)) {}
|
||||
|
||||
template <
|
||||
typename Container,
|
||||
typename = internal::EnableIfSpanCompatibleContainer<const Container&, T>>
|
||||
span(const Container& container)
|
||||
span(const Container& container) noexcept
|
||||
: span(base::data(container), base::size(container)) {}
|
||||
|
||||
constexpr span(const span& other) noexcept = default;
|
||||
// Conversions from spans of compatible types: this allows a span<T> to be
|
||||
// seamlessly used as a span<const T>, but not the other way around.
|
||||
template <typename U, typename = internal::EnableIfLegalSpanConversion<U, T>>
|
||||
constexpr span(const span<U>& other) : span(other.data(), other.size()) {}
|
||||
|
||||
// Conversions from spans of compatible types and extents: this allows a
|
||||
// span<T> to be seamlessly used as a span<const T>, but not the other way
|
||||
// around. If extent is not dynamic, OtherExtent has to be equal to Extent.
|
||||
template <
|
||||
typename U,
|
||||
size_t OtherExtent,
|
||||
typename =
|
||||
internal::EnableIfLegalSpanConversion<U, OtherExtent, T, Extent>>
|
||||
constexpr span(const span<U, OtherExtent>& other)
|
||||
: span(other.data(), other.size()) {}
|
||||
|
||||
constexpr span& operator=(const span& other) noexcept = default;
|
||||
~span() noexcept = default;
|
||||
|
||||
// [span.sub], span subviews
|
||||
constexpr span first(size_t count) const {
|
||||
CHECK(count <= size_);
|
||||
return span(data_, count);
|
||||
template <size_t Count>
|
||||
constexpr span<T, Count> first() const noexcept {
|
||||
static_assert(Extent == dynamic_extent || Count <= Extent,
|
||||
"Count must not exceed Extent");
|
||||
CHECK(Extent != dynamic_extent || Count <= size());
|
||||
return {data(), Count};
|
||||
}
|
||||
|
||||
constexpr span last(size_t count) const {
|
||||
CHECK(count <= size_);
|
||||
return span(data_ + (size_ - count), count);
|
||||
template <size_t Count>
|
||||
constexpr span<T, Count> last() const noexcept {
|
||||
static_assert(Extent == dynamic_extent || Count <= Extent,
|
||||
"Count must not exceed Extent");
|
||||
CHECK(Extent != dynamic_extent || Count <= size());
|
||||
return {data() + (size() - Count), Count};
|
||||
}
|
||||
|
||||
constexpr span subspan(size_t pos, size_t count = -1) const {
|
||||
constexpr auto npos = static_cast<size_t>(-1);
|
||||
CHECK(pos <= size_);
|
||||
CHECK(count == npos || count <= size_ - pos);
|
||||
return span(data_ + pos, count == npos ? size_ - pos : count);
|
||||
template <size_t Offset, size_t Count = dynamic_extent>
|
||||
constexpr span<T,
|
||||
Count != dynamic_extent
|
||||
? Count
|
||||
: (Extent != dynamic_extent ? Extent - Offset
|
||||
: dynamic_extent)>
|
||||
subspan() const noexcept {
|
||||
static_assert(Extent == dynamic_extent || Offset <= Extent,
|
||||
"Offset must not exceed Extent");
|
||||
static_assert(Extent == dynamic_extent || Count == dynamic_extent ||
|
||||
Count <= Extent - Offset,
|
||||
"Count must not exceed Extent - Offset");
|
||||
CHECK(Extent != dynamic_extent || Offset <= size());
|
||||
CHECK(Extent != dynamic_extent || Count == dynamic_extent ||
|
||||
Count <= size() - Offset);
|
||||
return {data() + Offset, Count != dynamic_extent ? Count : size() - Offset};
|
||||
}
|
||||
|
||||
constexpr span<T, dynamic_extent> first(size_t count) const noexcept {
|
||||
// Note: CHECK_LE is not constexpr, hence regular CHECK must be used.
|
||||
CHECK(count <= size());
|
||||
return {data(), count};
|
||||
}
|
||||
|
||||
constexpr span<T, dynamic_extent> last(size_t count) const noexcept {
|
||||
// Note: CHECK_LE is not constexpr, hence regular CHECK must be used.
|
||||
CHECK(count <= size());
|
||||
return {data() + (size() - count), count};
|
||||
}
|
||||
|
||||
constexpr span<T, dynamic_extent> subspan(size_t offset,
|
||||
size_t count = dynamic_extent) const
|
||||
noexcept {
|
||||
// Note: CHECK_LE is not constexpr, hence regular CHECK must be used.
|
||||
CHECK(offset <= size());
|
||||
CHECK(count == dynamic_extent || count <= size() - offset);
|
||||
return {data() + offset, count != dynamic_extent ? count : size() - offset};
|
||||
}
|
||||
|
||||
// [span.obs], span observers
|
||||
constexpr size_t size() const noexcept { return size_; }
|
||||
constexpr size_t size_bytes() const noexcept { return size() * sizeof(T); }
|
||||
constexpr bool empty() const noexcept { return size_ == 0; }
|
||||
constexpr bool empty() const noexcept { return size() == 0; }
|
||||
|
||||
// [span.elem], span element access
|
||||
constexpr T& operator[](size_t index) const noexcept {
|
||||
CHECK(index < size_);
|
||||
return data_[index];
|
||||
constexpr T& operator[](size_t idx) const noexcept {
|
||||
// Note: CHECK_LT is not constexpr, hence regular CHECK must be used.
|
||||
CHECK(idx < size());
|
||||
return *(data() + idx);
|
||||
}
|
||||
constexpr T& operator()(size_t index) const noexcept {
|
||||
CHECK(index < size_);
|
||||
return data_[index];
|
||||
|
||||
constexpr T& operator()(size_t idx) const noexcept {
|
||||
// Note: CHECK_LT is not constexpr, hence regular CHECK must be used.
|
||||
CHECK(idx < size());
|
||||
return *(data() + idx);
|
||||
}
|
||||
|
||||
constexpr T* data() const noexcept { return data_; }
|
||||
|
||||
// [span.iter], span iterator support
|
||||
constexpr iterator begin() const noexcept { return data_; }
|
||||
constexpr iterator end() const noexcept { return data_ + size_; }
|
||||
constexpr iterator begin() const noexcept { return data(); }
|
||||
constexpr iterator end() const noexcept { return data() + size(); }
|
||||
|
||||
constexpr const_iterator cbegin() const noexcept { return begin(); }
|
||||
constexpr const_iterator cend() const noexcept { return end(); }
|
||||
@ -280,93 +349,102 @@ class span {
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
// span<T, Extent>::extent can not be declared inline prior to C++17, hence this
|
||||
// definition is required.
|
||||
template <class T, size_t Extent>
|
||||
constexpr size_t span<T, Extent>::extent;
|
||||
|
||||
// [span.comparison], span comparison operators
|
||||
// Relational operators. Equality is a element-wise comparison.
|
||||
template <typename T, typename U>
|
||||
constexpr bool operator==(span<T> lhs, span<U> rhs) noexcept {
|
||||
template <typename T, size_t X, typename U, size_t Y>
|
||||
constexpr bool operator==(span<T, X> lhs, span<U, Y> rhs) noexcept {
|
||||
return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
constexpr bool operator!=(span<T> lhs, span<U> rhs) noexcept {
|
||||
template <typename T, size_t X, typename U, size_t Y>
|
||||
constexpr bool operator!=(span<T, X> lhs, span<U, Y> rhs) noexcept {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
constexpr bool operator<(span<T> lhs, span<U> rhs) noexcept {
|
||||
template <typename T, size_t X, typename U, size_t Y>
|
||||
constexpr bool operator<(span<T, X> lhs, span<U, Y> rhs) noexcept {
|
||||
return std::lexicographical_compare(lhs.cbegin(), lhs.cend(), rhs.cbegin(),
|
||||
rhs.cend());
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
constexpr bool operator<=(span<T> lhs, span<U> rhs) noexcept {
|
||||
template <typename T, size_t X, typename U, size_t Y>
|
||||
constexpr bool operator<=(span<T, X> lhs, span<U, Y> rhs) noexcept {
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
constexpr bool operator>(span<T> lhs, span<U> rhs) noexcept {
|
||||
template <typename T, size_t X, typename U, size_t Y>
|
||||
constexpr bool operator>(span<T, X> lhs, span<U, Y> rhs) noexcept {
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
constexpr bool operator>=(span<T> lhs, span<U> rhs) noexcept {
|
||||
template <typename T, size_t X, typename U, size_t Y>
|
||||
constexpr bool operator>=(span<T, X> lhs, span<U, Y> rhs) noexcept {
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
// [span.objectrep], views of object representation
|
||||
template <typename T>
|
||||
span<const uint8_t> as_bytes(span<T> s) noexcept {
|
||||
template <typename T, size_t X>
|
||||
span<const uint8_t, X == dynamic_extent ? dynamic_extent : sizeof(T) * X>
|
||||
as_bytes(span<T, X> s) noexcept {
|
||||
return {reinterpret_cast<const uint8_t*>(s.data()), s.size_bytes()};
|
||||
}
|
||||
|
||||
template <typename T, typename = std::enable_if_t<!std::is_const<T>::value>>
|
||||
span<uint8_t> as_writable_bytes(span<T> s) noexcept {
|
||||
template <typename T,
|
||||
size_t X,
|
||||
typename = std::enable_if_t<!std::is_const<T>::value>>
|
||||
span<uint8_t, X == dynamic_extent ? dynamic_extent : sizeof(T) * X>
|
||||
as_writable_bytes(span<T, X> s) noexcept {
|
||||
return {reinterpret_cast<uint8_t*>(s.data()), s.size_bytes()};
|
||||
}
|
||||
|
||||
// Type-deducing helpers for constructing a span.
|
||||
template <typename T>
|
||||
constexpr span<T> make_span(T* data, size_t size) noexcept {
|
||||
return span<T>(data, size);
|
||||
return {data, size};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr span<T> make_span(T* begin, T* end) {
|
||||
return span<T>(begin, end);
|
||||
constexpr span<T> make_span(T* begin, T* end) noexcept {
|
||||
return {begin, end};
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
constexpr span<T> make_span(T (&array)[N]) noexcept {
|
||||
return span<T>(array);
|
||||
constexpr span<T, N> make_span(T (&array)[N]) noexcept {
|
||||
return array;
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
constexpr span<T> make_span(std::array<T, N>& array) noexcept {
|
||||
return span<T>(array);
|
||||
constexpr span<T, N> make_span(std::array<T, N>& array) noexcept {
|
||||
return array;
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
constexpr span<const T> make_span(const std::array<T, N>& array) noexcept {
|
||||
return span<const T>(array);
|
||||
constexpr span<const T, N> make_span(const std::array<T, N>& array) noexcept {
|
||||
return array;
|
||||
}
|
||||
|
||||
template <typename Container,
|
||||
typename T = typename Container::value_type,
|
||||
typename = internal::EnableIfSpanCompatibleContainer<Container&, T>>
|
||||
constexpr span<T> make_span(Container& container) {
|
||||
return span<T>(container);
|
||||
constexpr span<T> make_span(Container& container) noexcept {
|
||||
return container;
|
||||
}
|
||||
|
||||
template <
|
||||
typename Container,
|
||||
typename T = const typename Container::value_type,
|
||||
typename = internal::EnableIfSpanCompatibleContainer<const Container&, T>>
|
||||
constexpr span<T> make_span(const Container& container) {
|
||||
return span<T>(container);
|
||||
constexpr span<T> make_span(const Container& container) noexcept {
|
||||
return container;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr span<T> make_span(span<T> span) noexcept {
|
||||
template <typename T, size_t X>
|
||||
constexpr span<T, X> make_span(const span<T, X>& span) noexcept {
|
||||
return span;
|
||||
}
|
||||
|
||||
|
@ -22,58 +22,81 @@ using ::testing::Pointwise;
|
||||
namespace base {
|
||||
|
||||
TEST(SpanTest, DefaultConstructor) {
|
||||
span<int> span;
|
||||
EXPECT_EQ(nullptr, span.data());
|
||||
EXPECT_EQ(0u, span.size());
|
||||
span<int> dynamic_span;
|
||||
EXPECT_EQ(nullptr, dynamic_span.data());
|
||||
EXPECT_EQ(0u, dynamic_span.size());
|
||||
|
||||
constexpr span<int, 0> static_span;
|
||||
static_assert(nullptr == static_span.data(), "");
|
||||
static_assert(0u == static_span.size(), "");
|
||||
}
|
||||
|
||||
TEST(SpanTest, ConstructFromDataAndSize) {
|
||||
{
|
||||
span<int> empty_span(nullptr, 0);
|
||||
EXPECT_TRUE(empty_span.empty());
|
||||
EXPECT_EQ(nullptr, empty_span.data());
|
||||
}
|
||||
constexpr span<int> empty_span(nullptr, 0);
|
||||
EXPECT_TRUE(empty_span.empty());
|
||||
EXPECT_EQ(nullptr, empty_span.data());
|
||||
|
||||
{
|
||||
std::vector<int> vector = {1, 1, 2, 3, 5, 8};
|
||||
std::vector<int> vector = {1, 1, 2, 3, 5, 8};
|
||||
|
||||
span<int> span(vector.data(), vector.size());
|
||||
EXPECT_EQ(vector.data(), span.data());
|
||||
EXPECT_EQ(vector.size(), span.size());
|
||||
span<int> dynamic_span(vector.data(), vector.size());
|
||||
EXPECT_EQ(vector.data(), dynamic_span.data());
|
||||
EXPECT_EQ(vector.size(), dynamic_span.size());
|
||||
|
||||
for (size_t i = 0; i < span.size(); ++i)
|
||||
EXPECT_EQ(vector[i], span[i]);
|
||||
}
|
||||
for (size_t i = 0; i < dynamic_span.size(); ++i)
|
||||
EXPECT_EQ(vector[i], dynamic_span[i]);
|
||||
|
||||
span<int, 6> static_span(vector.data(), vector.size());
|
||||
EXPECT_EQ(vector.data(), static_span.data());
|
||||
EXPECT_EQ(vector.size(), static_span.size());
|
||||
|
||||
for (size_t i = 0; i < static_span.size(); ++i)
|
||||
EXPECT_EQ(vector[i], static_span[i]);
|
||||
}
|
||||
|
||||
TEST(SpanTest, ConstructFromPointerPair) {
|
||||
{
|
||||
span<int> empty_span(nullptr, nullptr);
|
||||
EXPECT_TRUE(empty_span.empty());
|
||||
EXPECT_EQ(nullptr, empty_span.data());
|
||||
}
|
||||
constexpr span<int> empty_span(nullptr, nullptr);
|
||||
EXPECT_TRUE(empty_span.empty());
|
||||
EXPECT_EQ(nullptr, empty_span.data());
|
||||
|
||||
{
|
||||
std::vector<int> vector = {1, 1, 2, 3, 5, 8};
|
||||
std::vector<int> vector = {1, 1, 2, 3, 5, 8};
|
||||
|
||||
span<int> span(vector.data(), vector.data() + vector.size() / 2);
|
||||
EXPECT_EQ(vector.data(), span.data());
|
||||
EXPECT_EQ(vector.size() / 2, span.size());
|
||||
span<int> dynamic_span(vector.data(), vector.data() + vector.size() / 2);
|
||||
EXPECT_EQ(vector.data(), dynamic_span.data());
|
||||
EXPECT_EQ(vector.size() / 2, dynamic_span.size());
|
||||
|
||||
for (size_t i = 0; i < span.size(); ++i)
|
||||
EXPECT_EQ(vector[i], span[i]);
|
||||
}
|
||||
for (size_t i = 0; i < dynamic_span.size(); ++i)
|
||||
EXPECT_EQ(vector[i], dynamic_span[i]);
|
||||
|
||||
span<int, 3> static_span(vector.data(), vector.data() + vector.size() / 2);
|
||||
EXPECT_EQ(vector.data(), static_span.data());
|
||||
EXPECT_EQ(vector.size() / 2, static_span.size());
|
||||
|
||||
for (size_t i = 0; i < static_span.size(); ++i)
|
||||
EXPECT_EQ(vector[i], static_span[i]);
|
||||
}
|
||||
|
||||
TEST(SpanTest, ConstructFromConstexprArray) {
|
||||
static constexpr int kArray[] = {5, 4, 3, 2, 1};
|
||||
|
||||
constexpr span<const int> span(kArray);
|
||||
EXPECT_EQ(kArray, span.data());
|
||||
EXPECT_EQ(arraysize(kArray), span.size());
|
||||
constexpr span<const int> dynamic_span(kArray);
|
||||
static_assert(kArray == dynamic_span.data(), "");
|
||||
static_assert(base::size(kArray) == dynamic_span.size(), "");
|
||||
|
||||
for (size_t i = 0; i < span.size(); ++i)
|
||||
EXPECT_EQ(kArray[i], span[i]);
|
||||
static_assert(kArray[0] == dynamic_span[0], "");
|
||||
static_assert(kArray[1] == dynamic_span[1], "");
|
||||
static_assert(kArray[2] == dynamic_span[2], "");
|
||||
static_assert(kArray[3] == dynamic_span[3], "");
|
||||
static_assert(kArray[4] == dynamic_span[4], "");
|
||||
|
||||
constexpr span<const int, base::size(kArray)> static_span(kArray);
|
||||
static_assert(kArray == static_span.data(), "");
|
||||
static_assert(base::size(kArray) == static_span.size(), "");
|
||||
|
||||
static_assert(kArray[0] == static_span[0], "");
|
||||
static_assert(kArray[1] == static_span[1], "");
|
||||
static_assert(kArray[2] == static_span[2], "");
|
||||
static_assert(kArray[3] == static_span[3], "");
|
||||
static_assert(kArray[4] == static_span[4], "");
|
||||
}
|
||||
|
||||
TEST(SpanTest, ConstructFromArray) {
|
||||
@ -85,11 +108,17 @@ TEST(SpanTest, ConstructFromArray) {
|
||||
for (size_t i = 0; i < const_span.size(); ++i)
|
||||
EXPECT_EQ(array[i], const_span[i]);
|
||||
|
||||
span<int> span(array);
|
||||
EXPECT_EQ(array, span.data());
|
||||
EXPECT_EQ(arraysize(array), span.size());
|
||||
for (size_t i = 0; i < span.size(); ++i)
|
||||
EXPECT_EQ(array[i], span[i]);
|
||||
span<int> dynamic_span(array);
|
||||
EXPECT_EQ(array, dynamic_span.data());
|
||||
EXPECT_EQ(base::size(array), dynamic_span.size());
|
||||
for (size_t i = 0; i < dynamic_span.size(); ++i)
|
||||
EXPECT_EQ(array[i], dynamic_span[i]);
|
||||
|
||||
span<int, base::size(array)> static_span(array);
|
||||
EXPECT_EQ(array, static_span.data());
|
||||
EXPECT_EQ(base::size(array), static_span.size());
|
||||
for (size_t i = 0; i < static_span.size(); ++i)
|
||||
EXPECT_EQ(array[i], static_span[i]);
|
||||
}
|
||||
|
||||
TEST(SpanTest, ConstructFromStdArray) {
|
||||
@ -103,11 +132,17 @@ TEST(SpanTest, ConstructFromStdArray) {
|
||||
for (size_t i = 0; i < const_span.size(); ++i)
|
||||
EXPECT_EQ(array[i], const_span[i]);
|
||||
|
||||
span<int> span(array);
|
||||
EXPECT_EQ(array.data(), span.data());
|
||||
EXPECT_EQ(array.size(), span.size());
|
||||
for (size_t i = 0; i < span.size(); ++i)
|
||||
EXPECT_EQ(array[i], span[i]);
|
||||
span<int> dynamic_span(array);
|
||||
EXPECT_EQ(array.data(), dynamic_span.data());
|
||||
EXPECT_EQ(array.size(), dynamic_span.size());
|
||||
for (size_t i = 0; i < dynamic_span.size(); ++i)
|
||||
EXPECT_EQ(array[i], dynamic_span[i]);
|
||||
|
||||
span<int, base::size(array)> static_span(array);
|
||||
EXPECT_EQ(array.data(), static_span.data());
|
||||
EXPECT_EQ(array.size(), static_span.size());
|
||||
for (size_t i = 0; i < static_span.size(); ++i)
|
||||
EXPECT_EQ(array[i], static_span[i]);
|
||||
}
|
||||
|
||||
TEST(SpanTest, ConstructFromInitializerList) {
|
||||
@ -119,6 +154,13 @@ TEST(SpanTest, ConstructFromInitializerList) {
|
||||
|
||||
for (size_t i = 0; i < const_span.size(); ++i)
|
||||
EXPECT_EQ(il.begin()[i], const_span[i]);
|
||||
|
||||
span<const int, 6> static_span(il);
|
||||
EXPECT_EQ(il.begin(), static_span.data());
|
||||
EXPECT_EQ(il.size(), static_span.size());
|
||||
|
||||
for (size_t i = 0; i < static_span.size(); ++i)
|
||||
EXPECT_EQ(il.begin()[i], static_span[i]);
|
||||
}
|
||||
|
||||
TEST(SpanTest, ConstructFromStdString) {
|
||||
@ -131,12 +173,19 @@ TEST(SpanTest, ConstructFromStdString) {
|
||||
for (size_t i = 0; i < const_span.size(); ++i)
|
||||
EXPECT_EQ(str[i], const_span[i]);
|
||||
|
||||
span<char> span(str);
|
||||
EXPECT_EQ(str.data(), span.data());
|
||||
EXPECT_EQ(str.size(), span.size());
|
||||
span<char> dynamic_span(str);
|
||||
EXPECT_EQ(str.data(), dynamic_span.data());
|
||||
EXPECT_EQ(str.size(), dynamic_span.size());
|
||||
|
||||
for (size_t i = 0; i < span.size(); ++i)
|
||||
EXPECT_EQ(str[i], span[i]);
|
||||
for (size_t i = 0; i < dynamic_span.size(); ++i)
|
||||
EXPECT_EQ(str[i], dynamic_span[i]);
|
||||
|
||||
span<char, 6> static_span(str);
|
||||
EXPECT_EQ(str.data(), static_span.data());
|
||||
EXPECT_EQ(str.size(), static_span.size());
|
||||
|
||||
for (size_t i = 0; i < static_span.size(); ++i)
|
||||
EXPECT_EQ(str[i], static_span[i]);
|
||||
}
|
||||
|
||||
TEST(SpanTest, ConstructFromConstContainer) {
|
||||
@ -148,6 +197,13 @@ TEST(SpanTest, ConstructFromConstContainer) {
|
||||
|
||||
for (size_t i = 0; i < const_span.size(); ++i)
|
||||
EXPECT_EQ(vector[i], const_span[i]);
|
||||
|
||||
span<const int, 6> static_span(vector);
|
||||
EXPECT_EQ(vector.data(), static_span.data());
|
||||
EXPECT_EQ(vector.size(), static_span.size());
|
||||
|
||||
for (size_t i = 0; i < static_span.size(); ++i)
|
||||
EXPECT_EQ(vector[i], static_span[i]);
|
||||
}
|
||||
|
||||
TEST(SpanTest, ConstructFromContainer) {
|
||||
@ -160,12 +216,19 @@ TEST(SpanTest, ConstructFromContainer) {
|
||||
for (size_t i = 0; i < const_span.size(); ++i)
|
||||
EXPECT_EQ(vector[i], const_span[i]);
|
||||
|
||||
span<int> span(vector);
|
||||
EXPECT_EQ(vector.data(), span.data());
|
||||
EXPECT_EQ(vector.size(), span.size());
|
||||
span<int> dynamic_span(vector);
|
||||
EXPECT_EQ(vector.data(), dynamic_span.data());
|
||||
EXPECT_EQ(vector.size(), dynamic_span.size());
|
||||
|
||||
for (size_t i = 0; i < span.size(); ++i)
|
||||
EXPECT_EQ(vector[i], span[i]);
|
||||
for (size_t i = 0; i < dynamic_span.size(); ++i)
|
||||
EXPECT_EQ(vector[i], dynamic_span[i]);
|
||||
|
||||
span<int, 6> static_span(vector);
|
||||
EXPECT_EQ(vector.data(), static_span.data());
|
||||
EXPECT_EQ(vector.size(), static_span.size());
|
||||
|
||||
for (size_t i = 0; i < static_span.size(); ++i)
|
||||
EXPECT_EQ(vector[i], static_span[i]);
|
||||
}
|
||||
|
||||
TEST(SpanTest, ConvertNonConstIntegralToConst) {
|
||||
@ -174,6 +237,10 @@ TEST(SpanTest, ConvertNonConstIntegralToConst) {
|
||||
span<int> int_span(vector.data(), vector.size());
|
||||
span<const int> const_span(int_span);
|
||||
EXPECT_THAT(const_span, Pointwise(Eq(), int_span));
|
||||
|
||||
span<int, 6> static_int_span(vector.data(), vector.size());
|
||||
span<const int, 6> static_const_span(static_int_span);
|
||||
EXPECT_THAT(static_const_span, Pointwise(Eq(), static_int_span));
|
||||
}
|
||||
|
||||
TEST(SpanTest, ConvertNonConstPointerToConst) {
|
||||
@ -192,6 +259,12 @@ TEST(SpanTest, ConvertNonConstPointerToConst) {
|
||||
// Note: no test for conversion from span<int*> to span<const int* const>,
|
||||
// due to CWG Defect 330:
|
||||
// http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#330
|
||||
|
||||
span<int*, 3> static_non_const_pointer_span(vector);
|
||||
EXPECT_THAT(static_non_const_pointer_span, Pointwise(Eq(), vector));
|
||||
span<int* const, 3> static_const_pointer_span(static_non_const_pointer_span);
|
||||
EXPECT_THAT(static_const_pointer_span,
|
||||
Pointwise(Eq(), static_non_const_pointer_span));
|
||||
}
|
||||
|
||||
TEST(SpanTest, ConvertBetweenEquivalentTypes) {
|
||||
@ -200,6 +273,390 @@ TEST(SpanTest, ConvertBetweenEquivalentTypes) {
|
||||
span<int32_t> int32_t_span(vector);
|
||||
span<int> converted_span(int32_t_span);
|
||||
EXPECT_EQ(int32_t_span, converted_span);
|
||||
|
||||
span<int32_t, 5> static_int32_t_span(vector);
|
||||
span<int, 5> static_converted_span(static_int32_t_span);
|
||||
EXPECT_EQ(static_int32_t_span, static_converted_span);
|
||||
}
|
||||
|
||||
TEST(SpanTest, TemplatedFirst) {
|
||||
static constexpr int array[] = {1, 2, 3};
|
||||
constexpr span<const int, 3> span(array);
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.first<0>();
|
||||
static_assert(span.data() == subspan.data(), "");
|
||||
static_assert(0u == subspan.size(), "");
|
||||
static_assert(0u == decltype(subspan)::extent, "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.first<1>();
|
||||
static_assert(span.data() == subspan.data(), "");
|
||||
static_assert(1u == subspan.size(), "");
|
||||
static_assert(1u == decltype(subspan)::extent, "");
|
||||
static_assert(1 == subspan[0], "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.first<2>();
|
||||
static_assert(span.data() == subspan.data(), "");
|
||||
static_assert(2u == subspan.size(), "");
|
||||
static_assert(2u == decltype(subspan)::extent, "");
|
||||
static_assert(1 == subspan[0], "");
|
||||
static_assert(2 == subspan[1], "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.first<3>();
|
||||
static_assert(span.data() == subspan.data(), "");
|
||||
static_assert(3u == subspan.size(), "");
|
||||
static_assert(3u == decltype(subspan)::extent, "");
|
||||
static_assert(1 == subspan[0], "");
|
||||
static_assert(2 == subspan[1], "");
|
||||
static_assert(3 == subspan[2], "");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SpanTest, TemplatedLast) {
|
||||
static constexpr int array[] = {1, 2, 3};
|
||||
constexpr span<const int, 3> span(array);
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.last<0>();
|
||||
static_assert(span.data() + 3 == subspan.data(), "");
|
||||
static_assert(0u == subspan.size(), "");
|
||||
static_assert(0u == decltype(subspan)::extent, "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.last<1>();
|
||||
static_assert(span.data() + 2 == subspan.data(), "");
|
||||
static_assert(1u == subspan.size(), "");
|
||||
static_assert(1u == decltype(subspan)::extent, "");
|
||||
static_assert(3 == subspan[0], "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.last<2>();
|
||||
static_assert(span.data() + 1 == subspan.data(), "");
|
||||
static_assert(2u == subspan.size(), "");
|
||||
static_assert(2u == decltype(subspan)::extent, "");
|
||||
static_assert(2 == subspan[0], "");
|
||||
static_assert(3 == subspan[1], "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.last<3>();
|
||||
static_assert(span.data() == subspan.data(), "");
|
||||
static_assert(3u == subspan.size(), "");
|
||||
static_assert(3u == decltype(subspan)::extent, "");
|
||||
static_assert(1 == subspan[0], "");
|
||||
static_assert(2 == subspan[1], "");
|
||||
static_assert(3 == subspan[2], "");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SpanTest, TemplatedSubspan) {
|
||||
static constexpr int array[] = {1, 2, 3};
|
||||
constexpr span<const int, 3> span(array);
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.subspan<0>();
|
||||
static_assert(span.data() == subspan.data(), "");
|
||||
static_assert(3u == subspan.size(), "");
|
||||
static_assert(3u == decltype(subspan)::extent, "");
|
||||
static_assert(1 == subspan[0], "");
|
||||
static_assert(2 == subspan[1], "");
|
||||
static_assert(3 == subspan[2], "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.subspan<1>();
|
||||
static_assert(span.data() + 1 == subspan.data(), "");
|
||||
static_assert(2u == subspan.size(), "");
|
||||
static_assert(2u == decltype(subspan)::extent, "");
|
||||
static_assert(2 == subspan[0], "");
|
||||
static_assert(3 == subspan[1], "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.subspan<2>();
|
||||
static_assert(span.data() + 2 == subspan.data(), "");
|
||||
static_assert(1u == subspan.size(), "");
|
||||
static_assert(1u == decltype(subspan)::extent, "");
|
||||
static_assert(3 == subspan[0], "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.subspan<3>();
|
||||
static_assert(span.data() + 3 == subspan.data(), "");
|
||||
static_assert(0u == subspan.size(), "");
|
||||
static_assert(0u == decltype(subspan)::extent, "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.subspan<0, 0>();
|
||||
static_assert(span.data() == subspan.data(), "");
|
||||
static_assert(0u == subspan.size(), "");
|
||||
static_assert(0u == decltype(subspan)::extent, "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.subspan<1, 0>();
|
||||
static_assert(span.data() + 1 == subspan.data(), "");
|
||||
static_assert(0u == subspan.size(), "");
|
||||
static_assert(0u == decltype(subspan)::extent, "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.subspan<2, 0>();
|
||||
static_assert(span.data() + 2 == subspan.data(), "");
|
||||
static_assert(0u == subspan.size(), "");
|
||||
static_assert(0u == decltype(subspan)::extent, "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.subspan<0, 1>();
|
||||
static_assert(span.data() == subspan.data(), "");
|
||||
static_assert(1u == subspan.size(), "");
|
||||
static_assert(1u == decltype(subspan)::extent, "");
|
||||
static_assert(1 == subspan[0], "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.subspan<1, 1>();
|
||||
static_assert(span.data() + 1 == subspan.data(), "");
|
||||
static_assert(1u == subspan.size(), "");
|
||||
static_assert(1u == decltype(subspan)::extent, "");
|
||||
static_assert(2 == subspan[0], "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.subspan<2, 1>();
|
||||
static_assert(span.data() + 2 == subspan.data(), "");
|
||||
static_assert(1u == subspan.size(), "");
|
||||
static_assert(1u == decltype(subspan)::extent, "");
|
||||
static_assert(3 == subspan[0], "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.subspan<0, 2>();
|
||||
static_assert(span.data() == subspan.data(), "");
|
||||
static_assert(2u == subspan.size(), "");
|
||||
static_assert(2u == decltype(subspan)::extent, "");
|
||||
static_assert(1 == subspan[0], "");
|
||||
static_assert(2 == subspan[1], "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.subspan<1, 2>();
|
||||
static_assert(span.data() + 1 == subspan.data(), "");
|
||||
static_assert(2u == subspan.size(), "");
|
||||
static_assert(2u == decltype(subspan)::extent, "");
|
||||
static_assert(2 == subspan[0], "");
|
||||
static_assert(3 == subspan[1], "");
|
||||
}
|
||||
|
||||
{
|
||||
constexpr auto subspan = span.subspan<0, 3>();
|
||||
static_assert(span.data() == subspan.data(), "");
|
||||
static_assert(3u == subspan.size(), "");
|
||||
static_assert(3u == decltype(subspan)::extent, "");
|
||||
static_assert(1 == subspan[0], "");
|
||||
static_assert(2 == subspan[1], "");
|
||||
static_assert(3 == subspan[2], "");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SpanTest, TemplatedFirstOnDynamicSpan) {
|
||||
int array[] = {1, 2, 3};
|
||||
span<const int> span(array);
|
||||
|
||||
{
|
||||
auto subspan = span.first<0>();
|
||||
EXPECT_EQ(span.data(), subspan.data());
|
||||
EXPECT_EQ(0u, subspan.size());
|
||||
static_assert(0u == decltype(subspan)::extent, "");
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.first<1>();
|
||||
EXPECT_EQ(span.data(), subspan.data());
|
||||
EXPECT_EQ(1u, subspan.size());
|
||||
static_assert(1u == decltype(subspan)::extent, "");
|
||||
EXPECT_EQ(1, subspan[0]);
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.first<2>();
|
||||
EXPECT_EQ(span.data(), subspan.data());
|
||||
EXPECT_EQ(2u, subspan.size());
|
||||
static_assert(2u == decltype(subspan)::extent, "");
|
||||
EXPECT_EQ(1, subspan[0]);
|
||||
EXPECT_EQ(2, subspan[1]);
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.first<3>();
|
||||
EXPECT_EQ(span.data(), subspan.data());
|
||||
EXPECT_EQ(3u, subspan.size());
|
||||
static_assert(3u == decltype(subspan)::extent, "");
|
||||
EXPECT_EQ(1, subspan[0]);
|
||||
EXPECT_EQ(2, subspan[1]);
|
||||
EXPECT_EQ(3, subspan[2]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SpanTest, TemplatedLastOnDynamicSpan) {
|
||||
int array[] = {1, 2, 3};
|
||||
span<int> span(array);
|
||||
|
||||
{
|
||||
auto subspan = span.last<0>();
|
||||
EXPECT_EQ(span.data() + 3, subspan.data());
|
||||
EXPECT_EQ(0u, subspan.size());
|
||||
static_assert(0u == decltype(subspan)::extent, "");
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.last<1>();
|
||||
EXPECT_EQ(span.data() + 2, subspan.data());
|
||||
EXPECT_EQ(1u, subspan.size());
|
||||
static_assert(1u == decltype(subspan)::extent, "");
|
||||
EXPECT_EQ(3, subspan[0]);
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.last<2>();
|
||||
EXPECT_EQ(span.data() + 1, subspan.data());
|
||||
EXPECT_EQ(2u, subspan.size());
|
||||
static_assert(2u == decltype(subspan)::extent, "");
|
||||
EXPECT_EQ(2, subspan[0]);
|
||||
EXPECT_EQ(3, subspan[1]);
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.last<3>();
|
||||
EXPECT_EQ(span.data(), subspan.data());
|
||||
EXPECT_EQ(3u, subspan.size());
|
||||
static_assert(3u == decltype(subspan)::extent, "");
|
||||
EXPECT_EQ(1, subspan[0]);
|
||||
EXPECT_EQ(2, subspan[1]);
|
||||
EXPECT_EQ(3, subspan[2]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SpanTest, TemplatedSubspanFromDynamicSpan) {
|
||||
int array[] = {1, 2, 3};
|
||||
span<int, 3> span(array);
|
||||
|
||||
{
|
||||
auto subspan = span.subspan<0>();
|
||||
EXPECT_EQ(span.data(), subspan.data());
|
||||
static_assert(3u == decltype(subspan)::extent, "");
|
||||
EXPECT_EQ(3u, subspan.size());
|
||||
EXPECT_EQ(1, subspan[0]);
|
||||
EXPECT_EQ(2, subspan[1]);
|
||||
EXPECT_EQ(3, subspan[2]);
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.subspan<1>();
|
||||
EXPECT_EQ(span.data() + 1, subspan.data());
|
||||
EXPECT_EQ(2u, subspan.size());
|
||||
static_assert(2u == decltype(subspan)::extent, "");
|
||||
EXPECT_EQ(2, subspan[0]);
|
||||
EXPECT_EQ(3, subspan[1]);
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.subspan<2>();
|
||||
EXPECT_EQ(span.data() + 2, subspan.data());
|
||||
EXPECT_EQ(1u, subspan.size());
|
||||
static_assert(1u == decltype(subspan)::extent, "");
|
||||
EXPECT_EQ(3, subspan[0]);
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.subspan<3>();
|
||||
EXPECT_EQ(span.data() + 3, subspan.data());
|
||||
EXPECT_EQ(0u, subspan.size());
|
||||
static_assert(0u == decltype(subspan)::extent, "");
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.subspan<0, 0>();
|
||||
EXPECT_EQ(span.data(), subspan.data());
|
||||
EXPECT_EQ(0u, subspan.size());
|
||||
static_assert(0u == decltype(subspan)::extent, "");
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.subspan<1, 0>();
|
||||
EXPECT_EQ(span.data() + 1, subspan.data());
|
||||
EXPECT_EQ(0u, subspan.size());
|
||||
static_assert(0u == decltype(subspan)::extent, "");
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.subspan<2, 0>();
|
||||
EXPECT_EQ(span.data() + 2, subspan.data());
|
||||
EXPECT_EQ(0u, subspan.size());
|
||||
static_assert(0u == decltype(subspan)::extent, "");
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.subspan<0, 1>();
|
||||
EXPECT_EQ(span.data(), subspan.data());
|
||||
EXPECT_EQ(1u, subspan.size());
|
||||
static_assert(1u == decltype(subspan)::extent, "");
|
||||
EXPECT_EQ(1, subspan[0]);
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.subspan<1, 1>();
|
||||
EXPECT_EQ(span.data() + 1, subspan.data());
|
||||
EXPECT_EQ(1u, subspan.size());
|
||||
static_assert(1u == decltype(subspan)::extent, "");
|
||||
EXPECT_EQ(2, subspan[0]);
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.subspan<2, 1>();
|
||||
EXPECT_EQ(span.data() + 2, subspan.data());
|
||||
EXPECT_EQ(1u, subspan.size());
|
||||
static_assert(1u == decltype(subspan)::extent, "");
|
||||
EXPECT_EQ(3, subspan[0]);
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.subspan<0, 2>();
|
||||
EXPECT_EQ(span.data(), subspan.data());
|
||||
EXPECT_EQ(2u, subspan.size());
|
||||
static_assert(2u == decltype(subspan)::extent, "");
|
||||
EXPECT_EQ(1, subspan[0]);
|
||||
EXPECT_EQ(2, subspan[1]);
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.subspan<1, 2>();
|
||||
EXPECT_EQ(span.data() + 1, subspan.data());
|
||||
EXPECT_EQ(2u, subspan.size());
|
||||
static_assert(2u == decltype(subspan)::extent, "");
|
||||
EXPECT_EQ(2, subspan[0]);
|
||||
EXPECT_EQ(3, subspan[1]);
|
||||
}
|
||||
|
||||
{
|
||||
auto subspan = span.subspan<0, 3>();
|
||||
EXPECT_EQ(span.data(), subspan.data());
|
||||
EXPECT_EQ(3u, subspan.size());
|
||||
static_assert(3u == decltype(subspan)::extent, "");
|
||||
EXPECT_EQ(1, subspan[0]);
|
||||
EXPECT_EQ(2, subspan[1]);
|
||||
EXPECT_EQ(3, subspan[2]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SpanTest, First) {
|
||||
@ -451,7 +908,7 @@ TEST(SpanTest, Equality) {
|
||||
static constexpr int kArray1[] = {3, 1, 4, 1, 5};
|
||||
static constexpr int kArray2[] = {3, 1, 4, 1, 5};
|
||||
constexpr span<const int> span1(kArray1);
|
||||
constexpr span<const int> span2(kArray2);
|
||||
constexpr span<const int, 5> span2(kArray2);
|
||||
|
||||
EXPECT_EQ(span1, span2);
|
||||
|
||||
@ -461,7 +918,7 @@ TEST(SpanTest, Equality) {
|
||||
EXPECT_FALSE(span1 == span3);
|
||||
|
||||
static double kArray4[] = {2.0, 7.0, 1.0, 8.0, 3.0};
|
||||
span<double> span4(kArray4);
|
||||
span<double, 5> span4(kArray4);
|
||||
|
||||
EXPECT_EQ(span3, span4);
|
||||
}
|
||||
@ -470,7 +927,7 @@ TEST(SpanTest, Inequality) {
|
||||
static constexpr int kArray1[] = {2, 3, 5, 7, 11};
|
||||
static constexpr int kArray2[] = {1, 4, 6, 8, 9};
|
||||
constexpr span<const int> span1(kArray1);
|
||||
constexpr span<const int> span2(kArray2);
|
||||
constexpr span<const int, 5> span2(kArray2);
|
||||
|
||||
EXPECT_NE(span1, span2);
|
||||
|
||||
@ -480,7 +937,7 @@ TEST(SpanTest, Inequality) {
|
||||
EXPECT_FALSE(span1 != span3);
|
||||
|
||||
static double kArray4[] = {1.0, 4.0, 6.0, 8.0, 9.0};
|
||||
span<double> span4(kArray4);
|
||||
span<double, 5> span4(kArray4);
|
||||
|
||||
EXPECT_NE(span3, span4);
|
||||
}
|
||||
@ -489,7 +946,7 @@ TEST(SpanTest, LessThan) {
|
||||
static constexpr int kArray1[] = {2, 3, 5, 7, 11};
|
||||
static constexpr int kArray2[] = {2, 3, 5, 7, 11, 13};
|
||||
constexpr span<const int> span1(kArray1);
|
||||
constexpr span<const int> span2(kArray2);
|
||||
constexpr span<const int, 6> span2(kArray2);
|
||||
|
||||
EXPECT_LT(span1, span2);
|
||||
|
||||
@ -499,7 +956,7 @@ TEST(SpanTest, LessThan) {
|
||||
EXPECT_FALSE(span1 < span3);
|
||||
|
||||
static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0, 13.0};
|
||||
span<double> span4(kArray4);
|
||||
span<double, 6> span4(kArray4);
|
||||
|
||||
EXPECT_LT(span3, span4);
|
||||
}
|
||||
@ -508,7 +965,7 @@ TEST(SpanTest, LessEqual) {
|
||||
static constexpr int kArray1[] = {2, 3, 5, 7, 11};
|
||||
static constexpr int kArray2[] = {2, 3, 5, 7, 11, 13};
|
||||
constexpr span<const int> span1(kArray1);
|
||||
constexpr span<const int> span2(kArray2);
|
||||
constexpr span<const int, 6> span2(kArray2);
|
||||
|
||||
EXPECT_LE(span1, span1);
|
||||
EXPECT_LE(span1, span2);
|
||||
@ -519,7 +976,7 @@ TEST(SpanTest, LessEqual) {
|
||||
EXPECT_FALSE(span1 <= span3);
|
||||
|
||||
static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0, 13.0};
|
||||
span<double> span4(kArray4);
|
||||
span<double, 6> span4(kArray4);
|
||||
|
||||
EXPECT_LE(span3, span4);
|
||||
}
|
||||
@ -528,7 +985,7 @@ TEST(SpanTest, GreaterThan) {
|
||||
static constexpr int kArray1[] = {2, 3, 5, 7, 11, 13};
|
||||
static constexpr int kArray2[] = {2, 3, 5, 7, 11};
|
||||
constexpr span<const int> span1(kArray1);
|
||||
constexpr span<const int> span2(kArray2);
|
||||
constexpr span<const int, 5> span2(kArray2);
|
||||
|
||||
EXPECT_GT(span1, span2);
|
||||
|
||||
@ -538,7 +995,7 @@ TEST(SpanTest, GreaterThan) {
|
||||
EXPECT_FALSE(span1 > span3);
|
||||
|
||||
static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0};
|
||||
span<double> span4(kArray4);
|
||||
span<double, 5> span4(kArray4);
|
||||
|
||||
EXPECT_GT(span3, span4);
|
||||
}
|
||||
@ -547,7 +1004,7 @@ TEST(SpanTest, GreaterEqual) {
|
||||
static constexpr int kArray1[] = {2, 3, 5, 7, 11, 13};
|
||||
static constexpr int kArray2[] = {2, 3, 5, 7, 11};
|
||||
constexpr span<const int> span1(kArray1);
|
||||
constexpr span<const int> span2(kArray2);
|
||||
constexpr span<const int, 5> span2(kArray2);
|
||||
|
||||
EXPECT_GE(span1, span1);
|
||||
EXPECT_GE(span1, span2);
|
||||
@ -558,7 +1015,7 @@ TEST(SpanTest, GreaterEqual) {
|
||||
EXPECT_FALSE(span1 >= span3);
|
||||
|
||||
static double kArray4[] = {2.0, 3.0, 5.0, 7.0, 11.0};
|
||||
span<double> span4(kArray4);
|
||||
span<double, 5> span4(kArray4);
|
||||
|
||||
EXPECT_GE(span3, span4);
|
||||
}
|
||||
@ -566,7 +1023,8 @@ TEST(SpanTest, GreaterEqual) {
|
||||
TEST(SpanTest, AsBytes) {
|
||||
{
|
||||
constexpr int kArray[] = {2, 3, 5, 7, 11, 13};
|
||||
span<const uint8_t> bytes_span = as_bytes(make_span(kArray));
|
||||
span<const uint8_t, sizeof(kArray)> bytes_span =
|
||||
as_bytes(make_span(kArray));
|
||||
EXPECT_EQ(reinterpret_cast<const uint8_t*>(kArray), bytes_span.data());
|
||||
EXPECT_EQ(sizeof(kArray), bytes_span.size());
|
||||
EXPECT_EQ(bytes_span.size(), bytes_span.size_bytes());
|
||||
@ -604,7 +1062,9 @@ TEST(SpanTest, MakeSpanFromDataAndSize) {
|
||||
|
||||
std::vector<int> vector = {1, 1, 2, 3, 5, 8};
|
||||
span<int> span(vector.data(), vector.size());
|
||||
EXPECT_EQ(span, make_span(vector.data(), vector.size()));
|
||||
auto made_span = make_span(vector.data(), vector.size());
|
||||
EXPECT_EQ(span, made_span);
|
||||
static_assert(decltype(made_span)::extent == dynamic_extent, "");
|
||||
}
|
||||
|
||||
TEST(SpanTest, MakeSpanFromPointerPair) {
|
||||
@ -615,34 +1075,40 @@ TEST(SpanTest, MakeSpanFromPointerPair) {
|
||||
|
||||
std::vector<int> vector = {1, 1, 2, 3, 5, 8};
|
||||
span<int> span(vector.data(), vector.size());
|
||||
EXPECT_EQ(span, make_span(vector.data(), vector.data() + vector.size()));
|
||||
auto made_span = make_span(vector.data(), vector.data() + vector.size());
|
||||
EXPECT_EQ(span, made_span);
|
||||
static_assert(decltype(made_span)::extent == dynamic_extent, "");
|
||||
}
|
||||
|
||||
TEST(SpanTest, MakeSpanFromConstexprArray) {
|
||||
static constexpr int kArray[] = {1, 2, 3, 4, 5};
|
||||
constexpr span<const int> span(kArray);
|
||||
EXPECT_EQ(span, make_span(kArray));
|
||||
static_assert(decltype(make_span(kArray))::extent == 5, "");
|
||||
}
|
||||
|
||||
TEST(SpanTest, MakeSpanFromStdArray) {
|
||||
const std::array<int, 5> kArray = {{1, 2, 3, 4, 5}};
|
||||
span<const int> span(kArray);
|
||||
EXPECT_EQ(span, make_span(kArray));
|
||||
static_assert(decltype(make_span(kArray))::extent == 5, "");
|
||||
}
|
||||
|
||||
TEST(SpanTest, MakeSpanFromConstContainer) {
|
||||
const std::vector<int> vector = {-1, -2, -3, -4, -5};
|
||||
span<const int> span(vector);
|
||||
EXPECT_EQ(span, make_span(vector));
|
||||
static_assert(decltype(make_span(vector))::extent == dynamic_extent, "");
|
||||
}
|
||||
|
||||
TEST(SpanTest, MakeSpanFromContainer) {
|
||||
std::vector<int> vector = {-1, -2, -3, -4, -5};
|
||||
span<int> span(vector);
|
||||
EXPECT_EQ(span, make_span(vector));
|
||||
static_assert(decltype(make_span(vector))::extent == dynamic_extent, "");
|
||||
}
|
||||
|
||||
TEST(SpanTest, MakeSpanFromSpan) {
|
||||
TEST(SpanTest, MakeSpanFromDynamicSpan) {
|
||||
static constexpr int kArray[] = {1, 2, 3, 4, 5};
|
||||
constexpr span<const int> span(kArray);
|
||||
static_assert(std::is_same<decltype(span)::element_type,
|
||||
@ -654,6 +1120,26 @@ TEST(SpanTest, MakeSpanFromSpan) {
|
||||
|
||||
static_assert(span.size() == make_span(span).size(),
|
||||
"make_span(span) should have the same size() as span");
|
||||
|
||||
static_assert(decltype(make_span(span))::extent == decltype(span)::extent,
|
||||
"make_span(span) should have the same extent as span");
|
||||
}
|
||||
|
||||
TEST(SpanTest, MakeSpanFromStaticSpan) {
|
||||
static constexpr int kArray[] = {1, 2, 3, 4, 5};
|
||||
constexpr span<const int, 5> span(kArray);
|
||||
static_assert(std::is_same<decltype(span)::element_type,
|
||||
decltype(make_span(span))::element_type>::value,
|
||||
"make_span(span) should have the same element_type as span");
|
||||
|
||||
static_assert(span.data() == make_span(span).data(),
|
||||
"make_span(span) should have the same data() as span");
|
||||
|
||||
static_assert(span.size() == make_span(span).size(),
|
||||
"make_span(span) should have the same size() as span");
|
||||
|
||||
static_assert(decltype(make_span(span))::extent == decltype(span)::extent,
|
||||
"make_span(span) should have the same extent as span");
|
||||
}
|
||||
|
||||
TEST(SpanTest, EnsureConstexprGoodness) {
|
||||
|
@ -19,7 +19,59 @@ class Base {
|
||||
class Derived : Base {
|
||||
};
|
||||
|
||||
#if defined(NCTEST_DERIVED_TO_BASE_CONVERSION_DISALLOWED) // [r"fatal error: no matching constructor for initialization of 'span<base::Base \*>'"]
|
||||
#if defined(NCTEST_DEFAULT_SPAN_WITH_NON_ZERO_STATIC_EXTENT_DISALLOWED) // [r"fatal error: static_assert failed \"Invalid Extent\""]
|
||||
|
||||
// A default constructed span must have an extent of 0 or dynamic_extent.
|
||||
void WontCompile() {
|
||||
span<int, 1> span;
|
||||
}
|
||||
|
||||
#elif defined(NCTEST_SPAN_FROM_ARRAY_WITH_NON_MATCHING_STATIC_EXTENT_DISALLOWED) // [r"fatal error: no matching constructor for initialization of 'span<int, 1>'"]
|
||||
|
||||
// A span with static extent constructed from an array must match the size of
|
||||
// the array.
|
||||
void WontCompile() {
|
||||
int array[] = {1, 2, 3};
|
||||
span<int, 1> span(array);
|
||||
}
|
||||
|
||||
#elif defined(NCTEST_SPAN_FROM_STD_ARRAY_WITH_NON_MATCHING_STATIC_EXTENT_DISALLOWED) // [r"fatal error: no matching constructor for initialization of 'span<int, 2>'"]
|
||||
|
||||
// A span with static extent constructed from std::array must match the size of
|
||||
// the array.
|
||||
void WontCompile() {
|
||||
std::array<int, 3> array = {1, 2, 3};
|
||||
span<int, 2> span(array);
|
||||
}
|
||||
|
||||
#elif defined(NCTEST_SPAN_FROM_CONST_STD_ARRAY_WITH_NON_MATCHING_STATIC_EXTENT_DISALLOWED) // [r"fatal error: no matching constructor for initialization of 'span<const int, 2>'"]
|
||||
|
||||
// A span with static extent constructed from std::array must match the size of
|
||||
// the array.
|
||||
void WontCompile() {
|
||||
const std::array<int, 3> array = {1, 2, 3};
|
||||
span<const int, 2> span(array);
|
||||
}
|
||||
|
||||
#elif defined(NCTEST_SPAN_FROM_OTHER_SPAN_WITH_MISMATCHING_EXTENT_DISALLOWED) // [r"fatal error: no matching constructor for initialization of 'span<int, 4>'"]
|
||||
|
||||
// A span with static extent constructed from another span must match the
|
||||
// extent.
|
||||
void WontCompile() {
|
||||
std::array<int, 3> array = {1, 2, 3};
|
||||
span<int, 3> span3(array);
|
||||
span<int, 4> span4(span3);
|
||||
}
|
||||
|
||||
#elif defined(NCTEST_DYNAMIC_SPAN_TO_STATIC_SPAN_DISALLOWED) // [r"fatal error: no matching constructor for initialization of 'span<int, 3>'"]
|
||||
|
||||
// Converting a dynamic span to a static span should not be allowed.
|
||||
void WontCompile() {
|
||||
span<int> dynamic_span;
|
||||
span<int, 3> static_span(dynamic_span);
|
||||
}
|
||||
|
||||
#elif defined(NCTEST_DERIVED_TO_BASE_CONVERSION_DISALLOWED) // [r"fatal error: no matching constructor for initialization of 'span<base::Base \*>'"]
|
||||
|
||||
// Internally, this is represented as a pointer to pointers to Derived. An
|
||||
// implicit conversion to a pointer to pointers to Base must not be allowed.
|
||||
@ -58,6 +110,42 @@ void WontCompile() {
|
||||
span<int> span(set);
|
||||
}
|
||||
|
||||
#elif defined(NCTEST_STATIC_FRONT_WITH_EXCEEDING_COUNT_DISALLOWED) // [r"fatal error: static_assert failed \"Count must not exceed Extent\""]
|
||||
|
||||
// Static first called on a span with static extent must not exceed the size.
|
||||
void WontCompile() {
|
||||
std::array<int, 3> array = {1, 2, 3};
|
||||
span<int, 3> span(array);
|
||||
auto first = span.first<4>();
|
||||
}
|
||||
|
||||
#elif defined(NCTEST_STATIC_LAST_WITH_EXCEEDING_COUNT_DISALLOWED) // [r"fatal error: static_assert failed \"Count must not exceed Extent\""]
|
||||
|
||||
// Static last called on a span with static extent must not exceed the size.
|
||||
void WontCompile() {
|
||||
std::array<int, 3> array = {1, 2, 3};
|
||||
span<int, 3> span(array);
|
||||
auto last = span.last<4>();
|
||||
}
|
||||
|
||||
#elif defined(NCTEST_STATIC_SUBSPAN_WITH_EXCEEDING_OFFSET_DISALLOWED) // [r"fatal error: static_assert failed \"Offset must not exceed Extent\""]
|
||||
|
||||
// Static subspan called on a span with static extent must not exceed the size.
|
||||
void WontCompile() {
|
||||
std::array<int, 3> array = {1, 2, 3};
|
||||
span<int, 3> span(array);
|
||||
auto subspan = span.subspan<4>();
|
||||
}
|
||||
|
||||
#elif defined(NCTEST_STATIC_SUBSPAN_WITH_EXCEEDING_COUNT_DISALLOWED) // [r"fatal error: static_assert failed \"Count must not exceed Extent - Offset\""]
|
||||
|
||||
// Static subspan called on a span with static extent must not exceed the size.
|
||||
void WontCompile() {
|
||||
std::array<int, 3> array = {1, 2, 3};
|
||||
span<int, 3> span(array);
|
||||
auto subspan = span.subspan<0, 4>();
|
||||
}
|
||||
|
||||
#elif defined(NCTEST_AS_WRITABLE_BYTES_WITH_CONST_CONTAINER_DISALLOWED) // [r"fatal error: no matching function for call to 'as_writable_bytes'"]
|
||||
|
||||
// as_writable_bytes should not be possible for a const container.
|
||||
|
@ -259,11 +259,11 @@ bool InstallSigner::VerifySignature(const InstallSignature& signature) {
|
||||
|
||||
crypto::SignatureVerifier verifier;
|
||||
if (!verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1,
|
||||
base::as_bytes<const char>(signature.signature),
|
||||
base::as_bytes<const char>(public_key)))
|
||||
base::as_bytes(base::make_span(signature.signature)),
|
||||
base::as_bytes(base::make_span(public_key))))
|
||||
return false;
|
||||
|
||||
verifier.VerifyUpdate(base::as_bytes<const char>(signed_data));
|
||||
verifier.VerifyUpdate(base::as_bytes(base::make_span(signed_data)));
|
||||
return verifier.VerifyFinal();
|
||||
}
|
||||
|
||||
|
@ -163,12 +163,13 @@ VerifierResult VerifyCrx3(
|
||||
auto v = std::make_unique<crypto::SignatureVerifier>();
|
||||
static_assert(sizeof(unsigned char) == sizeof(uint8_t),
|
||||
"Unsupported char size.");
|
||||
if (!v->VerifyInit(proof_type.second, base::as_bytes<const char>(sig),
|
||||
base::as_bytes<const char>(key)))
|
||||
if (!v->VerifyInit(proof_type.second,
|
||||
base::as_bytes(base::make_span(sig)),
|
||||
base::as_bytes(base::make_span(key))))
|
||||
return VerifierResult::ERROR_SIGNATURE_INITIALIZATION_FAILED;
|
||||
v->VerifyUpdate(kSignatureContext);
|
||||
v->VerifyUpdate(header_size_octets);
|
||||
v->VerifyUpdate(base::as_bytes<const char>(signed_header_data_str));
|
||||
v->VerifyUpdate(base::as_bytes(base::make_span(signed_header_data_str)));
|
||||
verifiers.push_back(std::move(v));
|
||||
}
|
||||
}
|
||||
|
@ -569,12 +569,13 @@ bool CloudPolicyValidatorBase::VerifySignature(const std::string& data,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!verifier.VerifyInit(algorithm, base::as_bytes<const char>(signature),
|
||||
base::as_bytes<const char>(key))) {
|
||||
if (!verifier.VerifyInit(algorithm,
|
||||
base::as_bytes(base::make_span(signature)),
|
||||
base::as_bytes(base::make_span(key)))) {
|
||||
DLOG(ERROR) << "Invalid verification signature/key format";
|
||||
return false;
|
||||
}
|
||||
verifier.VerifyUpdate(base::as_bytes<const char>(data));
|
||||
verifier.VerifyUpdate(base::as_bytes(base::make_span(data)));
|
||||
return verifier.VerifyFinal();
|
||||
}
|
||||
|
||||
|
@ -62,11 +62,12 @@ VerifySignatureResult VerifySeedSignature(
|
||||
|
||||
crypto::SignatureVerifier verifier;
|
||||
if (!verifier.VerifyInit(crypto::SignatureVerifier::ECDSA_SHA256,
|
||||
base::as_bytes<const char>(signature), kPublicKey)) {
|
||||
base::as_bytes(base::make_span(signature)),
|
||||
kPublicKey)) {
|
||||
return VerifySignatureResult::INVALID_SIGNATURE;
|
||||
}
|
||||
|
||||
verifier.VerifyUpdate(base::as_bytes<const char>(seed_bytes));
|
||||
verifier.VerifyUpdate(base::as_bytes(base::make_span(seed_bytes)));
|
||||
if (!verifier.VerifyFinal())
|
||||
return VerifySignatureResult::INVALID_SEED;
|
||||
|
||||
|
@ -169,7 +169,7 @@ bool VerifySignature(base::span<const uint8_t> sig,
|
||||
// check.
|
||||
crypto::SignatureVerifier verifier;
|
||||
if (!verifier.VerifyInit(crypto::SignatureVerifier::RSA_PSS_SHA256, sig,
|
||||
base::as_bytes<const char>(spki))) {
|
||||
base::as_bytes(base::make_span(spki)))) {
|
||||
signed_exchange_utils::ReportErrorAndEndTraceEvent(
|
||||
devtools_proxy, "VerifySignature", "VerifyInit failed.");
|
||||
return false;
|
||||
|
@ -47,6 +47,6 @@ TEST(ECSignatureCreatorTest, BasicTest) {
|
||||
ASSERT_TRUE(verifier.VerifyInit(crypto::SignatureVerifier::ECDSA_SHA256,
|
||||
signature, public_key_info));
|
||||
|
||||
verifier.VerifyUpdate(base::as_bytes<const char>(data));
|
||||
verifier.VerifyUpdate(base::as_bytes(base::make_span(data)));
|
||||
ASSERT_TRUE(verifier.VerifyFinal());
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ TEST(SignatureCreatorTest, BasicTest) {
|
||||
ASSERT_TRUE(verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1,
|
||||
signature, public_key_info));
|
||||
|
||||
verifier.VerifyUpdate(base::as_bytes<const char>(data));
|
||||
verifier.VerifyUpdate(base::as_bytes(base::make_span(data)));
|
||||
ASSERT_TRUE(verifier.VerifyFinal());
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ TEST(SignatureCreatorTest, SignDigestTest) {
|
||||
ASSERT_TRUE(verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1,
|
||||
signature, public_key_info));
|
||||
|
||||
verifier.VerifyUpdate(base::as_bytes<const char>(data));
|
||||
verifier.VerifyUpdate(base::as_bytes(base::make_span(data)));
|
||||
ASSERT_TRUE(verifier.VerifyFinal());
|
||||
}
|
||||
|
||||
@ -112,6 +112,6 @@ TEST(SignatureCreatorTest, SignSHA256DigestTest) {
|
||||
ASSERT_TRUE(verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA256,
|
||||
signature, public_key_info));
|
||||
|
||||
verifier.VerifyUpdate(base::as_bytes<const char>(data));
|
||||
verifier.VerifyUpdate(base::as_bytes(base::make_span(data)));
|
||||
ASSERT_TRUE(verifier.VerifyFinal());
|
||||
}
|
||||
|
@ -299,17 +299,18 @@ bool VerifiedContents::VerifySignature(const std::string& protected_value,
|
||||
crypto::SignatureVerifier signature_verifier;
|
||||
if (!signature_verifier.VerifyInit(
|
||||
crypto::SignatureVerifier::RSA_PKCS1_SHA256,
|
||||
base::as_bytes<const char>(signature_bytes), public_key_)) {
|
||||
base::as_bytes(base::make_span(signature_bytes)), public_key_)) {
|
||||
VLOG(1) << "Could not verify signature - VerifyInit failure";
|
||||
return false;
|
||||
}
|
||||
|
||||
signature_verifier.VerifyUpdate(base::as_bytes<const char>(protected_value));
|
||||
signature_verifier.VerifyUpdate(
|
||||
base::as_bytes(base::make_span(protected_value)));
|
||||
|
||||
std::string dot(".");
|
||||
signature_verifier.VerifyUpdate(base::as_bytes<const char>(dot));
|
||||
signature_verifier.VerifyUpdate(base::as_bytes(base::make_span(dot)));
|
||||
|
||||
signature_verifier.VerifyUpdate(base::as_bytes<const char>(payload));
|
||||
signature_verifier.VerifyUpdate(base::as_bytes(base::make_span(payload)));
|
||||
|
||||
if (!signature_verifier.VerifyFinal()) {
|
||||
VLOG(1) << "Could not verify signature - VerifyFinal failure";
|
||||
|
@ -53,7 +53,7 @@ TEST(VerifiedContents, Simple) {
|
||||
// Initialize the VerifiedContents object.
|
||||
std::string public_key;
|
||||
ASSERT_TRUE(GetPublicKey(path.AppendASCII(kPublicKeyPem), &public_key));
|
||||
VerifiedContents contents(base::as_bytes<const char>(public_key));
|
||||
VerifiedContents contents(base::as_bytes(base::make_span(public_key)));
|
||||
base::FilePath verified_contents_path =
|
||||
path.AppendASCII("verified_contents.json");
|
||||
|
||||
@ -146,7 +146,7 @@ TEST(VerifiedContents, FailsOnBase64) {
|
||||
// Initialize the VerifiedContents object.
|
||||
std::string public_key;
|
||||
ASSERT_TRUE(GetPublicKey(path.AppendASCII(kPublicKeyPem), &public_key));
|
||||
VerifiedContents contents(base::as_bytes<const char>(public_key));
|
||||
VerifiedContents contents(base::as_bytes(base::make_span(public_key)));
|
||||
|
||||
base::FilePath verified_contents_path =
|
||||
path.AppendASCII("verified_contents_base64.json");
|
||||
|
@ -535,21 +535,18 @@ bool ProofVerifierChromium::Job::VerifySignature(
|
||||
}
|
||||
|
||||
crypto::SignatureVerifier verifier;
|
||||
if (!verifier.VerifyInit(algorithm, base::as_bytes<const char>(signature),
|
||||
base::as_bytes<const char>(spki))) {
|
||||
if (!verifier.VerifyInit(algorithm,
|
||||
base::as_bytes(base::make_span(signature)),
|
||||
base::as_bytes(base::make_span(spki)))) {
|
||||
DLOG(WARNING) << "VerifyInit failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
verifier.VerifyUpdate(
|
||||
base::make_span(reinterpret_cast<const uint8_t*>(kProofSignatureLabel),
|
||||
sizeof(kProofSignatureLabel)));
|
||||
verifier.VerifyUpdate(base::as_bytes(base::make_span(kProofSignatureLabel)));
|
||||
uint32_t len = chlo_hash.length();
|
||||
verifier.VerifyUpdate(
|
||||
base::make_span(reinterpret_cast<const uint8_t*>(&len), sizeof(len)));
|
||||
verifier.VerifyUpdate(base::as_bytes<const char>(chlo_hash));
|
||||
|
||||
verifier.VerifyUpdate(base::as_bytes<const char>(signed_data));
|
||||
verifier.VerifyUpdate(base::as_bytes(base::make_span(&len, 1)));
|
||||
verifier.VerifyUpdate(base::as_bytes(base::make_span(chlo_hash)));
|
||||
verifier.VerifyUpdate(base::as_bytes(base::make_span(signed_data)));
|
||||
|
||||
if (!verifier.VerifyFinal()) {
|
||||
DLOG(WARNING) << "VerifyFinal failed";
|
||||
|
Reference in New Issue
Block a user