KTL
trivial_buffer.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "../utility/assert.h"
4 
5 #include <cstring>
6 #include <iterator>
7 #include <memory>
8 #include <utility>
9 
10 namespace ktl
11 {
12  template<typename T, size_t Size>
14  {
15  private:
16  static_assert(std::is_default_constructible<T>::value, "Template class needs to be default constructible");
17  static_assert(std::is_trivially_copyable<T>::value, "Template class needs to be trivially copyable");
18 
19  public:
20  typedef T* iterator;
21  typedef const T* const_iterator;
22 
23  typedef std::reverse_iterator<T*> reverse_iterator;
24  typedef std::reverse_iterator<const T*> const_reverse_iterator;
25 
26  public:
30  trivial_buffer() noexcept {}
31 
32  explicit trivial_buffer(const T& value)
33  {
34  std::uninitialized_fill_n<T*, size_t>(reinterpret_cast<T*>(m_Data), Size, value);
35  }
36 
37  trivial_buffer(std::initializer_list<T> initializer)
38  {
39  KTL_ASSERT(initializer.size() <= Size);
40 
41  T* dst = reinterpret_cast<T*>(m_Data);
42  for (auto value : initializer)
43  {
44  *dst = value;
45  dst++;
46  }
47  }
48 
49  explicit trivial_buffer(const T* first, const T* last)
50  {
51  KTL_ASSERT(last - first == Size);
52 
53  std::memcpy(m_Data, first, Size * sizeof(T));
54  }
55 
56  trivial_buffer(const trivial_buffer& other) noexcept
57  {
58  std::memcpy(m_Data, other.m_Data, Size * sizeof(T));
59  }
60 
61  trivial_buffer(trivial_buffer&& other) noexcept
62  {
63  std::memcpy(m_Data, other.m_Data, Size * sizeof(T));
64  }
65 
66  trivial_buffer& operator=(const trivial_buffer& other) noexcept
67  {
68  std::memcpy(m_Data, other.m_Data, Size * sizeof(T));
69  return *this;
70  }
71 
73  {
74  std::memcpy(m_Data, other.m_Data, Size * sizeof(T));
75  return *this;
76  }
77 
84  T& operator[](size_t index) noexcept { return reinterpret_cast<T*>(m_Data)[index % Size]; }
85 
92  const T& operator[](size_t index) const noexcept { return reinterpret_cast<T*>(m_Data)[index % Size]; }
93 
94 
95  iterator begin() noexcept { return m_Data; }
96 
97  const_iterator begin() const noexcept { return m_Data; }
98 
99  iterator end() noexcept { return m_Data + Size; }
100 
101  const_iterator end() const noexcept { return m_Data + Size; }
102 
103  std::reverse_iterator<T*> rbegin() noexcept { return std::reverse_iterator(m_Data + Size); }
104 
105  std::reverse_iterator<const T*> rbegin() const noexcept { return std::reverse_iterator(m_Data + Size); }
106 
107  std::reverse_iterator<T*> rend() noexcept { return std::reverse_iterator(m_Data); }
108 
109  std::reverse_iterator<const T*> rend() const noexcept { return std::reverse_iterator(m_Data); }
110 
111 
116  constexpr size_t size() const noexcept { return Size; }
117 
122  iterator data() noexcept { return m_Data; }
123 
128  const_iterator data() const noexcept { return m_Data; }
129 
136  T& at(size_t index) const noexcept { return reinterpret_cast<T*>(m_Data)[index % Size]; }
137 
138 
144  void assign(const T* first, const T* last)
145  {
146  KTL_ASSERT(last - first == Size);
147 
148  std::memcpy(m_Data, first, Size * sizeof(T));
149  }
150 
151  private:
152  uint8_t m_Data[Size * sizeof(T)];
153  };
154 }
#define KTL_ASSERT(x)
Definition: assert.h:17
Definition: trivial_buffer.h:14
trivial_buffer(trivial_buffer &&other) noexcept
Definition: trivial_buffer.h:61
trivial_buffer & operator=(trivial_buffer &&other) noexcept
Definition: trivial_buffer.h:72
trivial_buffer() noexcept
Default construct a buffer of trivial types.
Definition: trivial_buffer.h:30
trivial_buffer(const T &value)
Definition: trivial_buffer.h:32
T & operator[](size_t index) noexcept
Returns a reference to the element at index, rolling.
Definition: trivial_buffer.h:84
trivial_buffer(const trivial_buffer &other) noexcept
Definition: trivial_buffer.h:56
iterator begin() noexcept
Definition: trivial_buffer.h:95
constexpr size_t size() const noexcept
Returns the size of the buffer.
Definition: trivial_buffer.h:116
std::reverse_iterator< T * > rend() noexcept
Definition: trivial_buffer.h:107
const T * const_iterator
Definition: trivial_buffer.h:21
T & at(size_t index) const noexcept
Returns a reference to the element at index, rolling.
Definition: trivial_buffer.h:136
const_iterator end() const noexcept
Definition: trivial_buffer.h:101
void assign(const T *first, const T *last)
Assigns the given values from first to last.
Definition: trivial_buffer.h:144
std::reverse_iterator< T * > rbegin() noexcept
Definition: trivial_buffer.h:103
std::reverse_iterator< const T * > rbegin() const noexcept
Definition: trivial_buffer.h:105
const_iterator begin() const noexcept
Definition: trivial_buffer.h:97
std::reverse_iterator< T * > reverse_iterator
Definition: trivial_buffer.h:23
const_iterator data() const noexcept
Returns a const iterator to the start of the buffer.
Definition: trivial_buffer.h:128
T * iterator
Definition: trivial_buffer.h:16
trivial_buffer(const T *first, const T *last)
Definition: trivial_buffer.h:49
trivial_buffer & operator=(const trivial_buffer &other) noexcept
Definition: trivial_buffer.h:66
iterator end() noexcept
Definition: trivial_buffer.h:99
std::reverse_iterator< const T * > rend() const noexcept
Definition: trivial_buffer.h:109
trivial_buffer(std::initializer_list< T > initializer)
Definition: trivial_buffer.h:37
iterator data() noexcept
Returns an iterator to the start of the buffer.
Definition: trivial_buffer.h:122
const T & operator[](size_t index) const noexcept
Returns a const reference to the element at index, rolling.
Definition: trivial_buffer.h:92
std::reverse_iterator< const T * > const_reverse_iterator
Definition: trivial_buffer.h:24
Definition: cascading.h:15