暫無描述

type_sets.go 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. package main
  2. // TYPE OMIT
  3. type Integer interface {
  4. int
  5. }
  6. // TYPE OMIT
  7. // INVALID OMIT
  8. // EmbeddedParameter is INVALID.
  9. type EmbeddedParameter[T any] interface {
  10. T // INVALID: may not list a plain type parameter
  11. }
  12. // INVALID OMIT
  13. // APPRO OMIT
  14. type MyInt int
  15. type AnyInteger interface {
  16. ~int
  17. }
  18. // APPRO OMIT
  19. // ALL INVALID OMIT
  20. type MyString string
  21. // ApproximateMyString is INVALID.
  22. type ApproximateMyString interface {
  23. ~MyString // INVALID: underlying type of MyString is not MyString
  24. }
  25. // ApproximateParameter is INVALID.
  26. type ApproximateParameter[T any] interface {
  27. ~T // INVALID: T is a type parameter
  28. }
  29. type MyInterface {}
  30. // ApproximateInterface is INVALID.
  31. type ApproximateInterface interface {
  32. ~MyInterface // INVALID: T is an interface type
  33. }
  34. // ALL INVALID OMIT
  35. // ONION EXAMPLE OMIT
  36. // PredeclaredSignedInteger is a constraint that matches the
  37. // five predeclared signed integer types.
  38. type PredeclaredSignedInteger interface {
  39. int | int8 | int16 | int32 | int64
  40. }
  41. // SignedInteger is a constraint that matches any signed integer type.
  42. type SignedInteger interface {
  43. ~int | ~int8 | ~int16 | ~int32 | ~int64
  44. }
  45. // ONION EXAMPLE OMIT
  46. // StringableSignedInteger OMIT
  47. type StringableSignedInteger interface {
  48. ~int | ~int8 | ~int16 | ~int32 | ~int64
  49. String() string
  50. }
  51. // StringableSignedInteger OMIT
  52. // COMPOSITE TYPE OMIT
  53. type byteseq interface{
  54. string | []byte
  55. }
  56. func Join[T byteseq](a []T, sep T) (ret T) {
  57. // some checks...
  58. n := len(sep) * (len(a) - 1)
  59. for _, v := range a {
  60. n += len(v)
  61. }
  62. b := make([]byte, n)
  63. bp := copy(b, a[0])
  64. for _, s := range a[1:] {
  65. bp += copy(b[bp:], sep)
  66. bp += copy(b[bp:], s)
  67. }
  68. return T(b)
  69. }
  70. // COMPOSITE TYPE OMIT
  71. // COMPOSITE STRUCT FIELD OMIT
  72. // structField is a type constraint whose type set consists of some
  73. // struct types that all have a field named x.
  74. type structField interface {
  75. struct { a int; x int } |
  76. struct { b int; x float64 } |
  77. struct { c int; x uint64 }
  78. }
  79. // This function is INVALID.
  80. func IncrementX[T structField](p *T) {
  81. v := p.x // INVALID: type of p.x is not the same for all types in set
  82. v++
  83. p.x = v
  84. }
  85. // COMPOSITE STRUCT FIELD OMIT
  86. // TYPE CONVERSION OMIT
  87. type integer interface {
  88. ~int | ~int8 | ~int16 | ~int32 | ~int64 |
  89. ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
  90. }
  91. func Convert[To, From integer](from From) To {
  92. to := To(from)
  93. if From(to) != from {
  94. panic("conversion out of range")
  95. }
  96. return to
  97. }
  98. // TYPE CONVERSION OMIT
  99. // UNTYPED CONSTANTS OMIT
  100. type integer interface {
  101. ~int | ~int8 | ~int16 | ~int32 | ~int64 |
  102. ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
  103. }
  104. func Add10[T integer](s []T) {
  105. for i, v := range s {
  106. s[i] = v + 10 // OK: 10 can convert to any integer type
  107. }
  108. }
  109. // This function is INVALID.
  110. func Add1024[T integer](s []T) {
  111. for i, v := range s {
  112. s[i] = v + 1024 // INVALID: 1024 not permitted by int8/uint8
  113. }
  114. }
  115. // UNTYPED CONSTANTS OMIT
  116. // EMBED INTERSECTION OMIT
  117. // Addable is types that support the + operator.
  118. type Addable interface {
  119. ~int | ~int8 | ~int16 | ~int32 | ~int64 |
  120. ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
  121. ~float32 | ~float64 | ~complex64 | ~complex128 |
  122. ~string
  123. }
  124. // Byteseq is a byte sequence: either string or []byte.
  125. type Byteseq interface {
  126. ~string | ~[]byte
  127. }
  128. // AddableByteseq is a byte sequence that supports +.
  129. // This is every type that is both Addable and Byteseq.
  130. // In other words, just the type set ~string.
  131. type AddableByteseq interface {
  132. Addable
  133. Byteseq
  134. }
  135. // EMBED INTERSECTION OMIT
  136. // EMBED UNION OMIT
  137. // Signed is a constraint with a type set of all signed integer
  138. // types.
  139. type Signed interface {
  140. ~int | ~int8 | ~int16 | ~int32 | ~int64
  141. }
  142. // Unsigned is a constraint with a type set of all unsigned integer
  143. // types.
  144. type Unsigned interface {
  145. ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
  146. }
  147. // Integer is a constraint with a type set of all integer types.
  148. type Integer interface {
  149. Signed | Unsigned
  150. }
  151. // EMBED UNION OMIT
  152. // INTERFACE IN UNION OMIT
  153. type Stringish interface {
  154. string | fmt.Stringer
  155. }
  156. func ToString[T Stringish](v T) string {
  157. switch x := (interface{})(v).(type) {
  158. case string:
  159. return x
  160. case fmt.Stringer:
  161. return x.String()
  162. }
  163. panic("impossible")
  164. }
  165. // INTERFACE IN UNION OMIT
  166. // EMPTY TYPE SETS OMIT
  167. // Unsatisfiable is an unsatisfiable constraint with an empty type set.
  168. // No predeclared types have any methods.
  169. // If this used ~int | ~float32 the type set would not be empty.
  170. type Unsatisfiable interface {
  171. int | float32
  172. String() string
  173. }
  174. // EMPTY TYPE SETS OMIT