reflect.odin 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578
  1. package reflect
  2. import "core:runtime"
  3. import "core:intrinsics"
  4. import "core:mem"
  5. _ :: mem
  6. _ :: intrinsics
  7. Type_Info :: runtime.Type_Info
  8. Type_Info_Named :: runtime.Type_Info_Named
  9. Type_Info_Integer :: runtime.Type_Info_Integer
  10. Type_Info_Rune :: runtime.Type_Info_Rune
  11. Type_Info_Float :: runtime.Type_Info_Float
  12. Type_Info_Complex :: runtime.Type_Info_Complex
  13. Type_Info_Quaternion :: runtime.Type_Info_Quaternion
  14. Type_Info_String :: runtime.Type_Info_String
  15. Type_Info_Boolean :: runtime.Type_Info_Boolean
  16. Type_Info_Any :: runtime.Type_Info_Any
  17. Type_Info_Type_Id :: runtime.Type_Info_Type_Id
  18. Type_Info_Pointer :: runtime.Type_Info_Pointer
  19. Type_Info_Multi_Pointer :: runtime.Type_Info_Multi_Pointer
  20. Type_Info_Procedure :: runtime.Type_Info_Procedure
  21. Type_Info_Array :: runtime.Type_Info_Array
  22. Type_Info_Enumerated_Array :: runtime.Type_Info_Enumerated_Array
  23. Type_Info_Dynamic_Array :: runtime.Type_Info_Dynamic_Array
  24. Type_Info_Slice :: runtime.Type_Info_Slice
  25. Type_Info_Parameters :: runtime.Type_Info_Parameters
  26. Type_Info_Tuple :: runtime.Type_Info_Parameters
  27. Type_Info_Struct :: runtime.Type_Info_Struct
  28. Type_Info_Union :: runtime.Type_Info_Union
  29. Type_Info_Enum :: runtime.Type_Info_Enum
  30. Type_Info_Map :: runtime.Type_Info_Map
  31. Type_Info_Bit_Set :: runtime.Type_Info_Bit_Set
  32. Type_Info_Simd_Vector :: runtime.Type_Info_Simd_Vector
  33. Type_Info_Relative_Pointer :: runtime.Type_Info_Relative_Pointer
  34. Type_Info_Relative_Slice :: runtime.Type_Info_Relative_Slice
  35. Type_Info_Matrix :: runtime.Type_Info_Matrix
  36. Type_Info_Soa_Pointer :: runtime.Type_Info_Soa_Pointer
  37. Type_Info_Enum_Value :: runtime.Type_Info_Enum_Value
  38. Type_Kind :: enum {
  39. Invalid,
  40. Named,
  41. Integer,
  42. Rune,
  43. Float,
  44. Complex,
  45. Quaternion,
  46. String,
  47. Boolean,
  48. Any,
  49. Type_Id,
  50. Pointer,
  51. Multi_Pointer,
  52. Procedure,
  53. Array,
  54. Enumerated_Array,
  55. Dynamic_Array,
  56. Slice,
  57. Tuple,
  58. Struct,
  59. Union,
  60. Enum,
  61. Map,
  62. Bit_Set,
  63. Simd_Vector,
  64. Relative_Pointer,
  65. Relative_Slice,
  66. Matrix,
  67. Soa_Pointer,
  68. }
  69. @(require_results)
  70. type_kind :: proc(T: typeid) -> Type_Kind {
  71. ti := type_info_of(T)
  72. if ti != nil {
  73. switch _ in ti.variant {
  74. case Type_Info_Named: return .Named
  75. case Type_Info_Integer: return .Integer
  76. case Type_Info_Rune: return .Rune
  77. case Type_Info_Float: return .Float
  78. case Type_Info_Complex: return .Complex
  79. case Type_Info_Quaternion: return .Quaternion
  80. case Type_Info_String: return .String
  81. case Type_Info_Boolean: return .Boolean
  82. case Type_Info_Any: return .Any
  83. case Type_Info_Type_Id: return .Type_Id
  84. case Type_Info_Pointer: return .Pointer
  85. case Type_Info_Multi_Pointer: return .Multi_Pointer
  86. case Type_Info_Procedure: return .Procedure
  87. case Type_Info_Array: return .Array
  88. case Type_Info_Enumerated_Array: return .Enumerated_Array
  89. case Type_Info_Dynamic_Array: return .Dynamic_Array
  90. case Type_Info_Slice: return .Slice
  91. case Type_Info_Parameters: return .Tuple
  92. case Type_Info_Struct: return .Struct
  93. case Type_Info_Union: return .Union
  94. case Type_Info_Enum: return .Enum
  95. case Type_Info_Map: return .Map
  96. case Type_Info_Bit_Set: return .Bit_Set
  97. case Type_Info_Simd_Vector: return .Simd_Vector
  98. case Type_Info_Relative_Pointer: return .Relative_Pointer
  99. case Type_Info_Relative_Slice: return .Relative_Slice
  100. case Type_Info_Matrix: return .Matrix
  101. case Type_Info_Soa_Pointer: return .Soa_Pointer
  102. }
  103. }
  104. return .Invalid
  105. }
  106. // TODO(bill): Better name
  107. @(require_results)
  108. underlying_type_kind :: proc(T: typeid) -> Type_Kind {
  109. return type_kind(runtime.typeid_base(T))
  110. }
  111. // TODO(bill): Better name
  112. @(require_results)
  113. backing_type_kind :: proc(T: typeid) -> Type_Kind {
  114. return type_kind(runtime.typeid_core(T))
  115. }
  116. type_info_base :: runtime.type_info_base
  117. type_info_core :: runtime.type_info_core
  118. type_info_base_without_enum :: type_info_core
  119. when !ODIN_DISALLOW_RTTI {
  120. typeid_base :: runtime.typeid_base
  121. typeid_core :: runtime.typeid_core
  122. typeid_base_without_enum :: typeid_core
  123. }
  124. @(require_results)
  125. any_base :: proc(v: any) -> any {
  126. v := v
  127. if v != nil {
  128. v.id = typeid_base(v.id)
  129. }
  130. return v
  131. }
  132. @(require_results)
  133. any_core :: proc(v: any) -> any {
  134. v := v
  135. if v != nil {
  136. v.id = typeid_core(v.id)
  137. }
  138. return v
  139. }
  140. @(require_results)
  141. typeid_elem :: proc(id: typeid) -> typeid {
  142. ti := type_info_of(id)
  143. if ti == nil { return nil }
  144. bits := 8*ti.size
  145. #partial switch v in ti.variant {
  146. case Type_Info_Complex:
  147. switch bits {
  148. case 64: return f32
  149. case 128: return f64
  150. }
  151. case Type_Info_Quaternion:
  152. switch bits {
  153. case 128: return f32
  154. case 256: return f64
  155. }
  156. case Type_Info_Pointer: return v.elem.id
  157. case Type_Info_Multi_Pointer: return v.elem.id
  158. case Type_Info_Soa_Pointer: return v.elem.id
  159. case Type_Info_Array: return v.elem.id
  160. case Type_Info_Enumerated_Array: return v.elem.id
  161. case Type_Info_Slice: return v.elem.id
  162. case Type_Info_Dynamic_Array: return v.elem.id
  163. }
  164. return id
  165. }
  166. @(require_results)
  167. size_of_typeid :: proc(T: typeid) -> int {
  168. if ti := type_info_of(T); ti != nil {
  169. return ti.size
  170. }
  171. return 0
  172. }
  173. @(require_results)
  174. align_of_typeid :: proc(T: typeid) -> int {
  175. if ti := type_info_of(T); ti != nil {
  176. return ti.align
  177. }
  178. return 1
  179. }
  180. @(require_results)
  181. as_bytes :: proc(v: any) -> []byte {
  182. if v != nil {
  183. sz := size_of_typeid(v.id)
  184. return ([^]byte)(v.data)[:sz]
  185. }
  186. return nil
  187. }
  188. @(require_results)
  189. any_data :: #force_inline proc(v: any) -> (data: rawptr, id: typeid) {
  190. return v.data, v.id
  191. }
  192. @(require_results)
  193. is_nil :: proc(v: any) -> bool {
  194. if v == nil {
  195. return true
  196. }
  197. data := as_bytes(v)
  198. if data == nil {
  199. return true
  200. }
  201. for v in data {
  202. if v != 0 {
  203. return false
  204. }
  205. }
  206. return true
  207. }
  208. @(require_results)
  209. length :: proc(val: any) -> int {
  210. if val == nil { return 0 }
  211. #partial switch a in type_info_of(val.id).variant {
  212. case Type_Info_Named:
  213. return length({val.data, a.base.id})
  214. case Type_Info_Pointer:
  215. return length({val.data, a.elem.id})
  216. case Type_Info_Array:
  217. return a.count
  218. case Type_Info_Enumerated_Array:
  219. return a.count
  220. case Type_Info_Slice:
  221. return (^runtime.Raw_Slice)(val.data).len
  222. case Type_Info_Dynamic_Array:
  223. return (^runtime.Raw_Dynamic_Array)(val.data).len
  224. case Type_Info_Map:
  225. return runtime.map_len((^runtime.Raw_Map)(val.data)^)
  226. case Type_Info_String:
  227. if a.is_cstring {
  228. return len((^cstring)(val.data)^)
  229. } else {
  230. return (^runtime.Raw_String)(val.data).len
  231. }
  232. }
  233. return 0
  234. }
  235. @(require_results)
  236. capacity :: proc(val: any) -> int {
  237. if val == nil { return 0 }
  238. #partial switch a in type_info_of(val.id).variant {
  239. case Type_Info_Named:
  240. return capacity({val.data, a.base.id})
  241. case Type_Info_Pointer:
  242. return capacity({val.data, a.elem.id})
  243. case Type_Info_Array:
  244. return a.count
  245. case Type_Info_Enumerated_Array:
  246. return a.count
  247. case Type_Info_Dynamic_Array:
  248. return (^runtime.Raw_Dynamic_Array)(val.data).cap
  249. case Type_Info_Map:
  250. return runtime.map_cap((^runtime.Raw_Map)(val.data)^)
  251. }
  252. return 0
  253. }
  254. @(require_results)
  255. index :: proc(val: any, i: int, loc := #caller_location) -> any {
  256. if val == nil { return nil }
  257. #partial switch a in type_info_of(val.id).variant {
  258. case Type_Info_Named:
  259. return index({val.data, a.base.id}, i, loc)
  260. case Type_Info_Pointer:
  261. ptr := (^rawptr)(val.data)^
  262. if ptr == nil {
  263. return nil
  264. }
  265. return index({ptr, a.elem.id}, i, loc)
  266. case Type_Info_Multi_Pointer:
  267. ptr := (^rawptr)(val.data)^
  268. if ptr == nil {
  269. return nil
  270. }
  271. return index({ptr, a.elem.id}, i, loc)
  272. case Type_Info_Array:
  273. runtime.bounds_check_error_loc(loc, i, a.count)
  274. offset := uintptr(a.elem.size * i)
  275. data := rawptr(uintptr(val.data) + offset)
  276. return any{data, a.elem.id}
  277. case Type_Info_Enumerated_Array:
  278. runtime.bounds_check_error_loc(loc, i, a.count)
  279. offset := uintptr(a.elem.size * i)
  280. data := rawptr(uintptr(val.data) + offset)
  281. return any{data, a.elem.id}
  282. case Type_Info_Slice:
  283. raw := (^runtime.Raw_Slice)(val.data)
  284. runtime.bounds_check_error_loc(loc, i, raw.len)
  285. offset := uintptr(a.elem.size * i)
  286. data := rawptr(uintptr(raw.data) + offset)
  287. return any{data, a.elem.id}
  288. case Type_Info_Dynamic_Array:
  289. raw := (^runtime.Raw_Dynamic_Array)(val.data)
  290. runtime.bounds_check_error_loc(loc, i, raw.len)
  291. offset := uintptr(a.elem.size * i)
  292. data := rawptr(uintptr(raw.data) + offset)
  293. return any{data, a.elem.id}
  294. case Type_Info_String:
  295. if a.is_cstring { return nil }
  296. raw := (^runtime.Raw_String)(val.data)
  297. runtime.bounds_check_error_loc(loc, i, raw.len)
  298. offset := uintptr(size_of(u8) * i)
  299. data := rawptr(uintptr(raw.data) + offset)
  300. return any{data, typeid_of(u8)}
  301. }
  302. return nil
  303. }
  304. @(require_results)
  305. deref :: proc(val: any) -> any {
  306. if val != nil {
  307. ti := type_info_base(type_info_of(val.id))
  308. if info, ok := ti.variant.(Type_Info_Pointer); ok {
  309. return any{
  310. (^rawptr)(val.data)^,
  311. info.elem.id,
  312. }
  313. }
  314. }
  315. return val
  316. }
  317. // Struct_Tag represents the type of the string of a struct field
  318. //
  319. // Through convention, tags are the concatenation of optionally space separationed key:"value" pairs.
  320. // Each key is a non-empty string which contains no control characters other than space, quotes, and colon.
  321. Struct_Tag :: distinct string
  322. Struct_Field :: struct {
  323. name: string,
  324. type: ^Type_Info,
  325. tag: Struct_Tag,
  326. offset: uintptr,
  327. is_using: bool,
  328. }
  329. @(require_results)
  330. struct_field_at :: proc(T: typeid, i: int) -> (field: Struct_Field) {
  331. ti := runtime.type_info_base(type_info_of(T))
  332. if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
  333. if 0 <= i && i < len(s.names) {
  334. field.name = s.names[i]
  335. field.type = s.types[i]
  336. field.tag = Struct_Tag(s.tags[i])
  337. field.offset = s.offsets[i]
  338. field.is_using = s.usings[i]
  339. }
  340. }
  341. return
  342. }
  343. @(require_results)
  344. struct_field_by_name :: proc(T: typeid, name: string) -> (field: Struct_Field) {
  345. ti := runtime.type_info_base(type_info_of(T))
  346. if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
  347. for fname, i in s.names {
  348. if fname == name {
  349. field.name = s.names[i]
  350. field.type = s.types[i]
  351. field.tag = Struct_Tag(s.tags[i])
  352. field.offset = s.offsets[i]
  353. field.is_using = s.usings[i]
  354. break
  355. }
  356. }
  357. }
  358. return
  359. }
  360. @(require_results)
  361. struct_field_value_by_name :: proc(a: any, field: string, allow_using := false) -> any {
  362. if a == nil { return nil }
  363. ti := runtime.type_info_base(type_info_of(a.id))
  364. if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
  365. for name, i in s.names {
  366. if name == field {
  367. return any{
  368. rawptr(uintptr(a.data) + s.offsets[i]),
  369. s.types[i].id,
  370. }
  371. }
  372. if allow_using && s.usings[i] {
  373. f := any{
  374. rawptr(uintptr(a.data) + s.offsets[i]),
  375. s.types[i].id,
  376. }
  377. if res := struct_field_value_by_name(f, field, allow_using); res != nil {
  378. return res
  379. }
  380. }
  381. }
  382. }
  383. return nil
  384. }
  385. @(require_results)
  386. struct_field_value :: proc(a: any, field: Struct_Field) -> any {
  387. if a == nil { return nil }
  388. return any {
  389. rawptr(uintptr(a.data) + field.offset),
  390. field.type.id,
  391. }
  392. }
  393. @(require_results)
  394. struct_field_names :: proc(T: typeid) -> []string {
  395. ti := runtime.type_info_base(type_info_of(T))
  396. if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
  397. return s.names
  398. }
  399. return nil
  400. }
  401. @(require_results)
  402. struct_field_types :: proc(T: typeid) -> []^Type_Info {
  403. ti := runtime.type_info_base(type_info_of(T))
  404. if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
  405. return s.types
  406. }
  407. return nil
  408. }
  409. @(require_results)
  410. struct_field_tags :: proc(T: typeid) -> []Struct_Tag {
  411. ti := runtime.type_info_base(type_info_of(T))
  412. if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
  413. return transmute([]Struct_Tag)s.tags
  414. }
  415. return nil
  416. }
  417. @(require_results)
  418. struct_field_offsets :: proc(T: typeid) -> []uintptr {
  419. ti := runtime.type_info_base(type_info_of(T))
  420. if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
  421. return s.offsets
  422. }
  423. return nil
  424. }
  425. @(require_results)
  426. struct_fields_zipped :: proc(T: typeid) -> (fields: #soa[]Struct_Field) {
  427. ti := runtime.type_info_base(type_info_of(T))
  428. if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
  429. return soa_zip(
  430. name = s.names,
  431. type = s.types,
  432. tag = transmute([]Struct_Tag)s.tags,
  433. offset = s.offsets,
  434. is_using = s.usings,
  435. )
  436. }
  437. return nil
  438. }
  439. @(require_results)
  440. struct_tag_get :: proc(tag: Struct_Tag, key: string) -> (value: Struct_Tag) {
  441. value, _ = struct_tag_lookup(tag, key)
  442. return
  443. }
  444. @(require_results)
  445. struct_tag_lookup :: proc(tag: Struct_Tag, key: string) -> (value: Struct_Tag, ok: bool) {
  446. for t := tag; t != ""; /**/ {
  447. i := 0
  448. for i < len(t) && t[i] == ' ' { // Skip whitespace
  449. i += 1
  450. }
  451. t = t[i:]
  452. if len(t) == 0 {
  453. break
  454. }
  455. i = 0
  456. loop: for i < len(t) {
  457. switch t[i] {
  458. case ':', '"':
  459. break loop
  460. case 0x00 ..< ' ', 0x7f ..= 0x9f: // break if control character is found
  461. break loop
  462. }
  463. i += 1
  464. }
  465. if i == 0 {
  466. break
  467. }
  468. if i+1 >= len(t) {
  469. break
  470. }
  471. if t[i] != ':' || t[i+1] != '"' {
  472. break
  473. }
  474. name := string(t[:i])
  475. t = t[i+1:]
  476. i = 1
  477. for i < len(t) && t[i] != '"' { // find closing quote
  478. if t[i] == '\\' {
  479. i += 1 // Skip escaped characters
  480. }
  481. i += 1
  482. }
  483. if i >= len(t) {
  484. break
  485. }
  486. val := string(t[:i+1])
  487. t = t[i+1:]
  488. if key == name {
  489. return Struct_Tag(val[1:i]), true
  490. }
  491. }
  492. return
  493. }
  494. @(require_results)
  495. enum_string :: proc(a: any) -> string {
  496. if a == nil { return "" }
  497. ti := runtime.type_info_base(type_info_of(a.id))
  498. if e, ok := ti.variant.(runtime.Type_Info_Enum); ok {
  499. v, _ := as_i64(a)
  500. for value, i in e.values {
  501. if value == Type_Info_Enum_Value(v) {
  502. return e.names[i]
  503. }
  504. }
  505. } else {
  506. panic("expected an enum to reflect.enum_string")
  507. }
  508. return ""
  509. }
  510. // Given a enum type and a value name, get the enum value.
  511. @(require_results)
  512. enum_from_name :: proc($Enum_Type: typeid, name: string) -> (value: Enum_Type, ok: bool) {
  513. ti := type_info_base(type_info_of(Enum_Type))
  514. if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
  515. for value_name, i in eti.names {
  516. if value_name != name {
  517. continue
  518. }
  519. v := eti.values[i]
  520. value = Enum_Type(v)
  521. ok = true
  522. return
  523. }
  524. }
  525. return
  526. }
  527. @(require_results)
  528. enum_from_name_any :: proc(Enum_Type: typeid, name: string) -> (value: Type_Info_Enum_Value, ok: bool) {
  529. ti := runtime.type_info_base(type_info_of(Enum_Type))
  530. if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
  531. for value_name, i in eti.names {
  532. if value_name != name {
  533. continue
  534. }
  535. value = eti.values[i]
  536. ok = true
  537. return
  538. }
  539. }
  540. return
  541. }
  542. @(require_results)
  543. enum_field_names :: proc(Enum_Type: typeid) -> []string {
  544. ti := runtime.type_info_base(type_info_of(Enum_Type))
  545. if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
  546. return eti.names
  547. }
  548. return nil
  549. }
  550. @(require_results)
  551. enum_field_values :: proc(Enum_Type: typeid) -> []Type_Info_Enum_Value {
  552. ti := runtime.type_info_base(type_info_of(Enum_Type))
  553. if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
  554. return eti.values
  555. }
  556. return nil
  557. }
  558. Enum_Field :: struct {
  559. name: string,
  560. value: Type_Info_Enum_Value,
  561. }
  562. @(require_results)
  563. enum_fields_zipped :: proc(Enum_Type: typeid) -> (fields: #soa[]Enum_Field) {
  564. ti := runtime.type_info_base(type_info_of(Enum_Type))
  565. if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
  566. return soa_zip(name=eti.names, value=eti.values)
  567. }
  568. return nil
  569. }
  570. @(require_results)
  571. union_variant_type_info :: proc(a: any) -> ^Type_Info {
  572. id := union_variant_typeid(a)
  573. return type_info_of(id)
  574. }
  575. @(require_results)
  576. type_info_union_is_pure_maybe :: proc(info: runtime.Type_Info_Union) -> bool {
  577. return len(info.variants) == 1 && is_pointer(info.variants[0])
  578. }
  579. @(require_results)
  580. union_variant_typeid :: proc(a: any) -> typeid {
  581. if a == nil { return nil }
  582. ti := runtime.type_info_base(type_info_of(a.id))
  583. if info, ok := ti.variant.(runtime.Type_Info_Union); ok {
  584. if type_info_union_is_pure_maybe(info) {
  585. if a.data != nil {
  586. return info.variants[0].id
  587. }
  588. return nil
  589. }
  590. tag_ptr := uintptr(a.data) + info.tag_offset
  591. tag_any := any{rawptr(tag_ptr), info.tag_type.id}
  592. tag: i64 = ---
  593. switch i in tag_any {
  594. case u8: tag = i64(i)
  595. case i8: tag = i64(i)
  596. case u16: tag = i64(i)
  597. case i16: tag = i64(i)
  598. case u32: tag = i64(i)
  599. case i32: tag = i64(i)
  600. case u64: tag = i64(i)
  601. case i64: tag = i
  602. case: unimplemented()
  603. }
  604. if info.no_nil {
  605. return info.variants[tag].id
  606. } else if tag != 0 {
  607. return info.variants[tag-1].id
  608. }
  609. return nil
  610. }
  611. panic("expected a union to reflect.union_variant_typeid")
  612. }
  613. @(require_results)
  614. get_union_variant_raw_tag :: proc(a: any) -> i64 {
  615. if a == nil { return -1 }
  616. ti := runtime.type_info_base(type_info_of(a.id))
  617. if info, ok := ti.variant.(runtime.Type_Info_Union); ok {
  618. if type_info_union_is_pure_maybe(info) {
  619. return 1 if a.data != nil else 0
  620. }
  621. tag_ptr := uintptr(a.data) + info.tag_offset
  622. tag_any := any{rawptr(tag_ptr), info.tag_type.id}
  623. tag: i64 = ---
  624. switch i in tag_any {
  625. case u8: tag = i64(i)
  626. case i8: tag = i64(i)
  627. case u16: tag = i64(i)
  628. case i16: tag = i64(i)
  629. case u32: tag = i64(i)
  630. case i32: tag = i64(i)
  631. case u64: tag = i64(i)
  632. case i64: tag = i
  633. case: unimplemented()
  634. }
  635. return tag
  636. }
  637. panic("expected a union to reflect.get_union_variant_raw_tag")
  638. }
  639. @(require_results)
  640. get_union_variant :: proc(a: any) -> any {
  641. if a == nil {
  642. return nil
  643. }
  644. id := union_variant_typeid(a)
  645. if id == nil {
  646. return nil
  647. }
  648. return any{a.data, id}
  649. }
  650. @(require_results)
  651. get_union_as_ptr_variants :: proc(val: ^$T) -> (res: intrinsics.type_convert_variants_to_pointers(T)) where intrinsics.type_is_union(T) {
  652. ptr := rawptr(val)
  653. tag := get_union_variant_raw_tag(val^)
  654. mem.copy(&res, &ptr, size_of(ptr))
  655. set_union_variant_raw_tag(res, tag)
  656. return
  657. }
  658. set_union_variant_raw_tag :: proc(a: any, tag: i64) {
  659. if a == nil { return }
  660. ti := runtime.type_info_base(type_info_of(a.id))
  661. if info, ok := ti.variant.(runtime.Type_Info_Union); ok {
  662. if type_info_union_is_pure_maybe(info) {
  663. // Cannot do anything
  664. return
  665. }
  666. tag_ptr := uintptr(a.data) + info.tag_offset
  667. tag_any := any{rawptr(tag_ptr), info.tag_type.id}
  668. switch i in &tag_any {
  669. case u8: i = u8(tag)
  670. case i8: i = i8(tag)
  671. case u16: i = u16(tag)
  672. case i16: i = i16(tag)
  673. case u32: i = u32(tag)
  674. case i32: i = i32(tag)
  675. case u64: i = u64(tag)
  676. case i64: i = tag
  677. case: unimplemented()
  678. }
  679. return
  680. }
  681. panic("expected a union to reflect.set_union_variant_raw_tag")
  682. }
  683. set_union_variant_typeid :: proc(a: any, id: typeid) {
  684. if a == nil { return }
  685. ti := runtime.type_info_base(type_info_of(a.id))
  686. if info, ok := ti.variant.(runtime.Type_Info_Union); ok {
  687. if type_info_union_is_pure_maybe(info) {
  688. // Cannot do anything
  689. return
  690. }
  691. if id == nil && !info.no_nil {
  692. set_union_variant_raw_tag(a, 0)
  693. return
  694. }
  695. for variant, i in info.variants {
  696. if variant.id == id {
  697. tag := i64(i)
  698. if !info.no_nil {
  699. tag += 1
  700. }
  701. set_union_variant_raw_tag(a, tag)
  702. return
  703. }
  704. }
  705. return
  706. }
  707. panic("expected a union to reflect.set_union_variant_typeid")
  708. }
  709. set_union_variant_type_info :: proc(a: any, tag_ti: ^Type_Info) {
  710. if a == nil { return }
  711. ti := runtime.type_info_base(type_info_of(a.id))
  712. if info, ok := ti.variant.(runtime.Type_Info_Union); ok {
  713. if type_info_union_is_pure_maybe(info) {
  714. // Cannot do anything
  715. return
  716. }
  717. if tag_ti == nil && !info.no_nil {
  718. set_union_variant_raw_tag(a, 0)
  719. return
  720. }
  721. for variant, i in info.variants {
  722. if variant == tag_ti {
  723. tag := i64(i)
  724. if !info.no_nil {
  725. tag += 1
  726. }
  727. set_union_variant_raw_tag(a, tag)
  728. return
  729. }
  730. }
  731. return
  732. }
  733. panic("expected a union to reflect.set_union_variant_type_info")
  734. }
  735. set_union_value :: proc(dst: any, value: any) -> bool {
  736. if dst == nil { return false }
  737. ti := runtime.type_info_base(type_info_of(dst.id))
  738. if info, ok := ti.variant.(runtime.Type_Info_Union); ok {
  739. if value.id == nil {
  740. intrinsics.mem_zero(dst.data, ti.size)
  741. return true
  742. }
  743. if ti.id == runtime.typeid_base(value.id) {
  744. intrinsics.mem_copy(dst.data, value.data, ti.size)
  745. return true
  746. }
  747. if type_info_union_is_pure_maybe(info) {
  748. if variant := info.variants[0]; variant.id == value.id {
  749. intrinsics.mem_copy(dst.data, value.data, variant.size)
  750. return true
  751. }
  752. return false
  753. }
  754. for variant, i in info.variants {
  755. if variant.id == value.id {
  756. tag := i64(i)
  757. if !info.no_nil {
  758. tag += 1
  759. }
  760. intrinsics.mem_copy(dst.data, value.data, variant.size)
  761. set_union_variant_raw_tag(dst, tag)
  762. return true
  763. }
  764. }
  765. return false
  766. }
  767. panic("expected a union to reflect.set_union_variant_typeid")
  768. }
  769. @(require_results)
  770. as_bool :: proc(a: any) -> (value: bool, valid: bool) {
  771. if a == nil { return }
  772. a := a
  773. ti := runtime.type_info_core(type_info_of(a.id))
  774. a.id = ti.id
  775. #partial switch info in ti.variant {
  776. case Type_Info_Boolean:
  777. valid = true
  778. switch v in a {
  779. case bool: value = v
  780. case b8: value = bool(v)
  781. case b16: value = bool(v)
  782. case b32: value = bool(v)
  783. case b64: value = bool(v)
  784. case: valid = false
  785. }
  786. }
  787. return
  788. }
  789. @(require_results)
  790. as_int :: proc(a: any) -> (value: int, valid: bool) {
  791. v: i64
  792. v, valid = as_i64(a)
  793. value = int(v)
  794. return
  795. }
  796. @(require_results)
  797. as_uint :: proc(a: any) -> (value: uint, valid: bool) {
  798. v: u64
  799. v, valid = as_u64(a)
  800. value = uint(v)
  801. return
  802. }
  803. @(require_results)
  804. as_i64 :: proc(a: any) -> (value: i64, valid: bool) {
  805. if a == nil { return }
  806. a := a
  807. ti := runtime.type_info_core(type_info_of(a.id))
  808. a.id = ti.id
  809. #partial switch info in ti.variant {
  810. case Type_Info_Integer:
  811. valid = true
  812. switch v in a {
  813. case i8: value = i64(v)
  814. case i16: value = i64(v)
  815. case i32: value = i64(v)
  816. case i64: value = v
  817. case i128: value = i64(v)
  818. case int: value = i64(v)
  819. case u8: value = i64(v)
  820. case u16: value = i64(v)
  821. case u32: value = i64(v)
  822. case u64: value = i64(v)
  823. case u128: value = i64(v)
  824. case uint: value = i64(v)
  825. case uintptr: value = i64(v)
  826. case u16le: value = i64(v)
  827. case u32le: value = i64(v)
  828. case u64le: value = i64(v)
  829. case u128le: value = i64(v)
  830. case i16le: value = i64(v)
  831. case i32le: value = i64(v)
  832. case i64le: value = i64(v)
  833. case i128le: value = i64(v)
  834. case u16be: value = i64(v)
  835. case u32be: value = i64(v)
  836. case u64be: value = i64(v)
  837. case u128be: value = i64(v)
  838. case i16be: value = i64(v)
  839. case i32be: value = i64(v)
  840. case i64be: value = i64(v)
  841. case i128be: value = i64(v)
  842. case: valid = false
  843. }
  844. case Type_Info_Rune:
  845. r := a.(rune)
  846. value = i64(r)
  847. valid = true
  848. case Type_Info_Float:
  849. valid = true
  850. switch v in a {
  851. case f32: value = i64(v)
  852. case f64: value = i64(v)
  853. case f32le: value = i64(v)
  854. case f64le: value = i64(v)
  855. case f32be: value = i64(v)
  856. case f64be: value = i64(v)
  857. case: valid = false
  858. }
  859. case Type_Info_Boolean:
  860. valid = true
  861. switch v in a {
  862. case bool: value = i64(v)
  863. case b8: value = i64(v)
  864. case b16: value = i64(v)
  865. case b32: value = i64(v)
  866. case b64: value = i64(v)
  867. case: valid = false
  868. }
  869. case Type_Info_Complex:
  870. switch v in a {
  871. case complex64:
  872. if imag(v) == 0 {
  873. value = i64(real(v))
  874. valid = true
  875. }
  876. case complex128:
  877. if imag(v) == 0 {
  878. value = i64(real(v))
  879. valid = true
  880. }
  881. }
  882. case Type_Info_Quaternion:
  883. switch v in a {
  884. case quaternion128:
  885. if imag(v) == 0 && jmag(v) == 0 && kmag(v) == 0 {
  886. value = i64(real(v))
  887. valid = true
  888. }
  889. case quaternion256:
  890. if imag(v) == 0 && jmag(v) == 0 && kmag(v) == 0 {
  891. value = i64(real(v))
  892. valid = true
  893. }
  894. }
  895. }
  896. return
  897. }
  898. @(require_results)
  899. as_u64 :: proc(a: any) -> (value: u64, valid: bool) {
  900. if a == nil { return }
  901. a := a
  902. ti := runtime.type_info_core(type_info_of(a.id))
  903. a.id = ti.id
  904. #partial switch info in ti.variant {
  905. case Type_Info_Integer:
  906. valid = true
  907. switch v in a {
  908. case i8: value = u64(v)
  909. case i16: value = u64(v)
  910. case i32: value = u64(v)
  911. case i64: value = u64(v)
  912. case i128: value = u64(v)
  913. case int: value = u64(v)
  914. case u8: value = u64(v)
  915. case u16: value = u64(v)
  916. case u32: value = u64(v)
  917. case u64: value = (v)
  918. case u128: value = u64(v)
  919. case uint: value = u64(v)
  920. case uintptr:value = u64(v)
  921. case u16le: value = u64(v)
  922. case u32le: value = u64(v)
  923. case u64le: value = u64(v)
  924. case u128le: value = u64(v)
  925. case i16le: value = u64(v)
  926. case i32le: value = u64(v)
  927. case i64le: value = u64(v)
  928. case i128le: value = u64(v)
  929. case u16be: value = u64(v)
  930. case u32be: value = u64(v)
  931. case u64be: value = u64(v)
  932. case u128be: value = u64(v)
  933. case i16be: value = u64(v)
  934. case i32be: value = u64(v)
  935. case i64be: value = u64(v)
  936. case i128be: value = u64(v)
  937. case: valid = false
  938. }
  939. case Type_Info_Rune:
  940. r := a.(rune)
  941. value = u64(r)
  942. valid = true
  943. case Type_Info_Float:
  944. valid = true
  945. switch v in a {
  946. case f16: value = u64(v)
  947. case f32: value = u64(v)
  948. case f64: value = u64(v)
  949. case f32le: value = u64(v)
  950. case f64le: value = u64(v)
  951. case f32be: value = u64(v)
  952. case f64be: value = u64(v)
  953. case: valid = false
  954. }
  955. case Type_Info_Boolean:
  956. valid = true
  957. switch v in a {
  958. case bool: value = u64(v)
  959. case b8: value = u64(v)
  960. case b16: value = u64(v)
  961. case b32: value = u64(v)
  962. case b64: value = u64(v)
  963. case: valid = false
  964. }
  965. case Type_Info_Complex:
  966. switch v in a {
  967. case complex64:
  968. if imag(v) == 0 {
  969. value = u64(real(v))
  970. valid = true
  971. }
  972. case complex128:
  973. if imag(v) == 0 {
  974. value = u64(real(v))
  975. valid = true
  976. }
  977. }
  978. case Type_Info_Quaternion:
  979. switch v in a {
  980. case quaternion128:
  981. if imag(v) == 0 && jmag(v) == 0 && kmag(v) == 0 {
  982. value = u64(real(v))
  983. valid = true
  984. }
  985. case quaternion256:
  986. if imag(v) == 0 && jmag(v) == 0 && kmag(v) == 0 {
  987. value = u64(real(v))
  988. valid = true
  989. }
  990. }
  991. }
  992. return
  993. }
  994. @(require_results)
  995. as_f64 :: proc(a: any) -> (value: f64, valid: bool) {
  996. if a == nil { return }
  997. a := a
  998. ti := runtime.type_info_core(type_info_of(a.id))
  999. a.id = ti.id
  1000. #partial switch info in ti.variant {
  1001. case Type_Info_Integer:
  1002. valid = true
  1003. switch v in a {
  1004. case i8: value = f64(v)
  1005. case i16: value = f64(v)
  1006. case i32: value = f64(v)
  1007. case i64: value = f64(v)
  1008. case i128: value = f64(v)
  1009. case u8: value = f64(v)
  1010. case u16: value = f64(v)
  1011. case u32: value = f64(v)
  1012. case u64: value = f64(v)
  1013. case u128: value = f64(v)
  1014. case u16le: value = f64(v)
  1015. case u32le: value = f64(v)
  1016. case u64le: value = f64(v)
  1017. case u128le:value = f64(v)
  1018. case i16le: value = f64(v)
  1019. case i32le: value = f64(v)
  1020. case i64le: value = f64(v)
  1021. case i128le:value = f64(v)
  1022. case u16be: value = f64(v)
  1023. case u32be: value = f64(v)
  1024. case u64be: value = f64(v)
  1025. case u128be:value = f64(v)
  1026. case i16be: value = f64(v)
  1027. case i32be: value = f64(v)
  1028. case i64be: value = f64(v)
  1029. case i128be:value = f64(v)
  1030. case: valid = false
  1031. }
  1032. case Type_Info_Rune:
  1033. r := a.(rune)
  1034. value = f64(i32(r))
  1035. valid = true
  1036. case Type_Info_Float:
  1037. valid = true
  1038. switch v in a {
  1039. case f16: value = f64(v)
  1040. case f32: value = f64(v)
  1041. case f64: value = (v)
  1042. case f32le: value = f64(v)
  1043. case f64le: value = f64(v)
  1044. case f32be: value = f64(v)
  1045. case f64be: value = f64(v)
  1046. case: valid = false
  1047. }
  1048. case Type_Info_Boolean:
  1049. valid = true
  1050. switch v in a {
  1051. case bool: value = f64(i32(v))
  1052. case b8: value = f64(i32(v))
  1053. case b16: value = f64(i32(v))
  1054. case b32: value = f64(i32(v))
  1055. case b64: value = f64(i32(v))
  1056. case: valid = false
  1057. }
  1058. case Type_Info_Complex:
  1059. switch v in a {
  1060. case complex64:
  1061. if imag(v) == 0 {
  1062. value = f64(real(v))
  1063. valid = true
  1064. }
  1065. case complex128:
  1066. if imag(v) == 0 {
  1067. value = real(v)
  1068. valid = true
  1069. }
  1070. }
  1071. case Type_Info_Quaternion:
  1072. switch v in a {
  1073. case quaternion128:
  1074. if imag(v) == 0 && jmag(v) == 0 && kmag(v) == 0 {
  1075. value = f64(real(v))
  1076. valid = true
  1077. }
  1078. case quaternion256:
  1079. if imag(v) == 0 && jmag(v) == 0 && kmag(v) == 0 {
  1080. value = real(v)
  1081. valid = true
  1082. }
  1083. }
  1084. }
  1085. return
  1086. }
  1087. @(require_results)
  1088. as_string :: proc(a: any) -> (value: string, valid: bool) {
  1089. if a == nil { return }
  1090. a := a
  1091. ti := runtime.type_info_core(type_info_of(a.id))
  1092. a.id = ti.id
  1093. #partial switch info in ti.variant {
  1094. case Type_Info_String:
  1095. valid = true
  1096. switch v in a {
  1097. case string: value = v
  1098. case cstring: value = string(v)
  1099. case: valid = false
  1100. }
  1101. }
  1102. return
  1103. }
  1104. @(require_results)
  1105. relative_pointer_to_absolute :: proc(a: any) -> rawptr {
  1106. if a == nil { return nil }
  1107. a := a
  1108. ti := runtime.type_info_core(type_info_of(a.id))
  1109. a.id = ti.id
  1110. #partial switch info in ti.variant {
  1111. case Type_Info_Relative_Pointer:
  1112. return relative_pointer_to_absolute_raw(a.data, info.base_integer.id)
  1113. }
  1114. return nil
  1115. }
  1116. @(require_results)
  1117. relative_pointer_to_absolute_raw :: proc(data: rawptr, base_integer_id: typeid) -> rawptr {
  1118. _handle :: proc(ptr: ^$T) -> rawptr where intrinsics.type_is_integer(T) {
  1119. if ptr^ == 0 {
  1120. return nil
  1121. }
  1122. when intrinsics.type_is_unsigned(T) {
  1123. return rawptr(uintptr(ptr) + uintptr(ptr^))
  1124. } else {
  1125. return rawptr(uintptr(ptr) + uintptr(i64(ptr^)))
  1126. }
  1127. }
  1128. ptr_any := any{data, base_integer_id}
  1129. ptr: rawptr
  1130. switch i in &ptr_any {
  1131. case u8: ptr = _handle(&i)
  1132. case u16: ptr = _handle(&i)
  1133. case u32: ptr = _handle(&i)
  1134. case u64: ptr = _handle(&i)
  1135. case i8: ptr = _handle(&i)
  1136. case i16: ptr = _handle(&i)
  1137. case i32: ptr = _handle(&i)
  1138. case i64: ptr = _handle(&i)
  1139. case u16le: ptr = _handle(&i)
  1140. case u32le: ptr = _handle(&i)
  1141. case u64le: ptr = _handle(&i)
  1142. case i16le: ptr = _handle(&i)
  1143. case i32le: ptr = _handle(&i)
  1144. case i64le: ptr = _handle(&i)
  1145. case u16be: ptr = _handle(&i)
  1146. case u32be: ptr = _handle(&i)
  1147. case u64be: ptr = _handle(&i)
  1148. case i16be: ptr = _handle(&i)
  1149. case i32be: ptr = _handle(&i)
  1150. case i64be: ptr = _handle(&i)
  1151. }
  1152. return ptr
  1153. }
  1154. @(require_results)
  1155. as_pointer :: proc(a: any) -> (value: rawptr, valid: bool) {
  1156. if a == nil { return }
  1157. a := a
  1158. ti := runtime.type_info_core(type_info_of(a.id))
  1159. a.id = ti.id
  1160. #partial switch info in ti.variant {
  1161. case Type_Info_Pointer:
  1162. valid = true
  1163. value = a.data
  1164. case Type_Info_String:
  1165. valid = true
  1166. switch v in a {
  1167. case cstring: value = rawptr(v)
  1168. case: valid = false
  1169. }
  1170. case Type_Info_Relative_Pointer:
  1171. valid = true
  1172. value = relative_pointer_to_absolute_raw(a.data, info.base_integer.id)
  1173. }
  1174. return
  1175. }
  1176. @(require_results)
  1177. as_raw_data :: proc(a: any) -> (value: rawptr, valid: bool) {
  1178. if a == nil { return }
  1179. a := a
  1180. ti := runtime.type_info_core(type_info_of(a.id))
  1181. a.id = ti.id
  1182. #partial switch info in ti.variant {
  1183. case Type_Info_String:
  1184. valid = true
  1185. switch v in a {
  1186. case string: value = raw_data(v)
  1187. case cstring: value = rawptr(v) // just in case
  1188. case: valid = false
  1189. }
  1190. case Type_Info_Array:
  1191. valid = true
  1192. value = a.data
  1193. case Type_Info_Slice:
  1194. valid = true
  1195. value = (^runtime.Raw_Slice)(a.data).data
  1196. case Type_Info_Dynamic_Array:
  1197. valid = true
  1198. value = (^runtime.Raw_Dynamic_Array)(a.data).data
  1199. }
  1200. return
  1201. }
  1202. eq :: equal
  1203. ne :: not_equal
  1204. DEFAULT_EQUAL_MAX_RECURSION_LEVEL :: 32
  1205. @(require_results)
  1206. not_equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_level := 0) -> bool {
  1207. return !equal(a, b, including_indirect_array_recursion, recursion_level)
  1208. }
  1209. @(require_results)
  1210. equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_level := 0) -> bool {
  1211. if a == nil && b == nil {
  1212. return true
  1213. }
  1214. if a.id != b.id {
  1215. return false
  1216. }
  1217. if a.data == b.data {
  1218. return true
  1219. }
  1220. including_indirect_array_recursion := including_indirect_array_recursion
  1221. if recursion_level >= DEFAULT_EQUAL_MAX_RECURSION_LEVEL {
  1222. including_indirect_array_recursion = false
  1223. }
  1224. t := type_info_of(a.id)
  1225. if .Comparable not_in t.flags && !including_indirect_array_recursion {
  1226. return false
  1227. }
  1228. if t.size == 0 {
  1229. return true
  1230. }
  1231. if .Simple_Compare in t.flags {
  1232. return runtime.memory_compare(a.data, b.data, t.size) == 0
  1233. }
  1234. t = runtime.type_info_core(t)
  1235. switch v in t.variant {
  1236. case Type_Info_Named:
  1237. unreachable()
  1238. case Type_Info_Parameters:
  1239. unreachable()
  1240. case Type_Info_Any:
  1241. if !including_indirect_array_recursion {
  1242. return false
  1243. }
  1244. va := (^any)(a.data)
  1245. vb := (^any)(b.data)
  1246. return equal(va, vb, including_indirect_array_recursion, recursion_level+1)
  1247. case Type_Info_Map:
  1248. return false
  1249. case Type_Info_Relative_Slice:
  1250. return false
  1251. case
  1252. Type_Info_Boolean,
  1253. Type_Info_Integer,
  1254. Type_Info_Rune,
  1255. Type_Info_Float,
  1256. Type_Info_Complex,
  1257. Type_Info_Quaternion,
  1258. Type_Info_Type_Id,
  1259. Type_Info_Pointer,
  1260. Type_Info_Multi_Pointer,
  1261. Type_Info_Procedure,
  1262. Type_Info_Bit_Set,
  1263. Type_Info_Enum,
  1264. Type_Info_Simd_Vector,
  1265. Type_Info_Relative_Pointer,
  1266. Type_Info_Soa_Pointer,
  1267. Type_Info_Matrix:
  1268. return runtime.memory_compare(a.data, b.data, t.size) == 0
  1269. case Type_Info_String:
  1270. if v.is_cstring {
  1271. x := string((^cstring)(a.data)^)
  1272. y := string((^cstring)(b.data)^)
  1273. return x == y
  1274. } else {
  1275. x := (^string)(a.data)^
  1276. y := (^string)(b.data)^
  1277. return x == y
  1278. }
  1279. return true
  1280. case Type_Info_Array:
  1281. for i in 0..<v.count {
  1282. x := rawptr(uintptr(a.data) + uintptr(v.elem_size*i))
  1283. y := rawptr(uintptr(b.data) + uintptr(v.elem_size*i))
  1284. if !equal(any{x, v.elem.id}, any{y, v.elem.id}, including_indirect_array_recursion, recursion_level) {
  1285. return false
  1286. }
  1287. }
  1288. return true
  1289. case Type_Info_Enumerated_Array:
  1290. for i in 0..<v.count {
  1291. x := rawptr(uintptr(a.data) + uintptr(v.elem_size*i))
  1292. y := rawptr(uintptr(b.data) + uintptr(v.elem_size*i))
  1293. if !equal(any{x, v.elem.id}, any{y, v.elem.id}, including_indirect_array_recursion, recursion_level) {
  1294. return false
  1295. }
  1296. }
  1297. return true
  1298. case Type_Info_Struct:
  1299. if v.equal != nil {
  1300. return v.equal(a.data, b.data)
  1301. } else {
  1302. for offset, i in v.offsets {
  1303. x := rawptr(uintptr(a.data) + offset)
  1304. y := rawptr(uintptr(b.data) + offset)
  1305. id := v.types[i].id
  1306. if !equal(any{x, id}, any{y, id}, including_indirect_array_recursion, recursion_level) {
  1307. return false
  1308. }
  1309. }
  1310. return true
  1311. }
  1312. case Type_Info_Union:
  1313. if v.equal != nil {
  1314. return v.equal(a.data, b.data)
  1315. }
  1316. return false
  1317. case Type_Info_Slice:
  1318. if !including_indirect_array_recursion {
  1319. return false
  1320. }
  1321. array_a := (^runtime.Raw_Slice)(a.data)
  1322. array_b := (^runtime.Raw_Slice)(b.data)
  1323. if array_a.len != array_b.len {
  1324. return false
  1325. }
  1326. if array_a.data == array_b.data {
  1327. return true
  1328. }
  1329. for i in 0..<array_a.len {
  1330. x := rawptr(uintptr(array_a.data) + uintptr(v.elem_size*i))
  1331. y := rawptr(uintptr(array_b.data) + uintptr(v.elem_size*i))
  1332. if !equal(any{x, v.elem.id}, any{y, v.elem.id}, including_indirect_array_recursion, recursion_level+1) {
  1333. return false
  1334. }
  1335. }
  1336. return true
  1337. case Type_Info_Dynamic_Array:
  1338. if !including_indirect_array_recursion {
  1339. return false
  1340. }
  1341. array_a := (^runtime.Raw_Dynamic_Array)(a.data)
  1342. array_b := (^runtime.Raw_Dynamic_Array)(b.data)
  1343. if array_a.len != array_b.len {
  1344. return false
  1345. }
  1346. if array_a.data == array_b.data {
  1347. return true
  1348. }
  1349. if .Simple_Compare in v.elem.flags {
  1350. return runtime.memory_compare((^byte)(array_a.data), (^byte)(array_b.data), array_a.len * v.elem.size) == 0
  1351. }
  1352. for i in 0..<array_a.len {
  1353. x := rawptr(uintptr(array_a.data) + uintptr(v.elem_size*i))
  1354. y := rawptr(uintptr(array_b.data) + uintptr(v.elem_size*i))
  1355. if !equal(any{x, v.elem.id}, any{y, v.elem.id}, including_indirect_array_recursion, recursion_level+1) {
  1356. return false
  1357. }
  1358. }
  1359. return true
  1360. }
  1361. runtime.print_typeid(a.id)
  1362. runtime.print_string("\n")
  1363. return true
  1364. }