diff --git a/Application/src/commons/common/gui/DrawCVBase.cpp b/Application/src/commons/common/gui/DrawCVBase.cpp index b6c567de2e55146207ff4aae271e80d9beb3fbc6..96abdb55821d3a483d6643a07ce1e58e4c06eb1a 100644 --- a/Application/src/commons/common/gui/DrawCVBase.cpp +++ b/Application/src/commons/common/gui/DrawCVBase.cpp @@ -113,7 +113,7 @@ namespace gui { auto ptr = static_cast<Vertices*>(o); float t = 1; if(dynamic_cast<Line*>(o)) - t = static_cast<Line*>(o)->thickness(); + t = max(1, min(static_cast<Line*>(o)->thickness(), CV_MAX_THICKNESS)); if(ptr->primitive() != LineStrip && ptr->primitive() != Lines) U_EXCEPTION("Does not support other primitive types yet."); diff --git a/Application/src/commons/common/misc/metastring.h b/Application/src/commons/common/misc/metastring.h index 5abcc365fac24141283d0ee11fc20e76541a6261..3d31a6c93f5d8f3138f8d75d45edb9592a124e30 100644 --- a/Application/src/commons/common/misc/metastring.h +++ b/Application/src/commons/common/misc/metastring.h @@ -1035,4 +1035,100 @@ namespace cmn { } } +namespace cmn { +namespace tag { +struct warn_on_error {}; +struct fail_on_error {}; +} + +template<typename To, typename From> +constexpr To narrow_cast(From&& value, struct tag::warn_on_error) { + using FromType = typename remove_cvref<From>::type; + using ToType = typename remove_cvref<To>::type; + static_assert(sizeof(FromType) > sizeof(ToType) || (std::is_unsigned<FromType>::value && std::is_signed<ToType>::value), "From type has to be bigger than to type."); + //static_assert(std::numeric_limits<ToType>::max() <= std::numeric_limits<FromType>::max(), "Maximum numeric limits of To type are larger than From type."); + //static_assert(std::numeric_limits<ToType>::min() >= std::numeric_limits<FromType>::min(), "Minimum numeric limits of To type are smaller than From type."); + + bool out_ranged = value > (FromType)std::numeric_limits<To>::max() + || value < (FromType)std::numeric_limits<To>::min(); + if constexpr( + std::is_floating_point<FromType>::value + || (std::is_unsigned<FromType>::value && std::is_unsigned<ToType>::value) + || (std::is_signed<FromType>::value && std::is_signed<ToType>::value) + ) { + // unsigned to unsigned + + } else if constexpr(std::is_unsigned<FromType>::value && std::is_signed<ToType>::value) { + // unsigned to signed + using signed_t = int64_t; + out_ranged = static_cast<signed_t>(value) > static_cast<signed_t>(std::numeric_limits<To>::max()); + + } else { + static_assert(std::is_signed<FromType>::value && std::is_unsigned<ToType>::value, "Expecting signed to unsigned conversion"); + // signed to unsigned + using unsigned_t = typename std::make_unsigned<FromType>::type; + out_ranged = value < 0 || static_cast<unsigned_t>(value) > static_cast<unsigned_t>(std::numeric_limits<To>::max()); + } + + if(out_ranged) { + auto vstr = Meta::toStr(value); + auto lstr = Meta::toStr(std::numeric_limits<To>::min()); + auto rstr = Meta::toStr(std::numeric_limits<To>::max()); + + auto tstr = Meta::name<To>(); + auto fstr = Meta::name<From>(); + Warning("Value '%S' in narrowing conversion of %S -> %S is not within limits [%S,%S].", &vstr, &fstr, &tstr, &lstr, &rstr); + } + + return static_cast<To>(std::forward<From>(value)); +} + +template<typename To, typename From> +constexpr To narrow_cast(From&& value, struct tag::fail_on_error) { + using FromType = typename remove_cvref<From>::type; + using ToType = typename remove_cvref<To>::type; + static_assert(sizeof(FromType) > sizeof(ToType) || (std::is_unsigned<FromType>::value && std::is_signed<ToType>::value), "From type has to be bigger than to type."); + //static_assert(std::numeric_limits<ToType>::max() <= std::numeric_limits<FromType>::max(), "Maximum numeric limits of To type are larger than From type."); + //static_assert(std::numeric_limits<ToType>::min() >= std::numeric_limits<FromType>::min(), "Minimum numeric limits of To type are smaller than From type."); + + bool out_ranged = value > (FromType)std::numeric_limits<To>::max() + || value < (FromType)std::numeric_limits<To>::min(); + if constexpr( + std::is_floating_point<FromType>::value + || (std::is_unsigned<FromType>::value && std::is_unsigned<ToType>::value) + || (std::is_signed<FromType>::value && std::is_signed<ToType>::value) + ) { + // unsigned to unsigned + + } else if constexpr(std::is_unsigned<FromType>::value && std::is_signed<ToType>::value) { + // unsigned to signed + using signed_t = int64_t; + out_ranged = static_cast<signed_t>(value) > static_cast<signed_t>(std::numeric_limits<To>::max()); + + } else { + static_assert(std::is_signed<FromType>::value && std::is_unsigned<ToType>::value, "Expecting signed to unsigned conversion"); + // signed to unsigned + using unsigned_t = typename std::make_unsigned<FromType>::type; + out_ranged = value < 0 || static_cast<unsigned_t>(value) > static_cast<unsigned_t>(std::numeric_limits<To>::max()); + } + + if(out_ranged) { + auto vstr = Meta::toStr(value); + auto lstr = Meta::toStr(std::numeric_limits<To>::min()); + auto rstr = Meta::toStr(std::numeric_limits<To>::max()); + + auto tstr = Meta::name<To>(); + auto fstr = Meta::name<From>(); + U_EXCEPTION("Value '%S' in narrowing conversion of %S -> %S is not within limits [%S,%S].", &vstr, &fstr, &tstr, &lstr, &rstr); + } + + return static_cast<To>(std::forward<From>(value)); +} + +template<typename To, typename From> +constexpr To narrow_cast(From&& value) { + return narrow_cast<To, From>(std::forward<From>(value), tag::warn_on_error{}); +} +} + #endif diff --git a/Application/src/tracker/main.cpp b/Application/src/tracker/main.cpp index cdb8eb3d1737a7898adf8b7ec2be7878f8a492fe..212506034af5667aa123bea221f6368ca10ddd4c 100644 --- a/Application/src/tracker/main.cpp +++ b/Application/src/tracker/main.cpp @@ -1158,7 +1158,7 @@ int main(int argc, char** argv) auto ptr = unused.front(); unused.pop(); - ptr->set_index(++currentID); + ptr->set_index(narrow_cast<long_t>(++currentID)); analysis->add(ptr); }