File: concepts.hpp

package info (click to toggle)
reflect-cpp 0.21.0%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,128 kB
  • sloc: cpp: 50,336; python: 139; makefile: 30; sh: 3
file content (67 lines) | stat: -rw-r--r-- 2,775 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#ifndef RFL_CONCEPTS_HPP_
#define RFL_CONCEPTS_HPP_

#include <concepts>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <type_traits>

namespace rfl::concepts {

/// Concept for byte-like types that can be used in contiguous containers
/// Includes char, signed char, unsigned char, std::byte, and uint8_t
template <typename T>
concept ByteLike = std::same_as<T, char> || std::same_as<T, signed char> ||
                   std::same_as<T, unsigned char> ||
                   std::same_as<T, std::uint8_t> || std::same_as<T, std::byte>;

/// Concept for containers with a contiguous sequence of byte-like types
/// Requires:
/// - Container has a value_type that is byte-like
/// - Container provides data() method returning a pointer to contiguous memory
/// - Container provides size() method returning the number of elements
/// - Container supports range-based for loops (begin/end)
template <typename Container>
concept ContiguousByteContainer = requires(const Container& c) {
  typename Container::value_type;
  { c.data() } -> std::convertible_to<const typename Container::value_type*>;
  { c.size() } -> std::convertible_to<std::size_t>;
  { c.begin() } -> std::input_iterator;
  { c.end() } -> std::input_iterator;
  requires ByteLike<typename Container::value_type>;
  requires std::contiguous_iterator<decltype(c.begin())>;
};

/// Concept for mutable containers with a contiguous sequence of byte-like types
/// Extends ContiguousByteContainer with mutable access requirements
template <typename Container>
concept MutableContiguousByteContainer =
    ContiguousByteContainer<Container> && requires(Container& c) {
      { c.data() } -> std::convertible_to<typename Container::value_type*>;
      { c.begin() } -> std::output_iterator<typename Container::value_type>;
      { c.end() } -> std::output_iterator<typename Container::value_type>;
    };

/// Concept for back-insertable byte containers (like std::vector<uint8_t>)
/// Useful for containers that can grow dynamically during serialization
template <typename Container>
concept BackInsertableByteContainer =
    ContiguousByteContainer<Container> &&
    requires(Container& c, typename Container::value_type v) {
      c.push_back(v);
      c.reserve(std::size_t{});
      { c.capacity() } -> std::convertible_to<std::size_t>;
    };

/// Concept for byte spans or views (read-only, non-owning containers)
/// Includes std::span<const uint8_t>, std::string_view when used with char
/// data, etc.
template <typename Container>
concept ByteSpanLike = ContiguousByteContainer<Container> &&
                       std::is_trivially_copyable_v<Container> &&
                       std::is_trivially_destructible_v<Container>;

}  // namespace rfl::concepts

#endif  // RFL_CONCEPTS_HPP_