add: [imp] span ut

This commit is contained in:
mutouyun 2022-10-29 19:19:11 +08:00
parent a0271041ee
commit a0076f6bfb
2 changed files with 109 additions and 1 deletions

View File

@ -10,9 +10,12 @@
#include <cstddef> #include <cstddef>
#include <iterator> #include <iterator>
#include <array> #include <array>
#include <vector>
#include <string>
#include <limits> #include <limits>
#include <algorithm> #include <algorithm>
#include <cstdint> #include <cstdint>
#include <initializer_list>
#ifdef LIBIMP_CPP_20 #ifdef LIBIMP_CPP_20
#include <span> #include <span>
#endif // LIBIMP_CPP_20 #endif // LIBIMP_CPP_20
@ -48,7 +51,8 @@ using is_inconvertible =
template <typename S, typename I> template <typename S, typename I>
using is_sized_sentinel_for = using is_sized_sentinel_for =
is_inconvertible<decltype(std::declval<S>() - std::declval<I>()), std::ptrdiff_t>; typename std::enable_if<std::is_convertible<decltype(std::declval<S>() - std::declval<I>()),
std::ptrdiff_t>::value>::type;
/// @brief Obtain the address represented by p /// @brief Obtain the address represented by p
/// without forming a reference to the object pointed to by p. /// without forming a reference to the object pointed to by p.
@ -202,10 +206,65 @@ public:
} }
}; };
template <typename T, typename U,
typename = decltype(std::declval<T>() == std::declval<U>())>
bool operator==(span<T> a, span<U> b) noexcept {
if (a.size() != b.size()) {
return false;
}
for (std::size_t i = 0; i < a.size(); ++i) {
if (a[i] != b[i]) return false;
}
return true;
}
template <typename T, template <typename T,
typename Byte = typename std::conditional<std::is_const<T>::value, std::uint8_t const, std::uint8_t>::type> typename Byte = typename std::conditional<std::is_const<T>::value, std::uint8_t const, std::uint8_t>::type>
auto as_bytes(span<T> s) noexcept -> span<Byte> { auto as_bytes(span<T> s) noexcept -> span<Byte> {
return {reinterpret_cast<Byte *>(s.data()), s.size_bytes()}; return {reinterpret_cast<Byte *>(s.data()), s.size_bytes()};
} }
template <typename T>
auto make_span(T *arr, std::size_t count) noexcept -> span<T> {
return {arr, count};
}
template <typename T, std::size_t E>
auto make_span(T (&arr)[E]) noexcept -> span<T> {
return {arr};
}
template <typename T, std::size_t E>
auto make_span(std::array<T, E> const &arr) noexcept -> span<T> {
return {arr};
}
template <typename T, std::size_t E>
auto make_span(std::array<T, E> const &arr) noexcept -> span<typename std::add_const<T>::type> {
return {arr};
}
template <typename T>
auto make_span(std::vector<T> &arr) noexcept -> span<T> {
return {arr.data(), arr.size()};
}
template <typename T>
auto make_span(std::vector<T> const &arr) noexcept -> span<typename std::add_const<T>::type> {
return {arr.data(), arr.size()};
}
template <typename T>
auto make_span(std::initializer_list<T> list) noexcept -> span<typename std::add_const<T>::type> {
return {list.begin(), list.end()};
}
inline auto make_span(std::string &str) noexcept -> span<char> {
return {const_cast<char *>(str.data()), str.size()};
}
inline auto make_span(std::string const &str) noexcept -> span<char const> {
return {str.data(), str.size()};
}
LIBIMP_NAMESPACE_END_ LIBIMP_NAMESPACE_END_

View File

@ -1,7 +1,56 @@
#include <string>
#include <memory>
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "libimp/span.h" #include "libimp/span.h"
#include "libimp/countof.h"
TEST(span, to_address) {
int *a = new int;
EXPECT_EQ(imp::detail::to_address(a), a);
std::unique_ptr<int> b {a};
EXPECT_EQ(imp::detail::to_address(b), a);
}
TEST(span, span) { TEST(span, span) {
auto test_proc = [](auto &&buf, auto &&sp) {
EXPECT_EQ(imp::countof(buf), sp.size());
EXPECT_EQ(sizeof(buf[0]) * imp::countof(buf), sp.size_bytes());
for (int i = 0; i < sp.size(); ++i) {
EXPECT_EQ(buf[i], sp[i]);
}
};
{
int buf[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
auto sp = imp::make_span(buf);
test_proc(buf, sp);
test_proc(imp::make_span({0, 1, 2}) , sp.first(3));
test_proc(imp::make_span({6, 7, 8, 9}), sp.last(4));
test_proc(imp::make_span({3, 4, 5, 6}), sp.subspan(3, 4));
test_proc(imp::make_span({3, 4, 5, 6, 7, 8, 9}), sp.subspan(3));
}
{
std::vector<int> buf = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
auto sp = imp::make_span(buf);
imp::span<int> sp2 {buf.begin(), buf.end()};
EXPECT_EQ(sp, sp2);
test_proc(buf, sp);
test_proc(imp::make_span({0, 1, 2}) , sp.first(3));
test_proc(imp::make_span({6, 7, 8, 9}), sp.last(4));
test_proc(imp::make_span({3, 4, 5, 6}), sp.subspan(3, 4));
test_proc(imp::make_span({3, 4, 5, 6, 7, 8, 9}), sp.subspan(3));
test_proc(imp::make_span((char *)sp.data(), sp.size_bytes()), imp::as_bytes(sp));
}
{
std::string buf = "0123456789";
auto sp = imp::make_span(buf);
// if (sp == imp::make_span({nullptr})) {}
test_proc(buf, sp);
test_proc(imp::make_span("012", 3) , sp.first(3));
test_proc(imp::make_span("6789", 4), sp.last(4));
test_proc(imp::make_span("3456", 4), sp.subspan(3, 4));
test_proc(imp::make_span("3456789", 7), sp.subspan(3));
}
} }