// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using osu.Framework.Bindables; using osuTK; using osu.Framework.Graphics; #nullable enable namespace osu.Framework.Utils { public static class Validation { /// /// Returns whether the two coordinates of a are not infinite or NaN. /// For further information, see . /// /// The to check. /// False if X or Y are Infinity or NaN, true otherwise. public static bool IsFinite(Vector2 toCheck) => float.IsFinite(toCheck.X) && float.IsFinite(toCheck.Y); /// /// Returns whether the components of a are not infinite or NaN. /// For further information, see . /// /// The to check. /// False if either component of are Infinity or NaN, true otherwise. public static bool IsFinite(MarginPadding toCheck) => float.IsFinite(toCheck.Top) && float.IsFinite(toCheck.Bottom) && float.IsFinite(toCheck.Left) && float.IsFinite(toCheck.Right); /// /// Attempts to parse as an absolute or relative in a platform-agnostic manner. /// /// /// This method is a workaround for inconsistencies across .NET and mono runtimes; /// on mono runtimes paths starting with / are considered absolute as per POSIX, /// and on .NET such paths are considered to be relative. /// This method uses the .NET behaviour. /// For more info, see Mono documentation. /// /// The string representation of the URI to parse. /// The resultant parsed URI, if parsing succeeded. /// if parsing succeeded; otherwise. public static bool TryParseUri(string uriString, [NotNullWhen(true)] out Uri? result) { #pragma warning disable RS0030 // Bypassing banned API check, as it'll actually be used properly here UriKind kind = uriString.StartsWith('/') ? UriKind.Relative : UriKind.RelativeOrAbsolute; #pragma warning restore RS0030 return Uri.TryCreate(uriString, kind, out result); } /// /// Whether the specified type is a number type supported by . /// /// /// Directly comparing typeof(T) to type literal is recognized pattern of JIT and very fast. /// Just a pointer comparison for reference types, or constant for value types. /// The check will become NOP in usages after optimization. /// /// The type to check for. /// if the type is supported; otherwise. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsSupportedBindableNumberType() => typeof(T) == typeof(sbyte) || typeof(T) == typeof(byte) || typeof(T) == typeof(short) || typeof(T) == typeof(ushort) || typeof(T) == typeof(int) || typeof(T) == typeof(uint) || typeof(T) == typeof(long) || typeof(T) == typeof(ulong) || typeof(T) == typeof(float) || typeof(T) == typeof(double); } }