Build: add GCC-13, Clang-14, Clang-15, Clang-16, Clang-17
[marnav.git] / include / marnav / nmea / checksum.hpp
blob35b35ca57582519c431b25d98ac4a5339ce6d6a7
1 #ifndef MARNAV_NMEA_CHECKSUM_HPP
2 #define MARNAV_NMEA_CHECKSUM_HPP
4 #include <algorithm>
5 #include <stdexcept>
6 #include <string>
7 #include <cstdint>
9 namespace marnav::nmea
11 /// Exception for cases where the checksum is wrong.
12 ///
13 /// This exception carries the actual as well as the expected
14 /// checksum and will provide this information in the explanation.
15 class checksum_error : public std::exception
17 public:
18 checksum_error() = delete;
19 explicit checksum_error(uint8_t exp, uint8_t act);
20 checksum_error(const checksum_error &) = default;
21 checksum_error(checksum_error &&) = default;
23 checksum_error & operator=(const checksum_error &) = default;
24 checksum_error & operator=(checksum_error &&) = default;
26 const char * what() const noexcept override { return text_; }
28 uint8_t expected() const noexcept { return expected_; }
29 uint8_t actual() const noexcept { return actual_; }
31 private:
32 uint8_t expected_ = 0u;
33 uint8_t actual_ = 0u;
34 char text_[64];
37 /// Computes and returns the checksum of the specified range.
38 ///
39 /// @tparam Iterator Iterator type which dereferences to a \c char.
40 /// @param[in] a The starting point to compute the checksum.
41 /// @param[in] b The ending point (exclusive) to compute the checksum.
42 /// @return The computed checksum.
43 ///
44 template <class Iterator>
45 uint8_t checksum(Iterator a, Iterator b) noexcept
47 uint8_t sum = 0x00;
48 std::for_each(a, b, [&sum](char c) { sum ^= static_cast<uint8_t>(c); });
49 return sum;
52 std::string checksum_to_string(uint8_t sum);
55 #endif