buffer_builder.hpp
Go to the documentation of this file.
1 // Copyright (C) 2020-2023 Jonathan Müller and lexy contributors
2 // SPDX-License-Identifier: BSL-1.0
3 
4 #ifndef LEXY_DETAIL_BUFFER_BUILDER_HPP_INCLUDED
5 #define LEXY_DETAIL_BUFFER_BUILDER_HPP_INCLUDED
6 
7 #include <cstring>
11 #include <new>
12 
13 namespace lexy::_detail
14 {
15 // Builds a buffer: it has a read are and a write area.
16 // The characters in the read area are already valid and can be read.
17 // The characters in the write area are not valid, but can be written too.
18 template <typename T>
20 {
21  static_assert(std::is_trivial_v<T>);
22 
23  static constexpr std::size_t total_size_bytes = 1024;
24  static constexpr std::size_t stack_buffer_size
25  = (total_size_bytes - 3 * sizeof(T*)) / sizeof(T);
26  static constexpr auto growth_factor = 2;
27 
28 public:
30  {
31  static_assert(sizeof(*this) == total_size_bytes, "invalid buffer size calculation");
32  }
33 
34  ~buffer_builder() noexcept
35  {
36  // Free memory if we allocated any.
37  if (_data != _stack_buffer)
38  ::operator delete(_data);
39  }
40 
41  buffer_builder(const buffer_builder&) = delete;
42  buffer_builder& operator=(const buffer_builder&) = delete;
43 
44  // The total capacity: read + write.
45  std::size_t capacity() const noexcept
46  {
47  return _read_size + _write_size;
48  }
49 
50  // The read area.
51  const T* read_data() const noexcept
52  {
53  return _data;
54  }
55  std::size_t read_size() const noexcept
56  {
57  return _read_size;
58  }
59 
60  // The write area.
61  T* write_data() noexcept
62  {
63  return _data + _read_size;
64  }
65  std::size_t write_size() const noexcept
66  {
67  return _write_size;
68  }
69 
70  // Clears the read area.
71  void clear() noexcept
72  {
74  _read_size = 0;
75  }
76 
77  // Takes the first n characters of the write area and appends them to the read area.
78  void commit(std::size_t n) noexcept
79  {
81  _read_size += n;
82  _write_size -= n;
83  }
84 
85  // Increases the write area, invalidates all pointers.
86  void grow()
87  {
88  const auto cur_cap = capacity();
89  const auto new_cap = growth_factor * cur_cap;
90 
91  // Allocate new memory.
92  auto memory = static_cast<T*>(::operator new(new_cap * sizeof(T)));
93  // Copy the read area into the new memory.
94  std::memcpy(memory, _data, _read_size);
95 
96  // Release the old memory, if there was any.
97  if (_data != _stack_buffer)
98  ::operator delete(_data);
99 
100  // Update for the new area.
101  _data = memory;
102  // _read_size hasn't been changed
103  _write_size = new_cap - _read_size;
104  }
105 
106  //=== iterator ===//
107  // Stable iterator over the memory.
108  class stable_iterator : public forward_iterator_base<stable_iterator, const T>
109  {
110  public:
111  constexpr stable_iterator() = default;
112 
114  std::size_t idx) noexcept
115  : _buffer(&buffer), _idx(idx)
116  {}
117 
118  constexpr const T& deref() const noexcept
119  {
120  LEXY_PRECONDITION(_idx != _buffer->read_size());
121  return _buffer->read_data()[_idx];
122  }
123 
124  constexpr void increment() noexcept
125  {
126  LEXY_PRECONDITION(_idx != _buffer->read_size());
127  ++_idx;
128  }
129 
130  constexpr bool equal(stable_iterator rhs) const noexcept
131  {
132  if (!_buffer || !rhs._buffer)
133  return !_buffer && !rhs._buffer;
134  else
135  {
136  LEXY_PRECONDITION(_buffer == rhs._buffer);
137  return _idx == rhs._idx;
138  }
139  }
140 
141  constexpr std::size_t index() const noexcept
142  {
143  return _idx;
144  }
145 
146  private:
148  std::size_t _idx = 0;
149  };
150 
151 private:
152  T* _data;
153  std::size_t _read_size;
154  std::size_t _write_size;
156 };
157 } // namespace lexy::_detail
158 
159 #endif // LEXY_DETAIL_BUFFER_BUILDER_HPP_INCLUDED
160 
lexy::_detail::buffer_builder::stable_iterator::stable_iterator
constexpr stable_iterator()=default
iterator.hpp
config.hpp
lexy::_detail::buffer_builder::read_data
const T * read_data() const noexcept
Definition: buffer_builder.hpp:51
lexy::_detail::buffer_builder
Definition: buffer_builder.hpp:19
lexy::_detail::buffer_builder::write_data
T * write_data() noexcept
Definition: buffer_builder.hpp:61
lexy::_detail::buffer_builder::stable_iterator
Definition: buffer_builder.hpp:108
LEXY_PRECONDITION
#define LEXY_PRECONDITION(Expr)
Definition: assert.hpp:36
lexy::_detail::buffer_builder::_data
T * _data
Definition: buffer_builder.hpp:152
lexy::_detail::buffer_builder::stable_iterator::equal
constexpr bool equal(stable_iterator rhs) const noexcept
Definition: buffer_builder.hpp:130
lexy::_detail::buffer_builder::stable_iterator::_idx
std::size_t _idx
Definition: buffer_builder.hpp:148
lexy::_detail::buffer_builder::stack_buffer_size
static constexpr std::size_t stack_buffer_size
Definition: buffer_builder.hpp:25
lexy::_detail::buffer_builder::stable_iterator::stable_iterator
constexpr stable_iterator(const _detail::buffer_builder< T > &buffer, std::size_t idx) noexcept
Definition: buffer_builder.hpp:113
lexy::_detail::buffer_builder::stable_iterator::_buffer
const _detail::buffer_builder< T > * _buffer
Definition: buffer_builder.hpp:147
lexy::_detail::buffer_builder::clear
void clear() noexcept
Definition: buffer_builder.hpp:71
lexy::_detail::buffer_builder::_read_size
std::size_t _read_size
Definition: buffer_builder.hpp:153
lexy::_detail::buffer_builder::grow
void grow()
Definition: buffer_builder.hpp:86
lexy::_detail::buffer_builder::_stack_buffer
T _stack_buffer[stack_buffer_size]
Definition: buffer_builder.hpp:155
assert.hpp
magic_enum::detail::n
constexpr auto n() noexcept
Definition: magic_enum.hpp:417
lexy::_detail::buffer_builder::read_size
std::size_t read_size() const noexcept
Definition: buffer_builder.hpp:55
lexy::_detail::buffer_builder::stable_iterator::increment
constexpr void increment() noexcept
Definition: buffer_builder.hpp:124
lexy::_detail::buffer_builder::operator=
buffer_builder & operator=(const buffer_builder &)=delete
lexy::_detail::buffer_builder::growth_factor
static constexpr auto growth_factor
Definition: buffer_builder.hpp:26
lexy::_detail::buffer_builder::buffer_builder
buffer_builder() noexcept
Definition: buffer_builder.hpp:29
lexy::_detail
Definition: any_ref.hpp:12
lexy::buffer
Definition: buffer.hpp:81
lexy::_detail::buffer_builder::stable_iterator::index
constexpr std::size_t index() const noexcept
Definition: buffer_builder.hpp:141
lexy::_detail::buffer_builder::commit
void commit(std::size_t n) noexcept
Definition: buffer_builder.hpp:78
lexy::_detail::buffer_builder::total_size_bytes
static constexpr std::size_t total_size_bytes
Definition: buffer_builder.hpp:23
lexy::_detail::buffer_builder::capacity
std::size_t capacity() const noexcept
Definition: buffer_builder.hpp:45
lexy::_detail::forward_iterator_base
Definition: iterator.hpp:157
lexy::_detail::buffer_builder::~buffer_builder
~buffer_builder() noexcept
Definition: buffer_builder.hpp:34
lexy::_detail::buffer_builder::write_size
std::size_t write_size() const noexcept
Definition: buffer_builder.hpp:65
lexy::_detail::buffer_builder::stable_iterator::deref
constexpr const T & deref() const noexcept
Definition: buffer_builder.hpp:118
lexy::_detail::buffer_builder::_write_size
std::size_t _write_size
Definition: buffer_builder.hpp:154


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Jun 28 2024 02:20:07