|
10 | 10 | #include <stdx/ct_string.hpp>
|
11 | 11 | #include <stdx/iterator.hpp>
|
12 | 12 | #include <stdx/ranges.hpp>
|
| 13 | +#include <stdx/span.hpp> |
13 | 14 | #include <stdx/type_traits.hpp>
|
14 | 15 |
|
15 | 16 | #include <algorithm>
|
|
20 | 21 | #include <limits>
|
21 | 22 | #include <span>
|
22 | 23 | #include <type_traits>
|
| 24 | +#include <utility> |
23 | 25 |
|
24 | 26 | namespace msg {
|
25 | 27 | template <typename T>
|
@@ -331,6 +333,9 @@ struct at {
|
331 | 333 | [[nodiscard]] constexpr auto lsb() const -> std::underlying_type_t<lsb_t> {
|
332 | 334 | return stdx::to_underlying(lsb_) % 32u;
|
333 | 335 | }
|
| 336 | + [[nodiscard]] constexpr auto msb() const -> std::underlying_type_t<msb_t> { |
| 337 | + return stdx::to_underlying(msb_); |
| 338 | + } |
334 | 339 | [[nodiscard]] constexpr auto size() const -> std::underlying_type_t<lsb_t> {
|
335 | 340 | return stdx::to_underlying(msb_) - stdx::to_underlying(lsb_) + 1;
|
336 | 341 | }
|
@@ -424,13 +429,27 @@ class field_t : public field_spec_t<Name, T, detail::field_size<Ats...>>,
|
424 | 429 | return locator_t::template extract<spec_t>(std::forward<R>(r));
|
425 | 430 | }
|
426 | 431 |
|
| 432 | + template <std::unsigned_integral U> |
| 433 | + [[nodiscard]] constexpr static auto extract(U const &u) -> value_type { |
| 434 | + static_assert(stdx::bit_size<U>() > std::max({0u, Ats.msb()...}), |
| 435 | + "Field location is outside the range of argument!"); |
| 436 | + return extract(stdx::span{std::addressof(u), 1}); |
| 437 | + } |
| 438 | + |
427 | 439 | template <stdx::range R>
|
428 | 440 | constexpr static void insert(R &&r, value_type const &value) {
|
429 | 441 | static_assert(is_mutable_value<field_t>,
|
430 | 442 | "Can't change a field with a required value!");
|
431 | 443 | locator_t::template insert<spec_t>(std::forward<R>(r), value);
|
432 | 444 | }
|
433 | 445 |
|
| 446 | + template <std::unsigned_integral U> |
| 447 | + constexpr static void insert(U &u, value_type const &value) { |
| 448 | + static_assert(stdx::bit_size<U>() > std::max({0u, Ats.msb()...}), |
| 449 | + "Field location is outside the range of argument!"); |
| 450 | + insert(stdx::span{std::addressof(u), 1}, value); |
| 451 | + } |
| 452 | + |
434 | 453 | template <stdx::range R> constexpr static void insert_default(R &&r) {
|
435 | 454 | if constexpr (has_default_value<Default>) {
|
436 | 455 | locator_t::template insert<spec_t>(std::forward<R>(r),
|
|
0 commit comments