diff --git a/Application/src/commons/common/misc/metastring.h b/Application/src/commons/common/misc/metastring.h
index ca12fa3a558d21a257c0ab54aeb59d8f40ed4ced..e8c7784577707bca03cd5a026f1ad2b65b32ff4a 100644
--- a/Application/src/commons/common/misc/metastring.h
+++ b/Application/src/commons/common/misc/metastring.h
@@ -1040,91 +1040,116 @@ struct warn_on_error {};
 struct fail_on_error {};
 }
 
+template<typename T>
+using try_make_unsigned =
+typename std::conditional<
+	std::is_integral<T>::value,
+	std::make_unsigned<T>,
+	double
+>::type;
+
+template<typename T>
+using try_make_signed =
+typename std::conditional<
+	std::is_integral<T>::value,
+	std::make_signed<T>,
+	double
+>::type;
+
 template<typename To, typename From>
-constexpr To narrow_cast(From&& value, struct tag::warn_on_error) {
+constexpr bool check_narrow_cast(const From& value) {
     using FromType = typename remove_cvref<From>::type;
     using ToType = typename remove_cvref<To>::type;
 
-    if constexpr (sizeof(FromType) <= sizeof(ToType))
-        return static_cast<ToType>(std::forward<From>(value));
-
-    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)
-      ) {
+    auto str = Meta::toStr(value);
+    if constexpr (
+        std::is_floating_point<ToType>::value
+        || (std::is_signed<FromType>::value == std::is_signed<ToType>::value && !std::is_floating_point<FromType>::value)
+        )
+    {
         // unsigned to unsigned
-        
-    } else if constexpr(std::is_unsigned<FromType>::value && std::is_signed<ToType>::value) {
+#ifdef _NARROW_PRINT_VERBOSE
+        auto tstr0 = Meta::name<FromType>();
+        auto tstr1 = Meta::name<ToType>();
+        Debug("Narrowing %S -> %S (same) = %S.", &tstr0, &tstr1, &str);
+#endif
+        return true;
+    }
+    else if constexpr (std::is_floating_point<FromType>::value && std::is_signed<ToType>::value) {
+        using signed_t = int64_t;
+#ifdef _NARROW_PRINT_VERBOSE
+        auto tstr0 = Meta::name<FromType>();
+        auto tstr1 = Meta::name<ToType>();
+        auto tstr2 = Meta::name<signed_t>();
+        Debug("Narrowing %S -> %S | converting to %S and comparing (fs) = %S.", &tstr0, &tstr1, &tstr2, &str);
+#endif
+        return static_cast<signed_t>(value) >= static_cast<signed_t>(std::numeric_limits<To>::min())
+            && static_cast<signed_t>(value) <= static_cast<signed_t>(std::numeric_limits<To>::max());
+    }
+    else if constexpr (std::is_floating_point<FromType>::value && std::is_unsigned<ToType>::value) {
+        using unsigned_t = uint64_t;
+#ifdef _NARROW_PRINT_VERBOSE
+        auto tstr0 = Meta::name<FromType>();
+        auto tstr1 = Meta::name<ToType>();
+        auto tstr2 = Meta::name<unsigned_t>();
+        Debug("Narrowing %S -> %S | converting to %S and comparing (fs) = %S.", &tstr0, &tstr1, &tstr2, &str);
+#endif
+        return value >= FromType(0)
+            && static_cast<unsigned_t>(value) <= static_cast<unsigned_t>(std::numeric_limits<To>::max());
+    }
+    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 {
+#ifdef _NARROW_PRINT_VERBOSE
+        auto tstr0 = Meta::name<FromType>();
+        auto tstr1 = Meta::name<ToType>();
+        auto tstr2 = Meta::name<signed_t>();
+        Debug("Narrowing %S -> %S | converting to %S and comparing (us) = %S.", &tstr0, &tstr1, &tstr2, &str);
+#endif
+        return 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());
+        using unsigned_t = typename try_make_unsigned<FromType>::type;
+#ifdef _NARROW_PRINT_VERBOSE
+        auto tstr0 = Meta::name<FromType>();
+        auto tstr1 = Meta::name<ToType>();
+        auto tstr2 = Meta::name<unsigned_t>();
+        Debug("Narrowing %S -> %S | converting to %S and comparing (su) = %S.", &tstr0, &tstr1, &tstr2, &str);
+#endif
+        return value >= 0 && static_cast<unsigned_t>(value) <= static_cast<unsigned_t>(std::numeric_limits<To>::max());
     }
-    
-    if(out_ranged) {
+}
+
+template<typename To, typename From>
+constexpr To narrow_cast(From&& value, struct tag::warn_on_error) {
+    if (!check_narrow_cast<To, From>(value)) {
         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) {
+    if (!check_narrow_cast<To, From>(value)) {
         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));
 }