utils: simple buffer view impl

This commit is contained in:
2019-04-06 18:09:31 +07:00
parent 6e71e782c5
commit 5ef031c1e1
4 changed files with 171 additions and 0 deletions

View File

@@ -12,6 +12,7 @@
namespace e2d
{
class buffer;
class buffer_view;
class color;
class color32;
class image;

View File

@@ -43,8 +43,63 @@ namespace e2d
std::size_t size_ = 0;
};
class buffer_view {
public:
buffer_view() noexcept = default;
buffer_view(const buffer_view&) noexcept = default;
buffer_view& operator=(const buffer_view&) noexcept = default;
buffer_view(std::nullptr_t) noexcept = delete;
buffer_view(std::nullptr_t, std::size_t) noexcept = delete;
buffer_view(const void* data, std::size_t size) noexcept
: data_(data)
, size_(size){
E2D_ASSERT(!size || data);
}
buffer_view(const buffer& buffer) noexcept
: data_(buffer.data())
, size_(buffer.size()) {}
template < typename T >
buffer_view(const vector<T>& buffer) noexcept
: data_(buffer.data())
, size_(buffer.size() * sizeof(T)) {}
template < typename T, std::size_t N >
buffer_view(const array<T,N>& buffer) noexcept
: data_(buffer.data())
, size_(buffer.size() * sizeof(T)) {}
const void* data() const noexcept {
return data_;
}
std::size_t size() const noexcept {
return size_;
}
bool empty() const noexcept {
return size_ == 0;
}
void swap(buffer_view& other) noexcept {
std::swap(data_, other.data_);
std::swap(size_, other.size_);
}
private:
const void* data_ = nullptr;
std::size_t size_ = 0;
};
void swap(buffer& l, buffer& r) noexcept;
bool operator<(const buffer& l, const buffer& r) noexcept;
bool operator==(const buffer& l, const buffer& r) noexcept;
bool operator!=(const buffer& l, const buffer& r) noexcept;
void swap(buffer_view& l, buffer_view& r) noexcept;
bool operator<(const buffer_view& l, const buffer_view& r) noexcept;
bool operator==(const buffer_view& l, const buffer_view& r) noexcept;
bool operator!=(const buffer_view& l, const buffer_view& r) noexcept;
}

View File

@@ -138,4 +138,32 @@ namespace e2d
bool operator!=(const buffer& l, const buffer& r) noexcept {
return !(l == r);
}
void swap(buffer_view& l, buffer_view& r) noexcept {
l.swap(r);
}
bool operator<(const buffer_view& l, const buffer_view& r) noexcept {
const void* ld = l.data();
const void* rd = r.data();
const std::size_t ls = l.size();
const std::size_t rs = r.size();
return
(ls < rs) ||
(ls == rs && ls > 0 && std::memcmp(ld, rd, ls) < 0);
}
bool operator==(const buffer_view& l, const buffer_view& r) noexcept {
const void* ld = l.data();
const void* rd = r.data();
const std::size_t ls = l.size();
const std::size_t rs = r.size();
return
(ls == rs) &&
(ls == 0 || std::memcmp(ld, rd, ls) == 0);
}
bool operator!=(const buffer_view& l, const buffer_view& r) noexcept {
return !(l == r);
}
}

View File

@@ -171,3 +171,90 @@ TEST_CASE("buffer") {
#endif
}
}
TEST_CASE("buffer_view") {
{
buffer_view v0;
REQUIRE(v0.data() == nullptr);
REQUIRE(v0.size() == 0);
REQUIRE(v0.empty());
const char* s = "hello";
buffer_view v1{s, 5};
REQUIRE(v1.data() == s);
REQUIRE(v1.size() == 5);
REQUIRE_FALSE(v1.empty());
buffer_view v2{s, 3};
REQUIRE(v2.data() == s);
REQUIRE(v2.size() == 3);
buffer b0("hello", 5);
buffer_view v3(b0);
REQUIRE(v3.data() == b0.data());
REQUIRE(v3.size() == 5);
vector<u16> b1{'h', 'e', 'l', 'l', 'o'};
buffer_view v4(b1);
REQUIRE(v4.data() == b1.data());
REQUIRE(v4.size() == 10);
array<u32,5> b2{'h', 'e', 'l', 'l', 'o'};
buffer_view v5(b2);
REQUIRE(v5.data() == b2.data());
REQUIRE(v5.size() == 20);
}
{
const char* s0 = "hell";
const char* s1 = "world";
buffer_view v0{s0, 4};
buffer_view v1{s1, 5};
v0.swap(v1);
REQUIRE(v0.data() == s1);
REQUIRE(v0.size() == 5);
REQUIRE(v1.data() == s0);
REQUIRE(v1.size() == 4);
}
{
buffer_view v0{"hello", 5};
buffer_view v1(v0);
REQUIRE(v1.data() == v0.data());
REQUIRE(v1.size() == 5);
buffer_view v2;
v2 = v1;
REQUIRE(v2.data() == v0.data());
REQUIRE(v2.size() == 5);
}
{
REQUIRE_FALSE(buffer_view() < buffer_view());
REQUIRE_FALSE(buffer_view("aa",2) < buffer_view("aa",2));
REQUIRE(buffer_view() < buffer_view("a",1));
REQUIRE_FALSE(buffer_view("a",1) < buffer_view());
REQUIRE(buffer_view("aa",2) < buffer_view("ab",2));
REQUIRE_FALSE(buffer_view("ab",2) < buffer_view("aa",2));
REQUIRE(buffer_view("aa",2) < buffer_view("aaa",3));
REQUIRE(buffer_view("aa",2) < buffer_view("abb",3));
REQUIRE_FALSE(buffer_view("aaa",3) < buffer_view("aa",2));
REQUIRE_FALSE(buffer_view("abb",3) < buffer_view("aa",2));
}
{
REQUIRE(buffer_view() == buffer_view());
REQUIRE_FALSE(buffer_view() != buffer_view());
REQUIRE_FALSE(buffer_view() == buffer_view("hello",5));
REQUIRE_FALSE(buffer_view("hello",5) == buffer_view());
REQUIRE(buffer_view("hello",5) == buffer_view("hello",5));
REQUIRE_FALSE(buffer_view("hello",5) != buffer_view("hello",5));
REQUIRE(buffer_view("hello",5) != buffer_view("world",5));
REQUIRE_FALSE(buffer_view("hello",5) == buffer_view("world",5));
REQUIRE(buffer_view("hello",5) != buffer_view("hello, world",12));
REQUIRE_FALSE(buffer_view("hello",5) == buffer_view("hello, world",12));
}
}