Skip to content

Commit c301d7d

Browse files
authored
const|mutable buffer concepts less restrictive. (#391)
Previously only allowed for [const] char* buffers, this should allow for anything that is trivially copyable and buffer like to work. Closes #390
1 parent 7adb929 commit c301d7d

File tree

3 files changed

+77
-2
lines changed

3 files changed

+77
-2
lines changed

include/coro/concepts/buffer.hpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,31 @@ namespace coro::concepts
1010
template<typename type>
1111
concept const_buffer = requires(const type t)
1212
{
13+
// The underlying data type must be a standard-layout type and trivially copyable
14+
typename std::remove_pointer_t<decltype(t.data())>;
15+
requires std::is_trivial_v<std::remove_pointer_t<decltype(t.data())>>;
16+
17+
// General buffer properties
1318
{ t.empty() } -> std::same_as<bool>;
14-
{ t.data() } -> std::same_as<const char*>;
1519
{ t.size() } -> std::same_as<std::size_t>;
20+
21+
// We check the return type of `data()` to be a const pointer to the underlying type
22+
{ t.data() } -> std::same_as<const typename std::remove_pointer_t<decltype(t.data())>*>;
1623
};
1724

1825
template<typename type>
1926
concept mutable_buffer = requires(type t)
2027
{
28+
// The underlying data type must be a standard-layout type and trivially copyable
29+
typename std::remove_pointer_t<decltype(t.data())>;
30+
requires std::is_trivial_v<std::remove_pointer_t<decltype(t.data())>>;
31+
32+
// General buffer properties
2133
{ t.empty() } -> std::same_as<bool>;
22-
{ t.data() } -> std::same_as<char*>;
2334
{ t.size() } -> std::same_as<std::size_t>;
35+
36+
// We check the return type of `data()` to be a non-const pointer to the underlying type
37+
{ t.data() } -> std::same_as<typename std::remove_pointer_t<decltype(t.data())>*>;
2438
};
2539
// clang-format on
2640

test/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.12)
22
project(libcoro_test)
33

44
set(LIBCORO_TEST_SOURCE_FILES
5+
concepts/test_concepts.cpp
6+
57
test_condition_variable.cpp
68
test_event.cpp
79
test_generator.cpp

test/concepts/test_concepts.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include "catch_amalgamated.hpp"
2+
3+
#include <coro/coro.hpp>
4+
5+
TEST_CASE("concepts", "[concepts]")
6+
{
7+
std::cerr << "[concepts]\n\n";
8+
}
9+
10+
struct char_buffer {
11+
bool empty() const { return false; }
12+
const char* data() const { return nullptr; }
13+
std::size_t size() const { return 0; }
14+
char* data() { return nullptr; }
15+
};
16+
17+
struct uint8_buffer {
18+
bool empty() const { return false; }
19+
const uint8_t* data() const { return nullptr; }
20+
std::size_t size() const { return 0; }
21+
uint8_t* data() { return nullptr; }
22+
};
23+
24+
struct std_byte_buffer {
25+
bool empty() const { return false; }
26+
const std::byte* data() const { return nullptr; }
27+
std::size_t size() const { return 0; }
28+
std::byte* data() { return nullptr; }
29+
};
30+
31+
using coro::concepts::mutable_buffer;
32+
using coro::concepts::const_buffer;
33+
34+
TEST_CASE("mutable_buffer", "[concepts]")
35+
{
36+
static_assert(mutable_buffer<char_buffer>);
37+
static_assert(mutable_buffer<uint8_buffer>);
38+
static_assert(mutable_buffer<std_byte_buffer>);
39+
static_assert(mutable_buffer<std::vector<char>>);
40+
static_assert(mutable_buffer<std::vector<uint8_t>>);
41+
42+
REQUIRE(true);
43+
}
44+
45+
TEST_CASE("const_buffer", "[concepts]")
46+
{
47+
static_assert(const_buffer<char_buffer>);
48+
static_assert(const_buffer<uint8_buffer>);
49+
static_assert(const_buffer<std_byte_buffer>);
50+
static_assert(const_buffer<std::vector<char>>);
51+
static_assert(const_buffer<std::vector<uint8_t>>);
52+
53+
REQUIRE(true);
54+
}
55+
56+
TEST_CASE("~concepts", "[concepts]")
57+
{
58+
std::cerr << "[~concepts]\n\n";
59+
}

0 commit comments

Comments
 (0)