reflect.odin 37 KB

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