bytes.inl
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
#ifndef CRUCIBLE_PARSING_BYTES_INL #define CRUCIBLE_PARSING_BYTES_INL #include "crucible/parsing/bytes.hpp" #include <climits> namespace crucible::parsing::bytes { template<UnsignedIntegerType T, Endianness E> auto UnsignedInteger<T, E>::operator()(StateType const &initial_state) const -> ResultType { auto const remaining_bytes { initial_state.get_remaining_input() }; if (remaining_bytes.size() < sizeof(T)) { return errors::make_reject(initial_state, errors::InsufficientInput { sizeof(T) }); } T total { 0 }; auto const shift_next_byte { [](std::byte const next_byte, std::size_t const byte_index) { std::size_t const bits_to_shift { byte_index * CHAR_BIT }; auto const byte_value { std::to_integer<T>(next_byte) }; return static_cast<T>(byte_value << bits_to_shift); } }; for (std::size_t i { 0 }; i < sizeof(T); ++i) { if constexpr (E == Endianness::Le) { total |= shift_next_byte(remaining_bytes[i], i); } else { total |= shift_next_byte(remaining_bytes[i], sizeof(T) - (i + 1)); } } auto const next_state { initial_state.advance(sizeof(T)) }; return errors::make_accept(next_state, total); } } #endif // CRUCIBLE_PARSING_BYTES_INL