1#ifndef BYTEME_PERBYTE_HPP
2#define BYTEME_PERBYTE_HPP
10#include <condition_variable>
26template<
class Reader_>
27void skip_zero_buffers(Reader_& reader, std::size_t& available) {
29 while (reader.load()) {
30 available = reader.available();
51template<
typename Type_>
71 const Type_*
ptr =
nullptr;
85 std::size_t my_current = 0;
89 unsigned long long my_overall = 0;
116 return ptr[my_current];
123 return my_overall + my_current;
152 std::pair<std::size_t, bool>
extract(std::size_t number, Type_* output) {
153 std::size_t original = number;
157 auto start =
ptr + my_current;
160 if (leftover > number) {
161 my_current += number;
163 std::copy(start,
ptr + my_current, output);
175 if (number == 0 || !okay) {
182 return std::make_pair(original - number, okay);
205 std::size_t original = number;
208 auto start =
ptr + my_current;
211 if (leftover >= number) {
212 std::copy_n(start, number, output);
213 my_current += number - 1;
231 return original - number;
247template<
typename Type_,
class Po
inter_ = std::unique_ptr<Reader> >
263 skip_zero_buffers(*my_reader, this->available);
264 this->
ptr =
reinterpret_cast<const Type_*
>(my_reader->buffer());
279template<
typename Type_,
class Po
inter_ = std::unique_ptr<Reader> >
287 my_ready_input =
false;
288 my_thread = std::thread([&]() { thread_loop(); });
290 skip_zero_buffers(*my_reader, my_next_available);
291 my_ready_output =
true;
300 std::unique_lock lck(my_mut);
302 my_ready_input =
true;
314 std::vector<Type_> my_buffer;
315 std::size_t my_next_available = 0;
316 bool my_finished =
false;
319 std::thread my_thread;
320 std::exception_ptr my_thread_err =
nullptr;
322 std::condition_variable my_cv;
323 bool my_ready_input, my_ready_output;
326 while (!my_finished) {
327 std::unique_lock lck(my_mut);
328 my_cv.wait(lck, [&]() {
return my_ready_input; });
329 my_ready_input =
false;
336 skip_zero_buffers(*my_reader, my_next_available);
337 my_finished = my_next_available == 0;
339 my_thread_err = std::current_exception();
343 my_ready_output =
true;
357 std::unique_lock lck(my_mut);
358 my_cv.wait(lck, [&]() {
return my_ready_output; });
359 my_ready_output =
false;
361 std::rethrow_exception(my_thread_err);
364 auto rptr =
reinterpret_cast<const Type_*
>(my_reader->buffer());
365 this->available = my_next_available;
366 my_buffer.resize(this->available);
367 std::copy_n(rptr, this->available, my_buffer.data());
368 this->
ptr = my_buffer.data();
370 my_ready_input =
true;
Interface for byte-by-byte extraction from a Reader source.
Definition PerByte.hpp:52
unsigned long long position() const
Definition PerByte.hpp:122
const Type_ * ptr
Definition PerByte.hpp:71
bool valid() const
Definition PerByte.hpp:129
Type_ get() const
Definition PerByte.hpp:115
bool advance()
Definition PerByte.hpp:98
std::pair< std::size_t, bool > extract(std::size_t number, Type_ *output)
Definition PerByte.hpp:152
std::size_t available
Definition PerByte.hpp:76
std::size_t advance_and_extract(std::size_t number, Type_ *output)
Definition PerByte.hpp:200
Parallelized byte-by-byte extraction from a Reader source.
Definition PerByte.hpp:280
void refill()
Definition PerByte.hpp:350
PerByteParallel(Pointer_ reader)
Definition PerByte.hpp:286
Serial byte-by-byte extraction from a Reader source.
Definition PerByte.hpp:248
PerByteSerial(Pointer_ reader)
Definition PerByte.hpp:254
void refill()
Definition PerByte.hpp:262
Simple byte readers and writers.