mirror of https://github.com/dahall/Vanara.git
Added TypeConverter, MinValue/MaxValue fields, comparison operators, and fixed inconsistent handling of Int32 conversions.
parent
246b53dd69
commit
fb62105f42
|
@ -1,13 +1,18 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Serialization;
|
|
||||||
|
|
||||||
namespace Vanara.PInvoke
|
namespace Vanara.PInvoke
|
||||||
{
|
{
|
||||||
/// <summary>Managed instance of the SIZE_T type.</summary>
|
/// <summary>Managed instance of the SIZE_T type.</summary>
|
||||||
[StructLayout(LayoutKind.Sequential), Serializable]
|
[StructLayout(LayoutKind.Sequential), Serializable]
|
||||||
|
[TypeConverter(typeof(SizeTTypeConverter))]
|
||||||
public struct SizeT : IEquatable<SizeT>, IComparable<SizeT>, IConvertible, IComparable
|
public struct SizeT : IEquatable<SizeT>, IComparable<SizeT>, IConvertible, IComparable
|
||||||
{
|
{
|
||||||
|
/// <summary>Represents the smallest possible value of <see cref="SizeT"/>. This field is constant.</summary>
|
||||||
|
public static readonly SizeT MinValue = 0;
|
||||||
|
|
||||||
private UIntPtr val;
|
private UIntPtr val;
|
||||||
|
|
||||||
/// <summary>Initializes a new instance of the <see cref="SizeT"/> struct.</summary>
|
/// <summary>Initializes a new instance of the <see cref="SizeT"/> struct.</summary>
|
||||||
|
@ -18,6 +23,11 @@ namespace Vanara.PInvoke
|
||||||
/// <param name="value">The value.</param>
|
/// <param name="value">The value.</param>
|
||||||
public SizeT(ulong value) => val = new UIntPtr(value);
|
public SizeT(ulong value) => val = new UIntPtr(value);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the largest possible value of <see cref="SizeT"/>. This property is determined by the maximum bit-size of a pointer.
|
||||||
|
/// </summary>
|
||||||
|
public static SizeT MaxValue => UIntPtr.Size == 8 ? ulong.MaxValue : uint.MaxValue;
|
||||||
|
|
||||||
/// <summary>Gets the value.</summary>
|
/// <summary>Gets the value.</summary>
|
||||||
/// <value>The value.</value>
|
/// <value>The value.</value>
|
||||||
public ulong Value { get => val.ToUInt64(); private set => val = new UIntPtr(value); }
|
public ulong Value { get => val.ToUInt64(); private set => val = new UIntPtr(value); }
|
||||||
|
@ -25,7 +35,7 @@ namespace Vanara.PInvoke
|
||||||
/// <summary>Performs an implicit conversion from <see cref="System.Int32"/> to <see cref="SizeT"/>.</summary>
|
/// <summary>Performs an implicit conversion from <see cref="System.Int32"/> to <see cref="SizeT"/>.</summary>
|
||||||
/// <param name="value">The value.</param>
|
/// <param name="value">The value.</param>
|
||||||
/// <returns>The result of the conversion.</returns>
|
/// <returns>The result of the conversion.</returns>
|
||||||
public static implicit operator SizeT(int value) => new SizeT((uint)value);
|
public static implicit operator SizeT(int value) => value >= 0 ? new SizeT((uint)value) : throw new ArgumentOutOfRangeException();
|
||||||
|
|
||||||
/// <summary>Performs an implicit conversion from <see cref="System.UInt32"/> to <see cref="SizeT"/>.</summary>
|
/// <summary>Performs an implicit conversion from <see cref="System.UInt32"/> to <see cref="SizeT"/>.</summary>
|
||||||
/// <param name="value">The value.</param>
|
/// <param name="value">The value.</param>
|
||||||
|
@ -35,7 +45,7 @@ namespace Vanara.PInvoke
|
||||||
/// <summary>Performs an implicit conversion from <see cref="System.Int64"/> to <see cref="SizeT"/>.</summary>
|
/// <summary>Performs an implicit conversion from <see cref="System.Int64"/> to <see cref="SizeT"/>.</summary>
|
||||||
/// <param name="value">The value.</param>
|
/// <param name="value">The value.</param>
|
||||||
/// <returns>The result of the conversion.</returns>
|
/// <returns>The result of the conversion.</returns>
|
||||||
public static implicit operator SizeT(long value) => new SizeT((ulong)value);
|
public static implicit operator SizeT(long value) => value >= 0 ? new SizeT((ulong)value) : throw new ArgumentOutOfRangeException();
|
||||||
|
|
||||||
/// <summary>Performs an implicit conversion from <see cref="System.UInt64"/> to <see cref="SizeT"/>.</summary>
|
/// <summary>Performs an implicit conversion from <see cref="System.UInt64"/> to <see cref="SizeT"/>.</summary>
|
||||||
/// <param name="value">The value.</param>
|
/// <param name="value">The value.</param>
|
||||||
|
@ -45,12 +55,12 @@ namespace Vanara.PInvoke
|
||||||
/// <summary>Performs an implicit conversion from <see cref="SizeT"/> to <see cref="System.Int32"/>.</summary>
|
/// <summary>Performs an implicit conversion from <see cref="SizeT"/> to <see cref="System.Int32"/>.</summary>
|
||||||
/// <param name="value">The value.</param>
|
/// <param name="value">The value.</param>
|
||||||
/// <returns>The result of the conversion.</returns>
|
/// <returns>The result of the conversion.</returns>
|
||||||
public static implicit operator int(SizeT value) => (int)value.Value;
|
public static implicit operator int(SizeT value) => (int)value.val.ToUInt32();
|
||||||
|
|
||||||
/// <summary>Performs an implicit conversion from <see cref="SizeT"/> to <see cref="System.UInt32"/>.</summary>
|
/// <summary>Performs an implicit conversion from <see cref="SizeT"/> to <see cref="System.UInt32"/>.</summary>
|
||||||
/// <param name="value">The value.</param>
|
/// <param name="value">The value.</param>
|
||||||
/// <returns>The result of the conversion.</returns>
|
/// <returns>The result of the conversion.</returns>
|
||||||
public static implicit operator uint(SizeT value) => (uint)value.Value;
|
public static implicit operator uint(SizeT value) => value.val.ToUInt32();
|
||||||
|
|
||||||
/// <summary>Performs an implicit conversion from <see cref="SizeT"/> to <see cref="System.Int64"/>.</summary>
|
/// <summary>Performs an implicit conversion from <see cref="SizeT"/> to <see cref="System.Int64"/>.</summary>
|
||||||
/// <param name="value">The value.</param>
|
/// <param name="value">The value.</param>
|
||||||
|
@ -62,9 +72,62 @@ namespace Vanara.PInvoke
|
||||||
/// <returns>The result of the conversion.</returns>
|
/// <returns>The result of the conversion.</returns>
|
||||||
public static implicit operator ulong(SizeT value) => value.Value;
|
public static implicit operator ulong(SizeT value) => value.Value;
|
||||||
|
|
||||||
|
/// <summary>Indicates whether two <see cref="SizeT"/> instances are not equal.</summary>
|
||||||
|
/// <param name="s1">The first integral size to compare.</param>
|
||||||
|
/// <param name="s2">The second integral size to compare.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true"/> if the value of <paramref name="s1"/> is not equal to the value of <paramref name="s2"/>; otherwise, <see langword="false"/>.
|
||||||
|
/// </returns>
|
||||||
|
public static bool operator !=(SizeT s1, SizeT s2) => !s1.Equals(s2);
|
||||||
|
|
||||||
|
/// <summary>Indicates whether a specified <see cref="SizeT"/> is less than another specified <see cref="SizeT"/>.</summary>
|
||||||
|
/// <param name="s1">The first integral size to compare.</param>
|
||||||
|
/// <param name="s2">The second integral size to compare.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true"/> if the value of <paramref name="s1"/> is less than the value of <paramref name="s2"/>; otherwise, <see langword="false"/>.
|
||||||
|
/// </returns>
|
||||||
|
public static bool operator <(SizeT s1, SizeT s2) => (s1.CompareTo(s2) < 0) ? true : false;
|
||||||
|
|
||||||
|
/// <summary>Indicates whether a specified <see cref="SizeT"/> is less than or equal to another specified <see cref="SizeT"/>.</summary>
|
||||||
|
/// <param name="s1">The first integral size to compare.</param>
|
||||||
|
/// <param name="s2">The second integral size to compare.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true"/> if the value of <paramref name="s1"/> is less than or equal to the value of <paramref name="s2"/>;
|
||||||
|
/// otherwise, <see langword="false"/>.
|
||||||
|
/// </returns>
|
||||||
|
public static bool operator <=(SizeT s1, SizeT s2) => (s1.CompareTo(s2) <= 0) ? true : false;
|
||||||
|
|
||||||
|
/// <summary>Indicates whether two <see cref="SizeT"/> instances are equal.</summary>
|
||||||
|
/// <param name="s1">The first integral size to compare.</param>
|
||||||
|
/// <param name="s2">The second integral size to compare.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true"/> if the value of <paramref name="s1"/> is equal to the value of <paramref name="s2"/>; otherwise, <see langword="false"/>.
|
||||||
|
/// </returns>
|
||||||
|
public static bool operator ==(SizeT s1, SizeT s2) => s1.Equals(s2);
|
||||||
|
|
||||||
|
/// <summary>Indicates whether a specified <see cref="SizeT"/> is greater than another specified <see cref="SizeT"/>.</summary>
|
||||||
|
/// <param name="s1">The first integral size to compare.</param>
|
||||||
|
/// <param name="s2">The second integral size to compare.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true"/> if the value of <paramref name="s1"/> is greater than the value of <paramref name="s2"/>; otherwise, <see langword="false"/>.
|
||||||
|
/// </returns>
|
||||||
|
public static bool operator >(SizeT s1, SizeT s2) => (s1.CompareTo(s2) > 0) ? true : false;
|
||||||
|
|
||||||
|
/// <summary>Indicates whether a specified <see cref="SizeT"/> is greater than or equal to another specified <see cref="SizeT"/>.</summary>
|
||||||
|
/// <param name="s1">The first integral size to compare.</param>
|
||||||
|
/// <param name="s2">The second integral size to compare.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true"/> if the value of <paramref name="s1"/> is greater than or equal to the value of <paramref name="s2"/>;
|
||||||
|
/// otherwise, <see langword="false"/>.
|
||||||
|
/// </returns>
|
||||||
|
public static bool operator >=(SizeT s1, SizeT s2) => (s1.CompareTo(s2) >= 0) ? true : false;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public int CompareTo(SizeT other) => Value.CompareTo(other.Value);
|
public int CompareTo(SizeT other) => Value.CompareTo(other.Value);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override bool Equals(object obj) => obj is SizeT s ? Equals(s) : Value.Equals(obj);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool Equals(SizeT other) => Value.Equals(other.Value);
|
public bool Equals(SizeT other) => Value.Equals(other.Value);
|
||||||
|
|
||||||
|
@ -86,46 +149,58 @@ namespace Vanara.PInvoke
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
bool IConvertible.ToBoolean(IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
|
bool IConvertible.ToBoolean(IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
char IConvertible.ToChar(IFormatProvider provider) => ((IConvertible)Value).ToChar(provider);
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)Value).ToSByte(provider);
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)Value).ToByte(provider);
|
byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)Value).ToByte(provider);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)Value).ToInt16(provider);
|
char IConvertible.ToChar(IFormatProvider provider) => ((IConvertible)Value).ToChar(provider);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)Value).ToUInt16(provider);
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)Value).ToInt32(provider);
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)Value).ToUInt32(provider);
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)Value).ToInt64(provider);
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)Value).ToUInt64(provider);
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)Value).ToSingle(provider);
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)Value).ToDouble(provider);
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)Value).ToDecimal(provider);
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
DateTime IConvertible.ToDateTime(IFormatProvider provider) => ((IConvertible)Value).ToDateTime(provider);
|
DateTime IConvertible.ToDateTime(IFormatProvider provider) => ((IConvertible)Value).ToDateTime(provider);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)Value).ToDecimal(provider);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)Value).ToDouble(provider);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)Value).ToInt16(provider);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)Value).ToInt32(provider);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)Value).ToInt64(provider);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)Value).ToSByte(provider);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)Value).ToSingle(provider);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
object IConvertible.ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
|
object IConvertible.ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)Value).ToUInt16(provider);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)Value).ToUInt32(provider);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)Value).ToUInt64(provider);
|
||||||
|
|
||||||
|
internal class SizeTTypeConverter : UInt64Converter
|
||||||
|
{
|
||||||
|
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
|
||||||
|
{
|
||||||
|
if (!(value is SizeT sz)) throw new ArgumentException();
|
||||||
|
return base.ConvertTo(context, culture, sz.Value, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) =>
|
||||||
|
new SizeT((ulong)base.ConvertFrom(context, culture, value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue