reflect.odin 35 KB

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