duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

szconv.hpp (1918B)


      1 #ifndef _C4_SZCONV_HPP_
      2 #define _C4_SZCONV_HPP_
      3 
      4 /** @file szconv.hpp utilities to deal safely with narrowing conversions */
      5 
      6 #include "c4/config.hpp"
      7 #include "c4/error.hpp"
      8 
      9 #include <limits>
     10 
     11 namespace c4 {
     12 
     13 C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wold-style-cast")
     14 
     15 /** @todo this would be so much easier with calls to numeric_limits::max()... */
     16 template<class SizeOut, class SizeIn>
     17 struct is_narrower_size : std::conditional
     18 <
     19    (std::is_signed<SizeOut>::value == std::is_signed<SizeIn>::value)
     20    ?
     21    (sizeof(SizeOut) < sizeof(SizeIn))
     22    :
     23    (
     24        (sizeof(SizeOut) < sizeof(SizeIn))
     25        ||
     26        (
     27            (sizeof(SizeOut) == sizeof(SizeIn))
     28            &&
     29            (std::is_signed<SizeOut>::value && std::is_unsigned<SizeIn>::value)
     30        )
     31    ),
     32    std::true_type,
     33    std::false_type
     34 >::type
     35 {
     36     static_assert(std::is_integral<SizeIn >::value, "must be integral type");
     37     static_assert(std::is_integral<SizeOut>::value, "must be integral type");
     38 };
     39 
     40 
     41 /** when SizeOut is wider than SizeIn, assignment can occur without reservations */
     42 template<class SizeOut, class SizeIn>
     43 C4_ALWAYS_INLINE
     44 typename std::enable_if< ! is_narrower_size<SizeOut, SizeIn>::value, SizeOut>::type
     45 szconv(SizeIn sz) noexcept
     46 {
     47     return static_cast<SizeOut>(sz);
     48 }
     49 
     50 /** when SizeOut is narrower than SizeIn, narrowing will occur, so we check
     51  * for overflow. Note that this check is done only if C4_XASSERT is enabled.
     52  * @see C4_XASSERT */
     53 template<class SizeOut, class SizeIn>
     54 C4_ALWAYS_INLINE
     55 typename std::enable_if<is_narrower_size<SizeOut, SizeIn>::value, SizeOut>::type
     56 szconv(SizeIn sz) C4_NOEXCEPT_X
     57 {
     58     C4_XASSERT(sz >= 0);
     59     C4_XASSERT_MSG((SizeIn)sz <= (SizeIn)std::numeric_limits<SizeOut>::max(), "size conversion overflow: in=%zu", (size_t)sz);
     60     SizeOut szo = static_cast<SizeOut>(sz);
     61     return szo;
     62 }
     63 
     64 C4_SUPPRESS_WARNING_GCC_CLANG_POP
     65 
     66 } // namespace c4
     67 
     68 #endif /* _C4_SZCONV_HPP_ */