31 #ifndef GOOGLE_PROTOBUF_PYTHON_CPP_SAFE_NUMERICS_H__
32 #define GOOGLE_PROTOBUF_PYTHON_CPP_SAFE_NUMERICS_H__
37 #include <google/protobuf/stubs/logging.h>
38 #include <google/protobuf/stubs/common.h>
44 template <
bool SameSize,
bool DestLarger,
45 bool DestIsSigned,
bool SourceIsSigned>
46 struct IsValidNumericCastImpl;
48 #define BASE_NUMERIC_CAST_CASE_SPECIALIZATION(A, B, C, D, Code) \
49 template <> struct IsValidNumericCastImpl<A, B, C, D> { \
50 template <class Source, class DestBounds> static inline bool Test( \
51 Source source, DestBounds min, DestBounds max) { \
56 #define BASE_NUMERIC_CAST_CASE_SAME_SIZE(DestSigned, SourceSigned, Code) \
57 BASE_NUMERIC_CAST_CASE_SPECIALIZATION( \
58 true, true, DestSigned, SourceSigned, Code); \
59 BASE_NUMERIC_CAST_CASE_SPECIALIZATION( \
60 true, false, DestSigned, SourceSigned, Code)
62 #define BASE_NUMERIC_CAST_CASE_SOURCE_LARGER(DestSigned, SourceSigned, Code) \
63 BASE_NUMERIC_CAST_CASE_SPECIALIZATION( \
64 false, false, DestSigned, SourceSigned, Code); \
66 #define BASE_NUMERIC_CAST_CASE_DEST_LARGER(DestSigned, SourceSigned, Code) \
67 BASE_NUMERIC_CAST_CASE_SPECIALIZATION( \
68 false, true, DestSigned, SourceSigned, Code); \
103 source >=
min && source <=
max);
106 source >= 0 && source <=
max);
124 #undef BASE_NUMERIC_CAST_CASE_SPECIALIZATION
125 #undef BASE_NUMERIC_CAST_CASE_SAME_SIZE
126 #undef BASE_NUMERIC_CAST_CASE_SOURCE_LARGER
127 #undef BASE_NUMERIC_CAST_CASE_DEST_LARGER
131 template <
class Dest,
class Source>
133 typedef std::numeric_limits<Source> SourceLimits;
134 typedef std::numeric_limits<Dest> DestLimits;
135 static_assert(SourceLimits::is_specialized,
"argument must be numeric");
136 static_assert(SourceLimits::is_integer,
"argument must be integral");
137 static_assert(DestLimits::is_specialized,
"result must be numeric");
138 static_assert(DestLimits::is_integer,
"result must be integral");
140 return IsValidNumericCastImpl<
141 sizeof(Dest) ==
sizeof(
Source),
142 (
sizeof(Dest) >
sizeof(
Source)),
143 DestLimits::is_signed,
144 SourceLimits::is_signed>::
Test(
154 template <
class Dest,
class Source>
157 return static_cast<Dest
>(source);
164 #endif // GOOGLE_PROTOBUF_PYTHON_CPP_SAFE_NUMERICS_H__