distortos  v0.7.0
object-oriented C++ RTOS for microcontrollers
extractBitField.hpp
Go to the documentation of this file.
1 
12 #ifndef ESTD_EXTRACTBITFIELD_HPP_
13 #define ESTD_EXTRACTBITFIELD_HPP_
14 
15 #include "estd/TypeFromSize.hpp"
16 
17 #include <array>
18 
19 #include <climits>
20 
21 namespace estd
22 {
23 
39 template<size_t index, size_t size, bool reverse = {}, typename Ret = TypeFromSize<(size + CHAR_BIT - 1) / CHAR_BIT>,
40  typename T, size_t arraySize>
41 inline static Ret extractBitField(const std::array<T, arraySize>& array)
42 {
43  static_assert(size <= sizeof(Ret) * CHAR_BIT, "`Ret` is too small to fit `size` bits!");
44  static_assert(index + size <= sizeof(array) * CHAR_BIT, "Bit field is out of `array` bounds!");
45 
46  constexpr auto divider = sizeof(T) * CHAR_BIT;
47  constexpr auto begin = index / divider;
48  constexpr auto offset = index % divider;
49  constexpr auto end = (index + size + divider - 1) / divider;
50 
51  Ret value {};
52  for (auto i = begin; i < end; ++i)
53  {
54  using Element = typename std::conditional<sizeof(Ret) >= sizeof(T), Ret, T>::type;
55  const Element element = reverse == false ? array[i] : array.rbegin()[i];
56  const auto shift = static_cast<int>((i - begin) * divider) - static_cast<int>(offset);
57  if (shift >= 0)
58  value |= element << shift;
59  else
60  value |= element >> -shift;
61  }
62 
63  value &= (Ret{1} << size) - 1;
64  return value;
65 }
66 
67 } // namespace estd
68 
69 #endif // ESTD_EXTRACTBITFIELD_HPP_
Collection of useful templates.
Definition: DmaChannel.hpp:121
typename internal::TypeFromSize< size >::Type TypeFromSize
Selects fixed width type from requested byte size.
Definition: TypeFromSize.hpp:60
TypeFromSize type alias template header.
static Ret extractBitField(const std::array< T, arraySize > &array)
Extracts a bit field from array of raw data.
Definition: extractBitField.hpp:41