Arduino Helpers master
Utility library for Arduino
IncreaseBitDepth.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <AH/STL/type_traits> // enable_if
4#include <limits.h> // CHAR_BIT
5#include <stddef.h> // size_t
6
8
9namespace detail {
10
11template <size_t Bits_out, size_t Bits_in, class T_out, class T_in>
12std::enable_if_t<(Bits_out <= 2 * Bits_in) && (Bits_out > Bits_in), T_out>
14 constexpr size_t leftShift = Bits_out - Bits_in;
15 constexpr size_t rightShift = Bits_in - leftShift;
16 return (static_cast<T_out>(in) << leftShift) | (in >> rightShift);
17}
18
19template <size_t Bits_out, size_t Bits_in, class T_out, class T_in>
20std::enable_if_t<(Bits_out <= Bits_in), T_out> increaseBitDepthImpl(T_in in) {
21 constexpr size_t rightShift = Bits_in - Bits_out;
22 return static_cast<T_out>(in >> rightShift);
23}
24
25template <size_t Bits_out, size_t Bits_in, class T_out, class T_in>
26std::enable_if_t<(Bits_out > 2 * Bits_in), T_out>
28 constexpr size_t leftShift = Bits_out - Bits_in;
29 return (static_cast<T_out>(in) << leftShift) |
30 increaseBitDepthImpl<leftShift, Bits_in, T_out>(in);
31}
32
33} // namespace detail
34
37
76template <size_t Bits_out, size_t Bits_in, class T_out, class T_in>
77T_out increaseBitDepth(T_in in) {
78 static_assert(Bits_in <= sizeof(T_in) * CHAR_BIT,
79 "Error: Bits_in > bits(T_in)");
80 static_assert(Bits_out <= sizeof(T_out) * CHAR_BIT,
81 "Error: Bits_out > bits(T_out)");
82 return detail::increaseBitDepthImpl<Bits_out, Bits_in, T_out>(in);
83}
84
124template <size_t Bits_out, size_t Bits_in, class T_out, class T_in>
126 static_assert(Bits_in <= sizeof(T_in) * CHAR_BIT,
127 "Error: Bits_in > bits(T_in)");
128 static_assert(Bits_out <= sizeof(T_out) * CHAR_BIT,
129 "Error: Bits_out > bits(T_out)");
130 constexpr size_t leftShift = Bits_out - Bits_in;
131 T_in half = T_in {1} << (Bits_in - 1);
132 T_out out = static_cast<T_out>(in) << leftShift;
133 if (in > half) {
134 T_in repeat = in & (half - 1);
135 out |= increaseBitDepth<leftShift, Bits_in - 1, T_out>(repeat);
136 }
137 return out;
138}
139
141
#define END_AH_NAMESPACE
#define BEGIN_AH_NAMESPACE
T_out increaseBitDepthMiddle(T_in in)
Increase the bit depth of the given value from Bits_in bits wide to Bits_out bits wide,...
T_out increaseBitDepth(T_in in)
Increase the bit depth of the given value from Bits_in bits wide to Bits_out bits wide,...
std::enable_if_t<(Bits_out<=2 *Bits_in) &&(Bits_out > Bits_in), T_out > increaseBitDepthImpl(T_in in)