1010
1111#include < algorithm>
1212#include < atomic>
13+ #include < concepts>
1314#include < cstdint>
1415#include < cstring>
1516#include < ios>
@@ -193,9 +194,14 @@ template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
193194 FORMATTER_METHODS (cls, obj)
194195
195196// clang-format off
196- #ifndef CHAR_EQUALS_INT8
197- template <typename Stream> void Serialize (Stream&, char ) = delete; // char serialization forbidden. Use uint8_t or int8_t
198- #endif
197+
198+ // Typically int8_t and char are distinct types, but some systems may define int8_t
199+ // in terms of char. Forbid serialization of char in the typical case, but allow it if
200+ // it's the only way to describe an int8_t.
201+ template<class T>
202+ concept CharNotInt8 = std::same_as<T, char> && !std::same_as<T, int8_t>;
203+
204+ template <typename Stream, CharNotInt8 V> void Serialize (Stream&, V) = delete; // char serialization forbidden. Use uint8_t or int8_t
199205template <typename Stream> void Serialize (Stream& s, std::byte a) { ser_writedata8 (s, uint8_t (a)); }
200206template <typename Stream> inline void Serialize (Stream& s, int8_t a ) { ser_writedata8 (s, a); }
201207template <typename Stream> inline void Serialize (Stream& s, uint8_t a ) { ser_writedata8 (s, a); }
@@ -209,9 +215,7 @@ template<typename Stream, int N> inline void Serialize(Stream& s, const char (&a
209215template <typename Stream, int N> inline void Serialize (Stream& s, const unsigned char (&a)[N]) { s.write (MakeByteSpan (a)); }
210216template <typename Stream, typename B> void Serialize (Stream& s, Span<B> span) { (void )/* force byte-type */ UCharCast (span.data ()); s.write (AsBytes (span)); }
211217
212- #ifndef CHAR_EQUALS_INT8
213- template <typename Stream> void Unserialize (Stream&, char ) = delete; // char serialization forbidden. Use uint8_t or int8_t
214- #endif
218+ template <typename Stream, CharNotInt8 V> void Unserialize (Stream&, V) = delete; // char serialization forbidden. Use uint8_t or int8_t
215219template <typename Stream> void Unserialize (Stream& s, std::byte& a) { a = std::byte{ser_readdata8 (s)}; }
216220template <typename Stream> inline void Unserialize (Stream& s, int8_t & a ) { a = ser_readdata8 (s); }
217221template <typename Stream> inline void Unserialize (Stream& s, uint8_t & a ) { a = ser_readdata8 (s); }
0 commit comments