Path: blob/master/dep/rapidyaml/include/c4/szconv.hpp
4261 views
#ifndef _C4_SZCONV_HPP_1#define _C4_SZCONV_HPP_23/** @file szconv.hpp utilities to deal safely with narrowing conversions */45#include "c4/config.hpp"6#include "c4/error.hpp"78#include <limits>910namespace c4 {1112C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wold-style-cast")1314/** @todo this would be so much easier with calls to numeric_limits::max()... */15template<class SizeOut, class SizeIn>16struct is_narrower_size : std::conditional17<18(std::is_signed<SizeOut>::value == std::is_signed<SizeIn>::value)19?20(sizeof(SizeOut) < sizeof(SizeIn))21:22(23(sizeof(SizeOut) < sizeof(SizeIn))24||25(26(sizeof(SizeOut) == sizeof(SizeIn))27&&28(std::is_signed<SizeOut>::value && std::is_unsigned<SizeIn>::value)29)30),31std::true_type,32std::false_type33>::type34{35static_assert(std::is_integral<SizeIn >::value, "must be integral type");36static_assert(std::is_integral<SizeOut>::value, "must be integral type");37};383940/** when SizeOut is wider than SizeIn, assignment can occur without reservations */41template<class SizeOut, class SizeIn>42C4_ALWAYS_INLINE43typename std::enable_if< ! is_narrower_size<SizeOut, SizeIn>::value, SizeOut>::type44szconv(SizeIn sz) noexcept45{46return static_cast<SizeOut>(sz);47}4849/** when SizeOut is narrower than SizeIn, narrowing will occur, so we check50* for overflow. Note that this check is done only if C4_XASSERT is enabled.51* @see C4_XASSERT */52template<class SizeOut, class SizeIn>53C4_ALWAYS_INLINE54typename std::enable_if<is_narrower_size<SizeOut, SizeIn>::value, SizeOut>::type55szconv(SizeIn sz) C4_NOEXCEPT_X56{57C4_XASSERT(sz >= 0);58C4_XASSERT_MSG((SizeIn)sz <= (SizeIn)std::numeric_limits<SizeOut>::max(), "size conversion overflow: in=%zu", (size_t)sz);59SizeOut szo = static_cast<SizeOut>(sz);60return szo;61}6263C4_SUPPRESS_WARNING_GCC_CLANG_POP6465} // namespace c46667#endif /* _C4_SZCONV_HPP_ */686970