CircularIndex: fight against type promotion in size checks
To generate optimal code, size itself needs to be of the same type as the index to avoid promotion to the largest type. In full(), wrap the subtraction explicity in another type cast to avoid another automatic type promotion.pull/49/head
parent
f57a1c3b17
commit
f95c47638d
|
|
@ -12,11 +12,11 @@
|
||||||
/// (recommended to keep uint8_fast8_t as single byte operations are atomical on the AVR)
|
/// (recommended to keep uint8_fast8_t as single byte operations are atomical on the AVR)
|
||||||
/// @param size number of index positions.
|
/// @param size number of index positions.
|
||||||
/// It is recommended to keep a power of 2 to allow for optimal code generation on the AVR (there is no HW modulo instruction)
|
/// It is recommended to keep a power of 2 to allow for optimal code generation on the AVR (there is no HW modulo instruction)
|
||||||
template <typename index_t = uint_fast8_t, size_t size = 16>
|
template <typename index_t = uint_fast8_t, index_t size = 16>
|
||||||
class CircularIndex {
|
class CircularIndex {
|
||||||
public:
|
public:
|
||||||
#ifndef __AVR__
|
#ifndef __AVR__
|
||||||
static_assert(size <= std::numeric_limits<index_t>::max(),
|
static_assert(size <= std::numeric_limits<index_t>::max() / 2,
|
||||||
"index_t is too small for the requested size");
|
"index_t is too small for the requested size");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -33,7 +33,7 @@ public:
|
||||||
inline bool full() const {
|
inline bool full() const {
|
||||||
// alternative without wrap-around logic:
|
// alternative without wrap-around logic:
|
||||||
// return tail != head && mask(tail) == mask(head);
|
// return tail != head && mask(tail) == mask(head);
|
||||||
return (head - tail) % (size * 2) == size;
|
return ((index_t)(head - tail) % (size * 2)) == size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Advance the head index of the buffer.
|
/// Advance the head index of the buffer.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue