reflect.odin 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769
  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.id != 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.id != 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 < int(s.field_count) {
  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[:s.field_count] {
  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[:s.field_count] {
  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[:s.field_count]
  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[:s.field_count]
  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[:s.field_count]
  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[:s.field_count]
  423. }
  424. return nil
  425. }
  426. Struct_Field_Count_Method :: enum {
  427. Top_Level,
  428. Using,
  429. Recursive,
  430. }
  431. /*
  432. Counts the number of fields in a struct
  433. This procedure returns the number of fields in a struct, counting in one of three ways:
  434. - .Top_Level: Only counts the top-level fields
  435. - .Using: Same count as .Top_Level, and adds the field count of any `using s: Struct` it encounters (in addition to itself)
  436. - .Recursive: The count of all top-level fields, plus the count of any child struct's fields, recursively
  437. Inputs:
  438. - T: The struct type
  439. - method: The counting method
  440. Returns:
  441. - The `count`, enumerated using the `method`, which will be `0` if the type is not a struct
  442. Example:
  443. symbols_loaded, ok := dynlib.initialize_symbols(&game_api, "game.dll")
  444. symbols_expected := reflect.struct_field_count(Game_Api) - API_PRIVATE_COUNT
  445. if symbols_loaded != symbols_expected {
  446. fmt.eprintf("Expected %v symbols, got %v", symbols_expected, symbols_loaded)
  447. return
  448. }
  449. */
  450. @(require_results)
  451. struct_field_count :: proc(T: typeid, method := Struct_Field_Count_Method.Top_Level) -> (count: int) {
  452. ti := runtime.type_info_base(type_info_of(T))
  453. if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
  454. switch method {
  455. case .Top_Level:
  456. return int(s.field_count)
  457. case .Using:
  458. count = int(s.field_count)
  459. for type, i in s.types[:s.field_count] {
  460. if s.usings[i] {
  461. count += struct_field_count(type.id)
  462. }
  463. }
  464. case .Recursive:
  465. count = int(s.field_count)
  466. for type in s.types[:s.field_count] {
  467. count += struct_field_count(type.id)
  468. }
  469. case: return 0
  470. }
  471. }
  472. return
  473. }
  474. @(require_results)
  475. struct_fields_zipped :: proc(T: typeid) -> (fields: #soa[]Struct_Field) {
  476. ti := runtime.type_info_base(type_info_of(T))
  477. if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
  478. return soa_zip(
  479. name = s.names[:s.field_count],
  480. type = s.types[:s.field_count],
  481. tag = ([^]Struct_Tag)(s.tags)[:s.field_count],
  482. offset = s.offsets[:s.field_count],
  483. is_using = s.usings[:s.field_count],
  484. )
  485. }
  486. return nil
  487. }
  488. @(require_results)
  489. struct_tag_get :: proc(tag: Struct_Tag, key: string) -> (value: string) {
  490. v, _ := struct_tag_lookup(tag, key)
  491. return string(v)
  492. }
  493. @(require_results)
  494. struct_tag_lookup :: proc(tag: Struct_Tag, key: string) -> (value: string, ok: bool) {
  495. for t := tag; t != ""; /**/ {
  496. i := 0
  497. for i < len(t) && t[i] == ' ' { // Skip whitespace
  498. i += 1
  499. }
  500. t = t[i:]
  501. if len(t) == 0 {
  502. break
  503. }
  504. i = 0
  505. loop: for i < len(t) {
  506. switch t[i] {
  507. case ':', '"':
  508. break loop
  509. case 0x00 ..< ' ', 0x7f ..= 0x9f: // break if control character is found
  510. break loop
  511. }
  512. i += 1
  513. }
  514. if i == 0 {
  515. break
  516. }
  517. if i+1 >= len(t) {
  518. break
  519. }
  520. if t[i] != ':' || t[i+1] != '"' {
  521. break
  522. }
  523. name := string(t[:i])
  524. t = t[i+1:]
  525. i = 1
  526. for i < len(t) && t[i] != '"' { // find closing quote
  527. if t[i] == '\\' {
  528. i += 1 // Skip escaped characters
  529. }
  530. i += 1
  531. }
  532. if i >= len(t) {
  533. break
  534. }
  535. val := string(t[:i+1])
  536. t = t[i+1:]
  537. if key == name {
  538. return val[1:i], true
  539. }
  540. }
  541. return
  542. }
  543. @(require_results)
  544. enum_string :: proc(a: any) -> string {
  545. if a == nil { return "" }
  546. ti := runtime.type_info_base(type_info_of(a.id))
  547. if e, ok := ti.variant.(runtime.Type_Info_Enum); ok {
  548. v, _ := as_i64(a)
  549. for value, i in e.values {
  550. if value == Type_Info_Enum_Value(v) {
  551. return e.names[i]
  552. }
  553. }
  554. } else {
  555. panic("expected an enum to reflect.enum_string")
  556. }
  557. return ""
  558. }
  559. // Given a enum type and a value name, get the enum value.
  560. @(require_results)
  561. enum_from_name :: proc($Enum_Type: typeid, name: string) -> (value: Enum_Type, ok: bool) {
  562. ti := type_info_base(type_info_of(Enum_Type))
  563. if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
  564. for value_name, i in eti.names {
  565. if value_name != name {
  566. continue
  567. }
  568. v := eti.values[i]
  569. value = Enum_Type(v)
  570. ok = true
  571. return
  572. }
  573. }
  574. return
  575. }
  576. @(require_results)
  577. enum_from_name_any :: proc(Enum_Type: typeid, name: string) -> (value: Type_Info_Enum_Value, ok: bool) {
  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. for value_name, i in eti.names {
  581. if value_name != name {
  582. continue
  583. }
  584. value = eti.values[i]
  585. ok = true
  586. return
  587. }
  588. }
  589. return
  590. }
  591. @(require_results)
  592. enum_name_from_value :: proc(value: $Enum_Type) -> (name: string, ok: bool) where intrinsics.type_is_enum(Enum_Type) {
  593. ti := type_info_base(type_info_of(Enum_Type))
  594. e := ti.variant.(runtime.Type_Info_Enum) or_return
  595. if len(e.values) == 0 {
  596. return
  597. }
  598. ev := Type_Info_Enum_Value(value)
  599. for val, idx in e.values {
  600. if val == ev {
  601. return e.names[idx], true
  602. }
  603. }
  604. return
  605. }
  606. @(require_results)
  607. enum_name_from_value_any :: proc(value: any) -> (name: string, ok: bool) {
  608. if value.id == nil {
  609. return
  610. }
  611. ti := type_info_base(type_info_of(value.id))
  612. e := ti.variant.(runtime.Type_Info_Enum) or_return
  613. if len(e.values) == 0 {
  614. return
  615. }
  616. ev := Type_Info_Enum_Value(as_i64(value) or_return)
  617. for val, idx in e.values {
  618. if val == ev {
  619. return e.names[idx], true
  620. }
  621. }
  622. return
  623. }
  624. @(require_results)
  625. enum_field_names :: proc(Enum_Type: typeid) -> []string {
  626. ti := runtime.type_info_base(type_info_of(Enum_Type))
  627. if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
  628. return eti.names
  629. }
  630. return nil
  631. }
  632. @(require_results)
  633. enum_field_values :: proc(Enum_Type: typeid) -> []Type_Info_Enum_Value {
  634. ti := runtime.type_info_base(type_info_of(Enum_Type))
  635. if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
  636. return eti.values
  637. }
  638. return nil
  639. }
  640. Enum_Field :: struct {
  641. name: string,
  642. value: Type_Info_Enum_Value,
  643. }
  644. @(require_results)
  645. enum_fields_zipped :: proc(Enum_Type: typeid) -> (fields: #soa[]Enum_Field) {
  646. ti := runtime.type_info_base(type_info_of(Enum_Type))
  647. if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
  648. return soa_zip(name=eti.names, value=eti.values)
  649. }
  650. return nil
  651. }
  652. @(require_results)
  653. union_variant_type_info :: proc(a: any) -> ^Type_Info {
  654. id := union_variant_typeid(a)
  655. return type_info_of(id)
  656. }
  657. @(require_results)
  658. type_info_union_is_pure_maybe :: proc(info: runtime.Type_Info_Union) -> bool {
  659. return len(info.variants) == 1 && is_pointer_internally(info.variants[0])
  660. }
  661. @(require_results)
  662. union_variant_typeid :: proc(a: any) -> typeid {
  663. if a == nil { return nil }
  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. if a.data != nil {
  668. return info.variants[0].id
  669. }
  670. return nil
  671. }
  672. tag_ptr := uintptr(a.data) + info.tag_offset
  673. tag_any := any{rawptr(tag_ptr), info.tag_type.id}
  674. tag: i64 = ---
  675. switch i in tag_any {
  676. case u8: tag = i64(i)
  677. case i8: tag = i64(i)
  678. case u16: tag = i64(i)
  679. case i16: tag = i64(i)
  680. case u32: tag = i64(i)
  681. case i32: tag = i64(i)
  682. case u64: tag = i64(i)
  683. case i64: tag = i
  684. case: unimplemented()
  685. }
  686. if info.no_nil {
  687. return info.variants[tag].id
  688. } else if tag != 0 {
  689. return info.variants[tag-1].id
  690. }
  691. return nil
  692. }
  693. panic("expected a union to reflect.union_variant_typeid")
  694. }
  695. @(require_results)
  696. get_union_variant_raw_tag :: proc(a: any) -> i64 {
  697. if a == nil { return -1 }
  698. ti := runtime.type_info_base(type_info_of(a.id))
  699. if info, ok := ti.variant.(runtime.Type_Info_Union); ok {
  700. if type_info_union_is_pure_maybe(info) {
  701. return 1 if a.data != nil else 0
  702. }
  703. tag_ptr := uintptr(a.data) + info.tag_offset
  704. tag_any := any{rawptr(tag_ptr), info.tag_type.id}
  705. tag: i64 = ---
  706. switch i in tag_any {
  707. case u8: tag = i64(i)
  708. case i8: tag = i64(i)
  709. case u16: tag = i64(i)
  710. case i16: tag = i64(i)
  711. case u32: tag = i64(i)
  712. case i32: tag = i64(i)
  713. case u64: tag = i64(i)
  714. case i64: tag = i
  715. case: unimplemented()
  716. }
  717. return tag
  718. }
  719. panic("expected a union to reflect.get_union_variant_raw_tag")
  720. }
  721. @(require_results)
  722. get_union_variant :: proc(a: any) -> any {
  723. if a == nil {
  724. return nil
  725. }
  726. id := union_variant_typeid(a)
  727. if id == nil {
  728. return nil
  729. }
  730. return any{a.data, id}
  731. }
  732. @(require_results)
  733. get_union_as_ptr_variants :: proc(val: ^$T) -> (res: intrinsics.type_convert_variants_to_pointers(T)) where intrinsics.type_is_union(T) {
  734. ptr := rawptr(val)
  735. tag := get_union_variant_raw_tag(val^)
  736. intrinsics.mem_copy(&res, &ptr, size_of(ptr))
  737. set_union_variant_raw_tag(res, tag)
  738. return
  739. }
  740. set_union_variant_raw_tag :: proc(a: any, tag: i64) {
  741. if a == nil { return }
  742. ti := runtime.type_info_base(type_info_of(a.id))
  743. if info, ok := ti.variant.(runtime.Type_Info_Union); ok {
  744. if type_info_union_is_pure_maybe(info) {
  745. // Cannot do anything
  746. return
  747. }
  748. tag_ptr := uintptr(a.data) + info.tag_offset
  749. tag_any := any{rawptr(tag_ptr), info.tag_type.id}
  750. switch &i in tag_any {
  751. case u8: i = u8(tag)
  752. case i8: i = i8(tag)
  753. case u16: i = u16(tag)
  754. case i16: i = i16(tag)
  755. case u32: i = u32(tag)
  756. case i32: i = i32(tag)
  757. case u64: i = u64(tag)
  758. case i64: i = tag
  759. case: unimplemented()
  760. }
  761. return
  762. }
  763. panic("expected a union to reflect.set_union_variant_raw_tag")
  764. }
  765. set_union_variant_typeid :: proc(a: any, id: typeid) {
  766. if a == nil { return }
  767. ti := runtime.type_info_base(type_info_of(a.id))
  768. if info, ok := ti.variant.(runtime.Type_Info_Union); ok {
  769. if type_info_union_is_pure_maybe(info) {
  770. // Cannot do anything
  771. return
  772. }
  773. if id == nil && !info.no_nil {
  774. set_union_variant_raw_tag(a, 0)
  775. return
  776. }
  777. for variant, i in info.variants {
  778. if variant.id == id {
  779. tag := i64(i)
  780. if !info.no_nil {
  781. tag += 1
  782. }
  783. set_union_variant_raw_tag(a, tag)
  784. return
  785. }
  786. }
  787. return
  788. }
  789. panic("expected a union to reflect.set_union_variant_typeid")
  790. }
  791. set_union_variant_type_info :: proc(a: any, tag_ti: ^Type_Info) {
  792. if a == nil { return }
  793. ti := runtime.type_info_base(type_info_of(a.id))
  794. if info, ok := ti.variant.(runtime.Type_Info_Union); ok {
  795. if type_info_union_is_pure_maybe(info) {
  796. // Cannot do anything
  797. return
  798. }
  799. if tag_ti == nil && !info.no_nil {
  800. set_union_variant_raw_tag(a, 0)
  801. return
  802. }
  803. for variant, i in info.variants {
  804. if variant == tag_ti {
  805. tag := i64(i)
  806. if !info.no_nil {
  807. tag += 1
  808. }
  809. set_union_variant_raw_tag(a, tag)
  810. return
  811. }
  812. }
  813. return
  814. }
  815. panic("expected a union to reflect.set_union_variant_type_info")
  816. }
  817. set_union_value :: proc(dst: any, value: any) -> bool {
  818. if dst == nil { return false }
  819. ti := runtime.type_info_base(type_info_of(dst.id))
  820. if info, ok := ti.variant.(runtime.Type_Info_Union); ok {
  821. if value.id == nil {
  822. intrinsics.mem_zero(dst.data, ti.size)
  823. return true
  824. }
  825. if ti.id == runtime.typeid_base(value.id) {
  826. intrinsics.mem_copy(dst.data, value.data, ti.size)
  827. return true
  828. }
  829. if type_info_union_is_pure_maybe(info) {
  830. if variant := info.variants[0]; variant.id == value.id {
  831. intrinsics.mem_copy(dst.data, value.data, variant.size)
  832. return true
  833. }
  834. return false
  835. }
  836. for variant, i in info.variants {
  837. if variant.id == value.id {
  838. tag := i64(i)
  839. if !info.no_nil {
  840. tag += 1
  841. }
  842. intrinsics.mem_copy(dst.data, value.data, variant.size)
  843. set_union_variant_raw_tag(dst, tag)
  844. return true
  845. }
  846. }
  847. return false
  848. }
  849. panic("expected a union to reflect.set_union_variant_typeid")
  850. }
  851. @(require_results)
  852. bit_set_is_big_endian :: proc(value: any, loc := #caller_location) -> bool {
  853. if value == nil { return ODIN_ENDIAN == .Big }
  854. ti := runtime.type_info_base(type_info_of(value.id))
  855. if info, ok := ti.variant.(runtime.Type_Info_Bit_Set); ok {
  856. if info.underlying == nil { return ODIN_ENDIAN == .Big }
  857. underlying_ti := runtime.type_info_base(info.underlying)
  858. if underlying_info, uok := underlying_ti.variant.(runtime.Type_Info_Integer); uok {
  859. switch underlying_info.endianness {
  860. case .Platform: return ODIN_ENDIAN == .Big
  861. case .Little: return false
  862. case .Big: return true
  863. }
  864. }
  865. return ODIN_ENDIAN == .Big
  866. }
  867. panic("expected a bit_set to reflect.bit_set_is_big_endian", loc)
  868. }
  869. Bit_Field :: struct {
  870. name: string,
  871. type: ^Type_Info,
  872. size: uintptr, // Size in bits
  873. offset: uintptr, // Offset in bits
  874. tag: Struct_Tag,
  875. }
  876. @(require_results)
  877. bit_fields_zipped :: proc(T: typeid) -> (fields: #soa[]Bit_Field) {
  878. ti := runtime.type_info_base(type_info_of(T))
  879. if s, ok := ti.variant.(runtime.Type_Info_Bit_Field); ok {
  880. return soa_zip(
  881. name = s.names[:s.field_count],
  882. type = s.types[:s.field_count],
  883. size = s.bit_sizes[:s.field_count],
  884. offset = s.bit_offsets[:s.field_count],
  885. tag = ([^]Struct_Tag)(s.tags)[:s.field_count],
  886. )
  887. }
  888. return nil
  889. }
  890. @(require_results)
  891. bit_field_names :: proc(T: typeid) -> []string {
  892. ti := runtime.type_info_base(type_info_of(T))
  893. if s, ok := ti.variant.(runtime.Type_Info_Bit_Field); ok {
  894. return s.names[:s.field_count]
  895. }
  896. return nil
  897. }
  898. @(require_results)
  899. bit_field_types :: proc(T: typeid) -> []^Type_Info {
  900. ti := runtime.type_info_base(type_info_of(T))
  901. if s, ok := ti.variant.(runtime.Type_Info_Bit_Field); ok {
  902. return s.types[:s.field_count]
  903. }
  904. return nil
  905. }
  906. @(require_results)
  907. bit_field_sizes :: proc(T: typeid) -> []uintptr {
  908. ti := runtime.type_info_base(type_info_of(T))
  909. if s, ok := ti.variant.(runtime.Type_Info_Bit_Field); ok {
  910. return s.bit_sizes[:s.field_count]
  911. }
  912. return nil
  913. }
  914. @(require_results)
  915. bit_field_offsets :: proc(T: typeid) -> []uintptr {
  916. ti := runtime.type_info_base(type_info_of(T))
  917. if s, ok := ti.variant.(runtime.Type_Info_Bit_Field); ok {
  918. return s.bit_offsets[:s.field_count]
  919. }
  920. return nil
  921. }
  922. @(require_results)
  923. bit_field_tags :: proc(T: typeid) -> []Struct_Tag {
  924. ti := runtime.type_info_base(type_info_of(T))
  925. if s, ok := ti.variant.(runtime.Type_Info_Bit_Field); ok {
  926. return transmute([]Struct_Tag)s.tags[:s.field_count]
  927. }
  928. return nil
  929. }
  930. @(require_results)
  931. as_bool :: proc(a: any) -> (value: bool, valid: bool) {
  932. if a == nil { return }
  933. a := a
  934. ti := runtime.type_info_core(type_info_of(a.id))
  935. a.id = ti.id
  936. #partial switch info in ti.variant {
  937. case Type_Info_Boolean:
  938. valid = true
  939. switch v in a {
  940. case bool: value = v
  941. case b8: value = bool(v)
  942. case b16: value = bool(v)
  943. case b32: value = bool(v)
  944. case b64: value = bool(v)
  945. case: valid = false
  946. }
  947. }
  948. return
  949. }
  950. @(require_results)
  951. as_int :: proc(a: any) -> (value: int, valid: bool) {
  952. v: i64
  953. v, valid = as_i64(a)
  954. value = int(v)
  955. return
  956. }
  957. @(require_results)
  958. as_uint :: proc(a: any) -> (value: uint, valid: bool) {
  959. v: u64
  960. v, valid = as_u64(a)
  961. value = uint(v)
  962. return
  963. }
  964. @(require_results)
  965. as_i64 :: proc(a: any) -> (value: i64, valid: bool) {
  966. if a == nil { return }
  967. a := a
  968. ti := runtime.type_info_core(type_info_of(a.id))
  969. a.id = ti.id
  970. #partial switch info in ti.variant {
  971. case Type_Info_Integer:
  972. valid = true
  973. switch v in a {
  974. case i8: value = i64(v)
  975. case i16: value = i64(v)
  976. case i32: value = i64(v)
  977. case i64: value = v
  978. case i128: value = i64(v)
  979. case int: value = i64(v)
  980. case u8: value = i64(v)
  981. case u16: value = i64(v)
  982. case u32: value = i64(v)
  983. case u64: value = i64(v)
  984. case u128: value = i64(v)
  985. case uint: value = i64(v)
  986. case uintptr: value = i64(v)
  987. case u16le: value = i64(v)
  988. case u32le: value = i64(v)
  989. case u64le: value = i64(v)
  990. case u128le: value = i64(v)
  991. case i16le: value = i64(v)
  992. case i32le: value = i64(v)
  993. case i64le: value = i64(v)
  994. case i128le: value = i64(v)
  995. case u16be: value = i64(v)
  996. case u32be: value = i64(v)
  997. case u64be: value = i64(v)
  998. case u128be: value = i64(v)
  999. case i16be: value = i64(v)
  1000. case i32be: value = i64(v)
  1001. case i64be: value = i64(v)
  1002. case i128be: value = i64(v)
  1003. case: valid = false
  1004. }
  1005. case Type_Info_Rune:
  1006. r := a.(rune)
  1007. value = i64(r)
  1008. valid = true
  1009. case Type_Info_Float:
  1010. valid = true
  1011. switch v in a {
  1012. case f32: value = i64(v)
  1013. case f64: value = i64(v)
  1014. case f32le: value = i64(v)
  1015. case f64le: value = i64(v)
  1016. case f32be: value = i64(v)
  1017. case f64be: value = i64(v)
  1018. case: valid = false
  1019. }
  1020. case Type_Info_Boolean:
  1021. valid = true
  1022. switch v in a {
  1023. case bool: value = i64(v)
  1024. case b8: value = i64(v)
  1025. case b16: value = i64(v)
  1026. case b32: value = i64(v)
  1027. case b64: value = i64(v)
  1028. case: valid = false
  1029. }
  1030. case Type_Info_Complex:
  1031. switch v in a {
  1032. case complex64:
  1033. if imag(v) == 0 {
  1034. value = i64(real(v))
  1035. valid = true
  1036. }
  1037. case complex128:
  1038. if imag(v) == 0 {
  1039. value = i64(real(v))
  1040. valid = true
  1041. }
  1042. }
  1043. case Type_Info_Quaternion:
  1044. switch v in a {
  1045. case quaternion128:
  1046. if imag(v) == 0 && jmag(v) == 0 && kmag(v) == 0 {
  1047. value = i64(real(v))
  1048. valid = true
  1049. }
  1050. case quaternion256:
  1051. if imag(v) == 0 && jmag(v) == 0 && kmag(v) == 0 {
  1052. value = i64(real(v))
  1053. valid = true
  1054. }
  1055. }
  1056. }
  1057. return
  1058. }
  1059. @(require_results)
  1060. as_u64 :: proc(a: any) -> (value: u64, 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_Integer:
  1067. valid = true
  1068. switch v in a {
  1069. case i8: value = u64(v)
  1070. case i16: value = u64(v)
  1071. case i32: value = u64(v)
  1072. case i64: value = u64(v)
  1073. case i128: value = u64(v)
  1074. case int: value = u64(v)
  1075. case u8: value = u64(v)
  1076. case u16: value = u64(v)
  1077. case u32: value = u64(v)
  1078. case u64: value = (v)
  1079. case u128: value = u64(v)
  1080. case uint: value = u64(v)
  1081. case uintptr:value = u64(v)
  1082. case u16le: value = u64(v)
  1083. case u32le: value = u64(v)
  1084. case u64le: value = u64(v)
  1085. case u128le: value = u64(v)
  1086. case i16le: value = u64(v)
  1087. case i32le: value = u64(v)
  1088. case i64le: value = u64(v)
  1089. case i128le: value = u64(v)
  1090. case u16be: value = u64(v)
  1091. case u32be: value = u64(v)
  1092. case u64be: value = u64(v)
  1093. case u128be: value = u64(v)
  1094. case i16be: value = u64(v)
  1095. case i32be: value = u64(v)
  1096. case i64be: value = u64(v)
  1097. case i128be: value = u64(v)
  1098. case: valid = false
  1099. }
  1100. case Type_Info_Rune:
  1101. r := a.(rune)
  1102. value = u64(r)
  1103. valid = true
  1104. case Type_Info_Float:
  1105. valid = true
  1106. switch v in a {
  1107. case f16: value = u64(v)
  1108. case f32: value = u64(v)
  1109. case f64: value = u64(v)
  1110. case f32le: value = u64(v)
  1111. case f64le: value = u64(v)
  1112. case f32be: value = u64(v)
  1113. case f64be: value = u64(v)
  1114. case: valid = false
  1115. }
  1116. case Type_Info_Boolean:
  1117. valid = true
  1118. switch v in a {
  1119. case bool: value = u64(v)
  1120. case b8: value = u64(v)
  1121. case b16: value = u64(v)
  1122. case b32: value = u64(v)
  1123. case b64: value = u64(v)
  1124. case: valid = false
  1125. }
  1126. case Type_Info_Complex:
  1127. switch v in a {
  1128. case complex64:
  1129. if imag(v) == 0 {
  1130. value = u64(real(v))
  1131. valid = true
  1132. }
  1133. case complex128:
  1134. if imag(v) == 0 {
  1135. value = u64(real(v))
  1136. valid = true
  1137. }
  1138. }
  1139. case Type_Info_Quaternion:
  1140. switch v in a {
  1141. case quaternion128:
  1142. if imag(v) == 0 && jmag(v) == 0 && kmag(v) == 0 {
  1143. value = u64(real(v))
  1144. valid = true
  1145. }
  1146. case quaternion256:
  1147. if imag(v) == 0 && jmag(v) == 0 && kmag(v) == 0 {
  1148. value = u64(real(v))
  1149. valid = true
  1150. }
  1151. }
  1152. }
  1153. return
  1154. }
  1155. @(require_results)
  1156. as_f64 :: proc(a: any) -> (value: f64, valid: bool) {
  1157. if a == nil { return }
  1158. a := a
  1159. ti := runtime.type_info_core(type_info_of(a.id))
  1160. a.id = ti.id
  1161. #partial switch info in ti.variant {
  1162. case Type_Info_Integer:
  1163. valid = true
  1164. switch v in a {
  1165. case i8: value = f64(v)
  1166. case i16: value = f64(v)
  1167. case i32: value = f64(v)
  1168. case i64: value = f64(v)
  1169. case i128: value = f64(v)
  1170. case u8: value = f64(v)
  1171. case u16: value = f64(v)
  1172. case u32: value = f64(v)
  1173. case u64: value = f64(v)
  1174. case u128: value = f64(v)
  1175. case u16le: value = f64(v)
  1176. case u32le: value = f64(v)
  1177. case u64le: value = f64(v)
  1178. case u128le:value = f64(v)
  1179. case i16le: value = f64(v)
  1180. case i32le: value = f64(v)
  1181. case i64le: value = f64(v)
  1182. case i128le:value = f64(v)
  1183. case u16be: value = f64(v)
  1184. case u32be: value = f64(v)
  1185. case u64be: value = f64(v)
  1186. case u128be:value = f64(v)
  1187. case i16be: value = f64(v)
  1188. case i32be: value = f64(v)
  1189. case i64be: value = f64(v)
  1190. case i128be:value = f64(v)
  1191. case: valid = false
  1192. }
  1193. case Type_Info_Rune:
  1194. r := a.(rune)
  1195. value = f64(i32(r))
  1196. valid = true
  1197. case Type_Info_Float:
  1198. valid = true
  1199. switch v in a {
  1200. case f16: value = f64(v)
  1201. case f32: value = f64(v)
  1202. case f64: value = (v)
  1203. case f32le: value = f64(v)
  1204. case f64le: value = f64(v)
  1205. case f32be: value = f64(v)
  1206. case f64be: value = f64(v)
  1207. case: valid = false
  1208. }
  1209. case Type_Info_Boolean:
  1210. valid = true
  1211. switch v in a {
  1212. case bool: value = f64(i32(v))
  1213. case b8: value = f64(i32(v))
  1214. case b16: value = f64(i32(v))
  1215. case b32: value = f64(i32(v))
  1216. case b64: value = f64(i32(v))
  1217. case: valid = false
  1218. }
  1219. case Type_Info_Complex:
  1220. switch v in a {
  1221. case complex64:
  1222. if imag(v) == 0 {
  1223. value = f64(real(v))
  1224. valid = true
  1225. }
  1226. case complex128:
  1227. if imag(v) == 0 {
  1228. value = real(v)
  1229. valid = true
  1230. }
  1231. }
  1232. case Type_Info_Quaternion:
  1233. switch v in a {
  1234. case quaternion128:
  1235. if imag(v) == 0 && jmag(v) == 0 && kmag(v) == 0 {
  1236. value = f64(real(v))
  1237. valid = true
  1238. }
  1239. case quaternion256:
  1240. if imag(v) == 0 && jmag(v) == 0 && kmag(v) == 0 {
  1241. value = real(v)
  1242. valid = true
  1243. }
  1244. }
  1245. }
  1246. return
  1247. }
  1248. @(require_results)
  1249. as_string :: proc(a: any) -> (value: string, valid: bool) {
  1250. if a == nil { return }
  1251. a := a
  1252. ti := runtime.type_info_core(type_info_of(a.id))
  1253. a.id = ti.id
  1254. #partial switch info in ti.variant {
  1255. case Type_Info_String:
  1256. valid = true
  1257. switch v in a {
  1258. case string: value = v
  1259. case cstring: value = string(v)
  1260. case: valid = false
  1261. }
  1262. }
  1263. return
  1264. }
  1265. @(require_results)
  1266. relative_pointer_to_absolute :: proc(a: any) -> rawptr {
  1267. if a == nil { return nil }
  1268. a := a
  1269. ti := runtime.type_info_core(type_info_of(a.id))
  1270. a.id = ti.id
  1271. #partial switch info in ti.variant {
  1272. case Type_Info_Relative_Pointer:
  1273. return relative_pointer_to_absolute_raw(a.data, info.base_integer.id)
  1274. }
  1275. return nil
  1276. }
  1277. @(require_results)
  1278. relative_pointer_to_absolute_raw :: proc(data: rawptr, base_integer_id: typeid) -> rawptr {
  1279. _handle :: proc(ptr: ^$T) -> rawptr where intrinsics.type_is_integer(T) {
  1280. if ptr^ == 0 {
  1281. return nil
  1282. }
  1283. when intrinsics.type_is_unsigned(T) {
  1284. return rawptr(uintptr(ptr) + uintptr(ptr^))
  1285. } else {
  1286. return rawptr(uintptr(ptr) + uintptr(i64(ptr^)))
  1287. }
  1288. }
  1289. ptr_any := any{data, base_integer_id}
  1290. ptr: rawptr
  1291. switch &i in ptr_any {
  1292. case u8: ptr = _handle(&i)
  1293. case u16: ptr = _handle(&i)
  1294. case u32: ptr = _handle(&i)
  1295. case u64: ptr = _handle(&i)
  1296. case i8: ptr = _handle(&i)
  1297. case i16: ptr = _handle(&i)
  1298. case i32: ptr = _handle(&i)
  1299. case i64: ptr = _handle(&i)
  1300. case u16le: ptr = _handle(&i)
  1301. case u32le: ptr = _handle(&i)
  1302. case u64le: ptr = _handle(&i)
  1303. case i16le: ptr = _handle(&i)
  1304. case i32le: ptr = _handle(&i)
  1305. case i64le: ptr = _handle(&i)
  1306. case u16be: ptr = _handle(&i)
  1307. case u32be: ptr = _handle(&i)
  1308. case u64be: ptr = _handle(&i)
  1309. case i16be: ptr = _handle(&i)
  1310. case i32be: ptr = _handle(&i)
  1311. case i64be: ptr = _handle(&i)
  1312. }
  1313. return ptr
  1314. }
  1315. @(require_results)
  1316. as_pointer :: proc(a: any) -> (value: rawptr, valid: bool) {
  1317. if a == nil { return }
  1318. a := a
  1319. ti := runtime.type_info_core(type_info_of(a.id))
  1320. a.id = ti.id
  1321. #partial switch info in ti.variant {
  1322. case Type_Info_Pointer:
  1323. valid = true
  1324. value = (^rawptr)(a.data)^
  1325. case Type_Info_String:
  1326. valid = true
  1327. switch v in a {
  1328. case cstring: value = rawptr(v)
  1329. case: valid = false
  1330. }
  1331. case Type_Info_Relative_Pointer:
  1332. valid = true
  1333. value = relative_pointer_to_absolute_raw(a.data, info.base_integer.id)
  1334. }
  1335. return
  1336. }
  1337. @(require_results)
  1338. as_raw_data :: proc(a: any) -> (value: rawptr, valid: bool) {
  1339. if a == nil { return }
  1340. a := a
  1341. ti := runtime.type_info_core(type_info_of(a.id))
  1342. a.id = ti.id
  1343. #partial switch info in ti.variant {
  1344. case Type_Info_String:
  1345. valid = true
  1346. switch v in a {
  1347. case string: value = raw_data(v)
  1348. case cstring: value = rawptr(v) // just in case
  1349. case: valid = false
  1350. }
  1351. case Type_Info_Array:
  1352. valid = true
  1353. value = a.data
  1354. case Type_Info_Slice:
  1355. valid = true
  1356. value = (^runtime.Raw_Slice)(a.data).data
  1357. case Type_Info_Dynamic_Array:
  1358. valid = true
  1359. value = (^runtime.Raw_Dynamic_Array)(a.data).data
  1360. }
  1361. return
  1362. }
  1363. eq :: equal
  1364. ne :: not_equal
  1365. DEFAULT_EQUAL_MAX_RECURSION_LEVEL :: 32
  1366. @(require_results)
  1367. not_equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_level := 0) -> bool {
  1368. return !equal(a, b, including_indirect_array_recursion, recursion_level)
  1369. }
  1370. @(require_results)
  1371. equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_level := 0) -> bool {
  1372. if a == nil && b == nil {
  1373. return true
  1374. }
  1375. if a.id != b.id {
  1376. return false
  1377. }
  1378. if a.data == b.data {
  1379. return true
  1380. }
  1381. including_indirect_array_recursion := including_indirect_array_recursion
  1382. if recursion_level >= DEFAULT_EQUAL_MAX_RECURSION_LEVEL {
  1383. including_indirect_array_recursion = false
  1384. }
  1385. t := type_info_of(a.id)
  1386. if .Comparable not_in t.flags && !including_indirect_array_recursion {
  1387. return false
  1388. }
  1389. if t.size == 0 {
  1390. return true
  1391. }
  1392. if .Simple_Compare in t.flags {
  1393. return runtime.memory_compare(a.data, b.data, t.size) == 0
  1394. }
  1395. t = runtime.type_info_core(t)
  1396. switch v in t.variant {
  1397. case Type_Info_Named:
  1398. unreachable()
  1399. case Type_Info_Parameters:
  1400. unreachable()
  1401. case Type_Info_Any:
  1402. if !including_indirect_array_recursion {
  1403. return false
  1404. }
  1405. va := (^any)(a.data)
  1406. vb := (^any)(b.data)
  1407. return equal(va, vb, including_indirect_array_recursion, recursion_level+1)
  1408. case Type_Info_Map:
  1409. return false
  1410. case
  1411. Type_Info_Boolean,
  1412. Type_Info_Integer,
  1413. Type_Info_Rune,
  1414. Type_Info_Float,
  1415. Type_Info_Complex,
  1416. Type_Info_Quaternion,
  1417. Type_Info_Type_Id,
  1418. Type_Info_Pointer,
  1419. Type_Info_Multi_Pointer,
  1420. Type_Info_Procedure,
  1421. Type_Info_Bit_Set,
  1422. Type_Info_Enum,
  1423. Type_Info_Simd_Vector,
  1424. Type_Info_Relative_Pointer,
  1425. Type_Info_Relative_Multi_Pointer,
  1426. Type_Info_Soa_Pointer,
  1427. Type_Info_Matrix:
  1428. return runtime.memory_compare(a.data, b.data, t.size) == 0
  1429. case Type_Info_String:
  1430. if v.is_cstring {
  1431. x := string((^cstring)(a.data)^)
  1432. y := string((^cstring)(b.data)^)
  1433. return x == y
  1434. } else {
  1435. x := (^string)(a.data)^
  1436. y := (^string)(b.data)^
  1437. return x == y
  1438. }
  1439. return true
  1440. case Type_Info_Array:
  1441. for i in 0..<v.count {
  1442. x := rawptr(uintptr(a.data) + uintptr(v.elem_size*i))
  1443. y := rawptr(uintptr(b.data) + uintptr(v.elem_size*i))
  1444. if !equal(any{x, v.elem.id}, any{y, v.elem.id}, including_indirect_array_recursion, recursion_level) {
  1445. return false
  1446. }
  1447. }
  1448. return true
  1449. case Type_Info_Enumerated_Array:
  1450. for i in 0..<v.count {
  1451. x := rawptr(uintptr(a.data) + uintptr(v.elem_size*i))
  1452. y := rawptr(uintptr(b.data) + uintptr(v.elem_size*i))
  1453. if !equal(any{x, v.elem.id}, any{y, v.elem.id}, including_indirect_array_recursion, recursion_level) {
  1454. return false
  1455. }
  1456. }
  1457. return true
  1458. case Type_Info_Struct:
  1459. if v.equal != nil {
  1460. return v.equal(a.data, b.data)
  1461. } else {
  1462. for offset, i in v.offsets[:v.field_count] {
  1463. x := rawptr(uintptr(a.data) + offset)
  1464. y := rawptr(uintptr(b.data) + offset)
  1465. id := v.types[i].id
  1466. if !equal(any{x, id}, any{y, id}, including_indirect_array_recursion, recursion_level) {
  1467. return false
  1468. }
  1469. }
  1470. return true
  1471. }
  1472. case Type_Info_Union:
  1473. if v.equal != nil {
  1474. return v.equal(a.data, b.data)
  1475. }
  1476. return false
  1477. case Type_Info_Slice:
  1478. if !including_indirect_array_recursion {
  1479. return false
  1480. }
  1481. array_a := (^runtime.Raw_Slice)(a.data)
  1482. array_b := (^runtime.Raw_Slice)(b.data)
  1483. if array_a.len != array_b.len {
  1484. return false
  1485. }
  1486. if array_a.data == array_b.data {
  1487. return true
  1488. }
  1489. for i in 0..<array_a.len {
  1490. x := rawptr(uintptr(array_a.data) + uintptr(v.elem_size*i))
  1491. y := rawptr(uintptr(array_b.data) + uintptr(v.elem_size*i))
  1492. if !equal(any{x, v.elem.id}, any{y, v.elem.id}, including_indirect_array_recursion, recursion_level+1) {
  1493. return false
  1494. }
  1495. }
  1496. return true
  1497. case Type_Info_Dynamic_Array:
  1498. if !including_indirect_array_recursion {
  1499. return false
  1500. }
  1501. array_a := (^runtime.Raw_Dynamic_Array)(a.data)
  1502. array_b := (^runtime.Raw_Dynamic_Array)(b.data)
  1503. if array_a.len != array_b.len {
  1504. return false
  1505. }
  1506. if array_a.data == array_b.data {
  1507. return true
  1508. }
  1509. if .Simple_Compare in v.elem.flags {
  1510. return runtime.memory_compare((^byte)(array_a.data), (^byte)(array_b.data), array_a.len * v.elem.size) == 0
  1511. }
  1512. for i in 0..<array_a.len {
  1513. x := rawptr(uintptr(array_a.data) + uintptr(v.elem_size*i))
  1514. y := rawptr(uintptr(array_b.data) + uintptr(v.elem_size*i))
  1515. if !equal(any{x, v.elem.id}, any{y, v.elem.id}, including_indirect_array_recursion, recursion_level+1) {
  1516. return false
  1517. }
  1518. }
  1519. return true
  1520. case Type_Info_Bit_Field:
  1521. x, y := a, b
  1522. x.id = v.backing_type.id
  1523. y.id = v.backing_type.id
  1524. return equal(x, y, including_indirect_array_recursion, recursion_level+0)
  1525. }
  1526. runtime.print_typeid(a.id)
  1527. runtime.print_string("\n")
  1528. return true
  1529. }