Skip to content

Commit bfc5f67

Browse files
belyshevdenisSergiusTheBestCopilot
authored
Add tests for SpanUtils (KF-27, #63)
* fix SpanUtils compilation without using namespace std implement tests for SpanUtils refactoring fix memcmp usage fix variable name * Update SpanUtils and tests * Remove g_Xinvalid_argument_call_count for now * Update test/SpanUtilsTest.cpp Co-authored-by: Copilot <[email protected]> * Update test/SpanUtilsTest.cpp Co-authored-by: Copilot <[email protected]> * Update include/kf/SpanUtils.h Co-authored-by: Copilot <[email protected]> * Fix review comments --------- Co-authored-by: Sergey Podobry <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 9a80cd0 commit bfc5f67

File tree

4 files changed

+441
-31
lines changed

4 files changed

+441
-31
lines changed

include/kf/SpanUtils.h

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,91 @@
11
#pragma once
22
#include <span>
3+
#include <algorithm>
34

45
namespace kf
56
{
6-
using namespace std;
7-
87
template<class T, class U>
9-
inline constexpr span<T> span_cast(span<U> input) noexcept
8+
constexpr std::span<T> span_cast(std::span<U> input) noexcept
109
{
1110
return { reinterpret_cast<T*>(input.data()), input.size_bytes() / sizeof(T) };
1211
}
1312

1413
template<class T, class U>
15-
inline constexpr span<T> span_cast(U* data, size_t size) noexcept
14+
constexpr std::span<T> span_cast(U* data, size_t size) noexcept
1615
{
1716
return { reinterpret_cast<T*>(data), size * sizeof(U) / sizeof(T) };
1817
}
1918

20-
inline constexpr span<const std::byte> as_bytes(const void* p, size_t size) noexcept
19+
inline constexpr std::span<const std::byte> as_bytes(const void* p, size_t size) noexcept
2120
{
2221
return { static_cast<const std::byte*>(p), size };
2322
}
2423

2524
// TODO: rename to asBytes
2625
template<class T, size_t N>
27-
inline constexpr auto as_bytes(const T(&p)[N]) noexcept
26+
constexpr auto as_bytes(const T(&p)[N]) noexcept
2827
{
29-
return span<const std::byte, sizeof(T)* N>{ reinterpret_cast<const std::byte*>(p), sizeof(p) };
28+
return std::span<const std::byte, sizeof(T)* N>{ reinterpret_cast<const std::byte*>(p), sizeof(p) };
3029
}
3130

32-
inline constexpr span<std::byte> as_writable_bytes(void* p, size_t size) noexcept
31+
inline constexpr std::span<std::byte> as_writable_bytes(void* p, size_t size) noexcept
3332
{
3433
return { static_cast<std::byte*>(p), size };
3534
}
3635

3736
// TODO: rename to asWritableBytes
3837
template<class T, size_t N>
39-
inline constexpr auto as_writable_bytes(T(&p)[N]) noexcept
38+
constexpr auto as_writable_bytes(T(&p)[N]) noexcept
4039
{
41-
return span<std::byte, sizeof(T) * N>{ reinterpret_cast<std::byte*>(p), sizeof(p) };
40+
return std::span<std::byte, sizeof(T) * N>{ reinterpret_cast<std::byte*>(p), sizeof(p) };
4241
}
4342

44-
template<class T, size_t dstExtent, size_t srcExtent>
45-
inline constexpr span<T> copyTruncate(span<T, dstExtent> dst, span<const T, srcExtent> src) noexcept
43+
template<class T, class Y, size_t dstExtent, size_t srcExtent> requires std::is_same_v<T, std::remove_const_t<Y>>
44+
constexpr std::span<T> copyTruncate(std::span<T, dstExtent> dst, std::span<Y, srcExtent> src) noexcept
4645
{
4746
//
4847
// Source can be larger than destination, truncate in such case
4948
//
5049

51-
src = src.first(min(src.size(), dst.size()));
50+
auto truncatedSrc = src.first((std::min)(src.size(), dst.size()));
5251

53-
return { dst.begin(), copy(src.begin(), src.end(), dst.begin()) };
52+
return { dst.begin(), std::copy(truncatedSrc.begin(), truncatedSrc.end(), dst.begin()) };
5453
}
5554

56-
template<class T, size_t dstExtent, size_t srcExtent>
57-
inline constexpr span<T> copyExact(span<T, dstExtent> dst, span<const T, srcExtent> src) noexcept
55+
template<class T, class Y, size_t dstExtent, size_t srcExtent> requires std::is_same_v<T, std::remove_const_t<Y>>
56+
constexpr std::span<T> copyExact(std::span<T, dstExtent> dst, std::span<Y, srcExtent> src) noexcept
5857
{
5958
//
6059
// Source MUST be equal to destination
6160
//
6261

63-
if constexpr (dstExtent == dynamic_extent || srcExtent == dynamic_extent)
62+
if constexpr (dstExtent == std::dynamic_extent || srcExtent == std::dynamic_extent)
6463
{
6564
if (dst.size() != src.size())
6665
{
67-
_Xinvalid_argument("dst.size() != src.size()");
66+
std::_Xinvalid_argument("dst.size() != src.size()");
6867
}
6968
}
7069
else
7170
{
7271
static_assert(srcExtent == dstExtent);
7372
}
7473

75-
return { dst.begin(), copy(src.begin(), src.end(), dst.begin()) };
74+
return { dst.begin(), std::copy(src.begin(), src.end(), dst.begin()) };
7675
}
7776

78-
template<class T, size_t dstExtent, size_t srcExtent>
79-
inline constexpr span<T> copy(span<T, dstExtent> dst, span<const T, srcExtent> src) noexcept
77+
template<class T, class Y, size_t dstExtent, size_t srcExtent> requires std::is_same_v<T, std::remove_const_t<Y>>
78+
constexpr std::span<T> copy(std::span<T, dstExtent> dst, std::span<Y, srcExtent> src) noexcept
8079
{
8180
//
8281
// Source MUST be smaller or equal to destination
8382
//
8483

85-
if constexpr (dstExtent == dynamic_extent || srcExtent == dynamic_extent)
84+
if constexpr (dstExtent == std::dynamic_extent || srcExtent == std::dynamic_extent)
8685
{
8786
if (dst.size() < src.size())
8887
{
89-
_Xinvalid_argument("dst.size() < src.size()");
88+
std::_Xinvalid_argument("dst.size() < src.size()");
9089
}
9190
}
9291
else
@@ -98,15 +97,15 @@ namespace kf
9897
}
9998

10099
template<class T, size_t LeftExtent, size_t RightExtent>
101-
inline constexpr bool equals(span<T, LeftExtent> left, span<T, RightExtent> right) noexcept
100+
constexpr bool equals(std::span<T, LeftExtent> left, std::span<T, RightExtent> right) noexcept
102101
{
103102
return std::equal(left.begin(), left.end(), right.begin(), right.end());
104103
}
105104

106-
template<class T>
107-
inline constexpr ptrdiff_t indexOf(span<T> input, typename span<T>::const_reference elem, ptrdiff_t fromIndex = 0) noexcept
105+
template<class T, size_t extent>
106+
constexpr ptrdiff_t indexOf(std::span<T, extent> input, typename std::span<T, extent>::const_reference elem, ptrdiff_t fromIndex = 0) noexcept
108107
{
109-
for (auto i = fromIndex; i < ssize(input); ++i)
108+
for (auto i = fromIndex; i < std::ssize(input); ++i)
110109
{
111110
if (input[i] == elem)
112111
{
@@ -117,8 +116,8 @@ namespace kf
117116
return -1;
118117
}
119118

120-
template<class T>
121-
inline constexpr span<T> split(span<T> input, typename span<T>::const_reference separator, _Inout_ ptrdiff_t& fromIndex) noexcept
119+
template<class T, size_t extent>
120+
constexpr std::span<T> split(std::span<T, extent> input, typename std::span<T, extent>::const_reference separator, _Inout_ ptrdiff_t& fromIndex) noexcept
122121
{
123122
auto originalFromIndex = fromIndex;
124123

@@ -134,8 +133,8 @@ namespace kf
134133
return input.subspan(originalFromIndex, count);
135134
}
136135

137-
template<class T>
138-
inline constexpr T atOrDefault(span<T> input, size_t index, convertible_to<T> auto defaultValue) noexcept
136+
template<class T, size_t extent>
137+
constexpr T atOrDefault(std::span<T, extent> input, size_t index, std::convertible_to<T> auto defaultValue) noexcept
139138
{
140139
return input.size() > index ? input[index] : defaultValue;
141140
}

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ wdk_add_driver(kf-test WINVER NTDDI_WIN10 STL
5656
VariableSizeStructTest.cpp
5757
ScopeFailureTest.cpp
5858
Base64Test.cpp
59+
SpanUtilsTest.cpp
5960
AlgorithmTest.cpp
6061
AutoSpinLockTest.cpp
6162
EResourceSharedLockTest.cpp

0 commit comments

Comments
 (0)