UIntPtr.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Globalization;
  5. using System.Runtime.CompilerServices;
  6. using System.Runtime.Serialization;
  7. using System.Runtime.Versioning;
  8. #pragma warning disable SA1121 // explicitly using type aliases instead of built-in types
  9. #if BIT64
  10. using nuint = System.UInt64;
  11. #else
  12. using nuint = System.UInt32;
  13. #endif
  14. namespace System
  15. {
  16. [Serializable]
  17. [CLSCompliant(false)]
  18. [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
  19. public readonly struct UIntPtr : IEquatable<UIntPtr>, ISerializable
  20. {
  21. private readonly unsafe void* _value; // Do not rename (binary serialization)
  22. [Intrinsic]
  23. public static readonly UIntPtr Zero;
  24. [Intrinsic]
  25. [NonVersionable]
  26. public unsafe UIntPtr(uint value)
  27. {
  28. _value = (void*)value;
  29. }
  30. [Intrinsic]
  31. [NonVersionable]
  32. public unsafe UIntPtr(ulong value)
  33. {
  34. #if BIT64
  35. _value = (void*)value;
  36. #else
  37. _value = (void*)checked((uint)value);
  38. #endif
  39. }
  40. [Intrinsic]
  41. [NonVersionable]
  42. public unsafe UIntPtr(void* value)
  43. {
  44. _value = value;
  45. }
  46. private unsafe UIntPtr(SerializationInfo info, StreamingContext context)
  47. {
  48. ulong l = info.GetUInt64("value");
  49. if (Size == 4 && l > uint.MaxValue)
  50. throw new ArgumentException(SR.Serialization_InvalidPtrValue);
  51. _value = (void*)l;
  52. }
  53. void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
  54. {
  55. if (info == null)
  56. throw new ArgumentNullException(nameof(info));
  57. info.AddValue("value", ToUInt64());
  58. }
  59. public override unsafe bool Equals(object? obj)
  60. {
  61. if (obj is UIntPtr)
  62. {
  63. return _value == ((UIntPtr)obj)._value;
  64. }
  65. return false;
  66. }
  67. unsafe bool IEquatable<UIntPtr>.Equals(UIntPtr other) =>
  68. _value == other._value;
  69. public override unsafe int GetHashCode()
  70. {
  71. #if BIT64
  72. ulong l = (ulong)_value;
  73. return unchecked((int)l) ^ (int)(l >> 32);
  74. #else
  75. return unchecked((int)_value);
  76. #endif
  77. }
  78. [Intrinsic]
  79. [NonVersionable]
  80. public unsafe uint ToUInt32()
  81. {
  82. #if BIT64
  83. return checked((uint)_value);
  84. #else
  85. return (uint)_value;
  86. #endif
  87. }
  88. [Intrinsic]
  89. [NonVersionable]
  90. public unsafe ulong ToUInt64() => (ulong)_value;
  91. [Intrinsic]
  92. [NonVersionable]
  93. public static explicit operator UIntPtr(uint value) =>
  94. new UIntPtr(value);
  95. [Intrinsic]
  96. [NonVersionable]
  97. public static explicit operator UIntPtr(ulong value) =>
  98. new UIntPtr(value);
  99. [Intrinsic]
  100. [NonVersionable]
  101. public static unsafe explicit operator UIntPtr(void* value) =>
  102. new UIntPtr(value);
  103. [Intrinsic]
  104. [NonVersionable]
  105. public static unsafe explicit operator void*(UIntPtr value) =>
  106. value._value;
  107. [Intrinsic]
  108. [NonVersionable]
  109. public static unsafe explicit operator uint(UIntPtr value) =>
  110. #if BIT64
  111. checked((uint)value._value);
  112. #else
  113. (uint)value._value;
  114. #endif
  115. [Intrinsic]
  116. [NonVersionable]
  117. public static unsafe explicit operator ulong(UIntPtr value) =>
  118. (ulong)value._value;
  119. [Intrinsic]
  120. [NonVersionable]
  121. public static unsafe bool operator ==(UIntPtr value1, UIntPtr value2) =>
  122. value1._value == value2._value;
  123. [Intrinsic]
  124. [NonVersionable]
  125. public static unsafe bool operator !=(UIntPtr value1, UIntPtr value2) =>
  126. value1._value != value2._value;
  127. [NonVersionable]
  128. public static UIntPtr Add(UIntPtr pointer, int offset) =>
  129. pointer + offset;
  130. [Intrinsic]
  131. [NonVersionable]
  132. public static unsafe UIntPtr operator +(UIntPtr pointer, int offset) =>
  133. new UIntPtr((nuint)pointer._value + (nuint)offset);
  134. [NonVersionable]
  135. public static UIntPtr Subtract(UIntPtr pointer, int offset) =>
  136. pointer - offset;
  137. [Intrinsic]
  138. [NonVersionable]
  139. public static unsafe UIntPtr operator -(UIntPtr pointer, int offset) =>
  140. new UIntPtr((nuint)pointer._value - (nuint)offset);
  141. public static int Size
  142. {
  143. [Intrinsic]
  144. [NonVersionable]
  145. get => sizeof(nuint);
  146. }
  147. [Intrinsic]
  148. [NonVersionable]
  149. public unsafe void* ToPointer() => _value;
  150. public override unsafe string ToString() =>
  151. ((nuint)_value).ToString(CultureInfo.InvariantCulture);
  152. }
  153. }