Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 30 additions & 31 deletions include/kf/SpanUtils.h
Original file line number Diff line number Diff line change
@@ -1,92 +1,91 @@
#pragma once
#include <span>
#include <algorithm>

namespace kf
{
using namespace std;

template<class T, class U>
inline constexpr span<T> span_cast(span<U> input) noexcept
constexpr std::span<T> span_cast(std::span<U> input) noexcept
{
return { reinterpret_cast<T*>(input.data()), input.size_bytes() / sizeof(T) };
}

template<class T, class U>
inline constexpr span<T> span_cast(U* data, size_t size) noexcept
constexpr std::span<T> span_cast(U* data, size_t size) noexcept
{
return { reinterpret_cast<T*>(data), size * sizeof(U) / sizeof(T) };
}

inline constexpr span<const std::byte> as_bytes(const void* p, size_t size) noexcept
inline constexpr std::span<const std::byte> as_bytes(const void* p, size_t size) noexcept
{
return { static_cast<const std::byte*>(p), size };
}

// TODO: rename to asBytes
template<class T, size_t N>
inline constexpr auto as_bytes(const T(&p)[N]) noexcept
constexpr auto as_bytes(const T(&p)[N]) noexcept
{
return span<const std::byte, sizeof(T)* N>{ reinterpret_cast<const std::byte*>(p), sizeof(p) };
return std::span<const std::byte, sizeof(T)* N>{ reinterpret_cast<const std::byte*>(p), sizeof(p) };
}

inline constexpr span<std::byte> as_writable_bytes(void* p, size_t size) noexcept
inline constexpr std::span<std::byte> as_writable_bytes(void* p, size_t size) noexcept
{
return { static_cast<std::byte*>(p), size };
}

// TODO: rename to asWritableBytes
template<class T, size_t N>
inline constexpr auto as_writable_bytes(T(&p)[N]) noexcept
constexpr auto as_writable_bytes(T(&p)[N]) noexcept
{
return span<std::byte, sizeof(T) * N>{ reinterpret_cast<std::byte*>(p), sizeof(p) };
return std::span<std::byte, sizeof(T) * N>{ reinterpret_cast<std::byte*>(p), sizeof(p) };
}

template<class T, size_t dstExtent, size_t srcExtent>
inline constexpr span<T> copyTruncate(span<T, dstExtent> dst, span<const T, srcExtent> src) noexcept
template<class T, class Y, size_t dstExtent, size_t srcExtent> requires std::is_same_v<T, std::remove_const_t<Y>>
constexpr std::span<T> copyTruncate(std::span<T, dstExtent> dst, std::span<Y, srcExtent> src) noexcept
{
//
// Source can be larger than destination, truncate in such case
//

src = src.first(min(src.size(), dst.size()));
auto truncatedSrc = src.first((std::min)(src.size(), dst.size()));

return { dst.begin(), copy(src.begin(), src.end(), dst.begin()) };
return { dst.begin(), std::copy(truncatedSrc.begin(), truncatedSrc.end(), dst.begin()) };
}

template<class T, size_t dstExtent, size_t srcExtent>
inline constexpr span<T> copyExact(span<T, dstExtent> dst, span<const T, srcExtent> src) noexcept
template<class T, class Y, size_t dstExtent, size_t srcExtent> requires std::is_same_v<T, std::remove_const_t<Y>>
constexpr std::span<T> copyExact(std::span<T, dstExtent> dst, std::span<Y, srcExtent> src) noexcept
{
//
// Source MUST be equal to destination
//

if constexpr (dstExtent == dynamic_extent || srcExtent == dynamic_extent)
if constexpr (dstExtent == std::dynamic_extent || srcExtent == std::dynamic_extent)
{
if (dst.size() != src.size())
{
_Xinvalid_argument("dst.size() != src.size()");
std::_Xinvalid_argument("dst.size() != src.size()");
}
}
else
{
static_assert(srcExtent == dstExtent);
}

return { dst.begin(), copy(src.begin(), src.end(), dst.begin()) };
return { dst.begin(), std::copy(src.begin(), src.end(), dst.begin()) };
}

template<class T, size_t dstExtent, size_t srcExtent>
inline constexpr span<T> copy(span<T, dstExtent> dst, span<const T, srcExtent> src) noexcept
template<class T, class Y, size_t dstExtent, size_t srcExtent> requires std::is_same_v<T, std::remove_const_t<Y>>
constexpr std::span<T> copy(std::span<T, dstExtent> dst, std::span<Y, srcExtent> src) noexcept
{
//
// Source MUST be smaller or equal to destination
//

if constexpr (dstExtent == dynamic_extent || srcExtent == dynamic_extent)
if constexpr (dstExtent == std::dynamic_extent || srcExtent == std::dynamic_extent)
{
if (dst.size() < src.size())
{
_Xinvalid_argument("dst.size() < src.size()");
std::_Xinvalid_argument("dst.size() < src.size()");
}
}
else
Expand All @@ -98,15 +97,15 @@ namespace kf
}

template<class T, size_t LeftExtent, size_t RightExtent>
inline constexpr bool equals(span<T, LeftExtent> left, span<T, RightExtent> right) noexcept
constexpr bool equals(std::span<T, LeftExtent> left, std::span<T, RightExtent> right) noexcept
{
return std::equal(left.begin(), left.end(), right.begin(), right.end());
}

template<class T>
inline constexpr ptrdiff_t indexOf(span<T> input, typename span<T>::const_reference elem, ptrdiff_t fromIndex = 0) noexcept
template<class T, size_t extent>
constexpr ptrdiff_t indexOf(std::span<T, extent> input, typename std::span<T, extent>::const_reference elem, ptrdiff_t fromIndex = 0) noexcept
{
for (auto i = fromIndex; i < ssize(input); ++i)
for (auto i = fromIndex; i < std::ssize(input); ++i)
{
if (input[i] == elem)
{
Expand All @@ -117,8 +116,8 @@ namespace kf
return -1;
}

template<class T>
inline constexpr span<T> split(span<T> input, typename span<T>::const_reference separator, _Inout_ ptrdiff_t& fromIndex) noexcept
template<class T, size_t extent>
constexpr std::span<T> split(std::span<T, extent> input, typename std::span<T, extent>::const_reference separator, _Inout_ ptrdiff_t& fromIndex) noexcept
{
auto originalFromIndex = fromIndex;

Expand All @@ -134,8 +133,8 @@ namespace kf
return input.subspan(originalFromIndex, count);
}

template<class T>
inline constexpr T atOrDefault(span<T> input, size_t index, convertible_to<T> auto defaultValue) noexcept
template<class T, size_t extent>
constexpr T atOrDefault(std::span<T, extent> input, size_t index, std::convertible_to<T> auto defaultValue) noexcept
{
return input.size() > index ? input[index] : defaultValue;
}
Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ wdk_add_driver(kf-test WINVER NTDDI_WIN10 STL
VariableSizeStructTest.cpp
ScopeFailureTest.cpp
Base64Test.cpp
SpanUtilsTest.cpp
AlgorithmTest.cpp
AutoSpinLockTest.cpp
EResourceSharedLockTest.cpp
Expand Down
Loading