MCPcopy Create free account
hub / github.com/couchbase/fleece / narrow_cast

Function narrow_cast

Fleece/Support/NumConversion.hh:66–105  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

64 #if DEBUG
65 template<typename Out, typename In>
66 static Out narrow_cast (In val) {
67 static_assert(::std::is_arithmetic<In>::value && ::std::is_arithmetic<Out>::value, "Only numeric types are valid for narrow_cast");
68 if(sizeof(In) <= sizeof(Out) && ::std::is_signed<In>::value == ::std::is_signed<Out>::value) {
69 return (Out)val;
70 }
71
72 // Comparing an unsigned number against a signed minimum causes issues, at least on Windows,
73 // but if the output is signed and the input is unsigned then there is never a case where
74 // the input could underflow the output. The reverse situation does not appear to be true.
75 // the input could underflow the output. The reverse situation does not appear to be true.
76 bool min_ok = std::is_signed<Out>::value && !std::is_signed<In>::value;
77
78#ifdef Assert
79 if(::std::is_floating_point<In>::value) {
80 Assert(val >= std::numeric_limits<Out>::min() && val <= ::std::numeric_limits<Out>::max(),
81 "Invalid narrow_cast %g -> %s", (double)val, typeid(Out).name());
82 } else if(::std::is_signed<In>::value) {
83 Assert((min_ok || val >= std::numeric_limits<Out>::min()) && val <= ::std::numeric_limits<Out>::max(),
84 "Invalid narrow_cast %" PRIi64 " -> %s", (int64_t)val, typeid(Out).name());
85 } else {
86 Assert((min_ok || val >= std::numeric_limits<Out>::min()) && val <= ::std::numeric_limits<Out>::max(),
87 "Invalid narrow_cast %" PRIu64 " -> %s", (uint64_t)val, typeid(Out).name());
88 }
89#else
90 char message[256];
91 if(::std::is_floating_point<In>::value) {
92 sprintf(message, "Invalid narrow_cast %g -> %s", (double)val, typeid(Out).name());
93 throwIf(val < std::numeric_limits<Out>::min() || val > std::numeric_limits<Out>::max(), InternalError, message);
94 } else if(::std::is_signed<In>::value) {
95 sprintf(message, "Invalid narrow_cast %" PRIi64 " -> %s", (int64_t)val, typeid(Out).name());
96 throwIf((!min_ok && val < std::numeric_limits<Out>::min()) || val > std::numeric_limits<Out>::max(),
97 InternalError, message);
98 } else {
99 sprintf(message, "Invalid narrow_cast %" PRIu64 " -> %s", (uint64_t)val, typeid(Out).name());
100 throwIf((!min_ok && val < std::numeric_limits<Out>::min()) || val > std::numeric_limits<Out>::max(),
101 InternalError, message);
102 }
103#endif
104 return (Out)val;
105 }
106 #else
107 template<typename Out, typename In>
108 static inline Out narrow_cast(In val) {

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected