# Changelog ## [3.0.0] In the midst of writing these release notes, I may have missed some important changes. If you notice an API change that is not documented here, please [open an issue](https://github.com/oliverbooth/X10D/issues)! ### Added - Added `T.AsArrayValue()` - Added `T.AsEnumerableValue()` - Added `T.RepeatValue(int)` - Added `T.ToJson([JsonSerializerOptions])` - Added `string.FromJson([JsonSerializerOptions])` - Added `T[].AsReadOnly()` - Added `T[].Clear([Range])` and `T[].Clear(int, int)` - Added `DateTime.IsLeapYear()` - Added `DateTimeOffset.IsLeapYear()` - Added `Endianness` enum - Added `FileInfo.GetHash()` - Added `FileInfo.TryWriteHash(Span, out int)` - Added `IComparable.Clamp(T, T)` - this supersedes `Clamp` defined for hard-coded numeric types (#24) - Added `IComparable.GreaterThan(T2)` (#22) - Added `IComparable.GreaterThanOrEqualTo(T2)` (#22) - Added `IComparable.LessThan(T2)` (#22) - Added `IComparable.LessThanOrEqualTo(T2)` (#22) - Added `IComparable.Max(T)` (#23) - Added `IComparable.Min(T)` (#23) - Added `IDictionary.AddOrUpdate()` - Added `IEnumerable.Product()` and `IEnumerable.Product(Func, TResult)` for all built-in numeric types, computing the product of all (optionally transformed) elements - Added `IList.Fill(T)` and `IList.Fill(T, int, int)` - Added `IPAddress.IsIPv4()` and `IPAddress.IsIPv6()` - Added `IReadOnlyList.Pack8Bit()` - Added `IReadOnlyList.Pack16Bit()` - Added `IReadOnlyList.Pack32Bit()` - Added `IReadOnlyList.Pack64Bit()` - Added `MemberInfo.HasCustomAttribute()` and `MemberInfo.HasCustomAttribute(Type)` - Added `defaultValue` overload for `MemberInfo.SelectFromCustomAttribute()` - Added `Random.Next()` (returns a random field from a specified enum type) - Added `Random.NextByte([byte[, byte]])` - Added `Random.NextColorArgb()`, returning a random color in RGB space, including random alpha - Added `Random.NextColorRgb()`, returning a random color in RGB space with alpha 255 - Added `Random.NextDouble(double[, double])` - Added `Random.NextInt16([short[, short]])` - Added `Random.NextSingle(float[, float])` (#34) - Added `Random.NextUnitVector2()` - Added `Random.NextUnitVector3()` - Added `Random.NextRotation()` - Added `Rune.Repeat(int)` - Added `byte.IsEven()` - Added `byte.IsOdd()` - Added `byte.IsPrime()` - Added `byte.UnpackBits()` - Added `byte.RangeTo(byte)`, `byte.RangeTo(short)`, `byte.RangeTo(int)`, and `byte.RangeTo(long)` - Added `int.Mod(int)` - Added `int.RangeTo(int)`, and `int.RangeTo(long)` - Added `int.UnpackBits()` - Added `long.Mod(long)` - Added `long.RangeTo(long)` - Added `long.UnpackBits()` - Added `sbyte.IsEven()` - Added `sbyte.IsOdd()` - Added `sbyte.IsPrime()` - Added `sbyte.Mod(sbyte)` - Added `short.IsEven()` - Added `short.IsOdd()` - Added `short.Mod(short)` - Added `short.RangeTo(short)`, `short.RangeTo(int)`, and `short.RangeTo(long)` - Added `short.UnpackBits()` - Added `string.IsPalindrome()` - Added `Stream.GetHash()` - Added `Stream.TryWriteHash(Span, out int)` - Added `Stream.ReadInt16([Endian])` - Added `Stream.ReadInt32([Endian])` - Added `Stream.ReadInt64([Endian])` - Added `Stream.ReadUInt16([Endian])` - Added `Stream.ReadUInt32([Endian])` - Added `Stream.ReadUInt64([Endian])` - Added `Stream.Write(short, [Endian])` - Added `Stream.Write(int, [Endian])` - Added `Stream.Write(long, [Endian])` - Added `Stream.Write(ushort, [Endian])` - Added `Stream.Write(uint, [Endian])` - Added `Stream.Write(ulong, [Endian])` - Added `TimeSpan.Ago()` - Added `TimeSpan.FromNow()` - Added `TimeSpanParser.TryParse` which supersedes `TimeSpanParser.Parse` - Added `Sqrt()` and `ComplexSqrt()` for all built-in decimal types - Added `All()` and `Any()` for `Span` and `ReadOnlySpan`, mimicking the corresponding methods in `System.Linq` - Added `Sign()` for built-in numeric types. For unsigned types, this never returns -1 - Added `Type.Implements()` and `Type.Implements(Type)` (#25) - Added `Type.Inherits()` and `Type.Inherits(Type)` (#25) - Added `DigitalRoot` function for built-in integer types - Added `Factorial` function for built-in integer types - Added `HostToNetworkOrder` and `NetworkToHostOrder` for `short`, `int`, and `long` - Added `IsLeapYear` function for `DateTime` and `DateTimeOffset`, as well as built-in numeric types - Added `MultiplicativePersistence` function for built-in integer types - Added `RotateLeft` and `RotateRight` for built-in integer types - Added trigonometric functions for built-in numeric types, including `Acos()`, `Asin()`, `Atan()`, `Atan2()`, `Cos()`, `Sin()`, `Tan()` (#49) - Added time-related extension methods for built-in numeric types, including `Milliseconds()`, `Seconds()`, `Minutes()`, `Hours()`, `Days()`, and `Weeks()`. `Ticks()` is also available, but only for integers; not floating point - Added `StringBuilderReader` (inheriting `TextReader`) which allows reading from a `StringBuilder` without consuming the underlying string - Added extension methods for `System.Decimal` ### Changed - Updated to .NET 6 (#45) - Methods defined to accept `byte[]` have been changed accept `IReadOnlyList` - Extension methods are now defined in appropriate child namespaces to reduce the risk of name collisions (#7) - `char[].Random(int)`, `char[].Random(int, int)`, `IEnumerable.Random(int)`, and `IEnumerable.Random(int, int)` have been redefined as `Random.NextString(IReadOnlyList, int)` - `IComparable.Between(T, T)` has been redefined as `IComparable.Between(T2, T3, [InclusiveOptions])` to allow comparison of disparate yet comparable types, and also offers inclusivity options - `DateTime` extensions now wrap `DateTimeOffset` extensions - `DateTime.ToUnixTimestamp([bool])` has been redefined as `DateTime.ToUnixTimeMilliseconds()` and `DateTime.ToUnixTimeSeconds()` - `Dictionary.ToGetParameters()`, `IDictionary.ToGetParameters()`, and `IReadOnlyDictionary.ToGetParameters()`, has been redefined as `IEnumerable>.ToGetParameters()` - `Dictionary.ToConnectionString()`, `IDictionary.ToConnectionString()`, and `IReadOnlyDictionary.ToConnectionString()`, has been redefined as `IEnumerable>.ToConnectionString()` - `IList.OneOf([Random])` and `IEnumerable.OneOf([Random])` have been redefined as `Random.NextFrom(IEnumerable)` to fall in line with the naming convention of `System.Random` (#21) - `IList.Shuffle([Random])` now uses a Fisher-Yates shuffle implementation - `IList.Shuffle([Random])` has been repurposed to shuffle the list in place, rather than returning a new enumerable - `IEnumerable.Shuffle([Random])` has been renamed to `IEnumerable.Shuffled([Random])` to avoid confusion with `IList.Shuffle([Random])` - `Random.CoinToss()` has been redefined as `Random.NextBoolean()` to fall in line with the naming convention of `System.Random` - `Random.OneOf(T[])` and `Random.OneOf(IList)` have been redefined as `Random.NextFrom(IEnumerable)` to fall in line with the naming convention of `System.Random` - `Enum.Next([bool])` and `Enum.Previous([bool])` have been redefined as `Enum.Next()`, `Enum.Previous()`, `Enum.NextUnchecked()`, `Enum.PreviousUnchecked()`. The `Unchecked` variants of these methods do not perform index validation, and will throw `IndexOutOfRangeException` when attempting to access an invalid index. The checked variants will perform a modulo to wrap the index - Seperated `string.WithAlternative(string, [bool])` to `string.WithEmptyAlternative(string)` and `string.WithWhiteSpaceAlternative(string)` - `string.AsNullIfEmpty()` and `string.AsNullIfWhiteSpace()` now accept a nullable `string` - `IEnumerable.GetString([Encoding])` has been renamed to `IReadOnlyList.ToString` and its `Encoding` parameter has been made non-optional - Fixed a bug where `IEnumerable>.ToConnectionString()` would not sanitize types with custom `ToString()` implementation (#20) Renamed `string.Random(int[, Random])` to `string.Randomize(int[, Random])` - Redefined `char[].Random(int)`, `char[].Random(int, Random)`, `IEnumerable.Random(int)`, and `IEnumerable.Random(int, Random)`, as `Random.NextString(IReadOnlyList, int)` - Improved performance for: - `string.IsLower()` - `string.IsUpper()` - `string.Reverse()` - `TimeSpanParser` ### Removed - Indefinitely suspended Unity support, until such a time that Unity can be updated to a newer version of .NET. See: https://forum.unity.com/threads/unity-future-net-development-status.1092205/ - Removed `bool.And(bool)` - Removed `bool.NAnd(bool)` - Removed `bool.NOr(bool)` - Removed `bool.Not(bool)` - Removed `bool.Or(bool)` - Removed `bool.ToByte()` - Removed `bool.ToInt16()` - Removed `bool.ToInt64()` - Removed `bool.XNOr()` - Removed `bool.XOr()` - Removed `IConvertible.To([IFormatProvider])` (#13) - Removed `IConvertible.ToOrDefault([IFormatProvider])` (#13) - Removed `IConvertible.ToOrDefault(out T, [IFormatProvider])` (#13) - Removed `IConvertible.ToOrNull([IFormatProvider])` (#13) - Removed `IConvertible.ToOrNull(out T, [IFormatProvider])` (#13) - Removed `IConvertible.ToOrOther(T, [IFormatProvider])` (#13) - Removed `IConvertible.ToOrOther(out T, T, [IFormatProvider])` (#13) - Removed `IEnumerable.Split(int)` - this functionality is now provided by .NET in the form of the `Chunk` method. See: https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk?view=net-6.0 - Removed `MemberInfo.GetDefaultValue()` (use `SelectFromCustomAttribute()` instead) - Removed `MemberInfo.GetDescription()` (use `SelectFromCustomAttribute()` instead) - Removed `int.ToBoolean()` - Removed `long.ToBoolean()` - Removed `short.ToBoolean()` - Removed `uint.ToBoolean()` - Removed `ushort.ToBoolean()` - Removed `ulong.ToBoolean()` - Removed `WaitHandle.WaitOneAsync()`. For suspensions of execution during asynchronous operations, favour `TaskCompletionSource` or `TaskCompletionSource`. See: https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskcompletionsource?view=net-6.0 and https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskcompletionsource-1?view=net-6.0 ## [2.6.0] - 2020-10-20 ### Added - Add `string.AsNullIfEmpty()` - Returns the current string, or `null` if the current string is null or empty. - Add `string.AsNullIfWhiteSpace()` - Returns the current string, or `null` if the current string is null, empty, or consists of only whitespace. - Add `string.Reverse()` - Reverses the current string - Add `string.WithAlternative()` - Returns the current string, or an alternative value if the current string is null or empty, or optionally if the current string consists of only whitespace. ### Changed - n/a ### Removed - n/a ## [2.5.0] - 2020-07-15 ### Added - `WaitHandle.WaitOneAsync()` - Wraps `WaitHandle.WaitOne` as a `Task` - Add support for Unity 2019.4.3f1 - Add `GameObject.LookAt(GameObject)` - Rotates the Transform on the current GameObject so that it faces the Transform on another GameObject - Add `GameObject.LookAt(Transform)` - Rotates the Transform on the current GameObject so that it faces another transform - Add `Transform.LookAt(GameObject)` - Rotates the current Transform so that it faces the Transform on another GameObject - Add `Vector3.Round([float])` - Returns a rounded Vector3 by calling `float.Round()` on each component - Add `Vector3.WithX(float)` - Returns a Vector3 with a new X component value - Add `Vector3.WithY(float)` - Returns a Vector3 with a new Y component value - Add `Vector3.WithZ(float)` - Returns a Vector3 with a new Z component value - Add `Vector3.WithXY(float, float)` - Returns a Vector3 with new X and Y component values - Add `Vector3.WithXZ(float, float)` - Returns a Vector3 with new X and Z component values - Add `Vector3.WithYZ(float, float)` - Returns a Vector3 with new Y and Z component values - Add `BetterBehavior` (experimental wrapper over `MonoBehaviour`) ### Changed - n/a ### Removed - n/a ## [2.2.0] - 2020-04-21 ### Added - Add `string.ChangeEncoding(Encoding, Encoding)` - Converts this string from one encoding to another - Add `string.IsLower()` - Determines if all alpha characters in this string are considered lowercase - Add `string.IsUpper()` - Determines if all alpha characters in this string are considered uppercase - Various extension methods with regards to reflection: - `GetDefaultValue` and `GetDefaultValue` - gets the value stored in the member's `DefaultValue` attribute - `GetDescription`- gets the value stored in the member's `Description` attribute - `SelectFromCustomAttribute` - Internally calls `GetCustomAttribute` and passes it to a `Func` so that specific members may be selected ### Changed - n/a ### Removed - n/a ## [2.1.0] - 2020-04-18 ### Added - Add `bool bool.And(bool)` - Performs logical AND - Add `bool bool.Or(bool)` - Performs logical OR - Add `bool bool.Not(bool)` - Performs logical NOT - Add `bool bool.XOr(bool)` - Performs Logical XOR - Add `bool bool.NAnd(bool)` - Performs logical NAND - Add `bool bool.NOr(bool)` - Performs logical NOR - Add `bool bool.XNOr(bool)` - Performs logical XNOR - Add `byte bool.ToByte()` - 1 if `true`, 0 otherwise - Add `short bool.ToInt16()` - 1 if `true`, 0 otherwise - Add `long bool.ToInt64()` - 1 if `true`, 0 otherwise ### Changed - n/a ### Removed - n/a ## [2.0.0] - 2020-04-18 ### Added - Add `IEnumerable.Split(int)` - Performs the same operation as the previously defined `IEnumerable.Chunkify(int)`, except now accepts any type `T` ### Changed - Fix `DateTime.Last(DayOfWeek)` implementation - Now returns the correct date/time for a given day of the week ### Removed - Remove `IEnumerable.Chunkify(int)` - Replaced by a method of the same behaviour `IEnumerable.Split(int)` ## Earlier versions ### ***Not documented*** [3.0.0]: https://github.com/oliverbooth/X10D/releases/tag/v3.0.0 [2.6.0]: https://github.com/oliverbooth/X10D/releases/tag/2.6.0 [2.5.0]: https://github.com/oliverbooth/X10D/releases/tag/2.5.0 [2.2.0]: https://github.com/oliverbooth/X10D/releases/tag/2.2.0 [2.1.0]: https://github.com/oliverbooth/X10D/releases/tag/2.1.0 [2.0.0]: https://github.com/oliverbooth/X10D/releases/tag/2.0.0