machines/projects/Printhead/test/mtest2/PriUint64.h
2023-11-12 21:43:05 +01:00

96 lines
2.0 KiB
C++

#ifndef PRIUINT64_H
#define PRIUINT64_H
#include <stdint.h>
#include <Print.h>
#include <Printable.h>
/** \brief Allow printing uint64_t value.
* \code
* uint64_t x = 1;
* Serial.print(PriUint64<DEC>(x));
* \endcode
*/
template<int Base>
class PriUint64 : public Printable
{
public:
explicit
PriUint64(uint64_t value, int ignored = 0)
: m_value(value)
{
}
size_t
printTo(Print& p) const override
{
char buf[8 * sizeof(uint64_t) + 1];
char* str = &buf[sizeof(buf) - 1];
*str = '\0';
uint64_t n = m_value;
do {
char c = n % Base;
n /= Base;
*--str = c < 10 ? c + '0' : c + 'A' - 10;
} while (n > 0);
return p.write(str);
}
private:
uint64_t m_value;
};
#if defined(ARDUINO_STREAMING) && defined(STREAMING_LIBRARY_VERSION) && STREAMING_LIBRARY_VERSION == 5
/** \brief Print uint64_t as decimal.
*/
inline Print&
operator<<(Print& p, uint64_t x)
{
return p << PriUint64<DEC>(x);
}
#if defined(ESP8266) || defined(ESP32)
#define PRIUINT64_OVERRIDE_STREAMING_BASED
// <type_traits> is available on ESP8266 and ESP32, but unavailable on AVR.
#endif
#ifdef PRIUINT64_OVERRIDE_STREAMING_BASED
#include <type_traits>
#undef _HEX
#undef _DEC
#undef _OCT
#undef _BIN
class _BASED1 : public _BASED, public Printable
{
public:
using _BASED::_BASED;
size_t
printTo(Print& p) const override
{
return p.print(val, base);
}
};
template<typename V, int Base, typename BaseCls = typename std::conditional<std::is_same<V, uint64_t>::value, PriUint64<Base>, _BASED1>::type>
class _BASED2 : public BaseCls
{
public:
using BaseCls::BaseCls;
};
#define _HEX(a) (_BASED2<decltype(a),HEX>(a, HEX))
#define _DEC(a) (_BASED2<decltype(a),DEC>(a, DEC))
#define _OCT(a) (_BASED2<decltype(a),OCT>(a, OCT))
#define _BIN(a) (_BASED2<decltype(a),BIN>(a, BIN))
#endif // PRIUINT64_OVERRIDE_STREAMING_BASED
#endif // ARDUINO_STREAMING
#endif // PRIUINT64_H