72
72
template<class T> struct is_scoped_enum; (NOT-APPLICABLE)
73
73
74
74
// type property queries
75
- template<class T> struct alignment_of; (TODO )
75
+ template<class T> struct alignment_of; (SPECIALIZED FOR REGISTERED TYPES )
76
76
template<class T> struct rank; (DONE)
77
77
template<class T, unsigned I = 0> struct extent; (DONE)
78
78
91
91
template<class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r;
92
92
93
93
// const-volatile modifications
94
- template<class T> struct remove_const; (TODO )
95
- template<class T> struct remove_volatile; (TODO )
96
- template<class T> struct remove_cv; (TODO )
97
- template<class T> struct add_const; (TODO )
98
- template<class T> struct add_volatile; (TODO )
99
- template<class T> struct add_cv; (TODO )
94
+ template<class T> struct remove_const; (DONE )
95
+ template<class T> struct remove_volatile; (DONE )
96
+ template<class T> struct remove_cv; (DONE )
97
+ template<class T> struct add_const; (DONE )
98
+ template<class T> struct add_volatile; (DONE )
99
+ template<class T> struct add_cv; (DONE )
100
100
101
101
// reference modifications
102
- template<class T> struct remove_reference; (TODO )
103
- template<class T> struct add_lvalue_reference; (TODO )
104
- template<class T> struct add_rvalue_reference; (TODO )
102
+ template<class T> struct remove_reference; (DONE )
103
+ template<class T> struct add_lvalue_reference; (DONE BUT DONT USE )
104
+ template<class T> struct add_rvalue_reference; (DONE BUT DONT USE )
105
105
106
106
// sign modifications
107
107
template<class T> struct make_signed; (TODO)
108
108
template<class T> struct make_unsigned; (TODO)
109
109
110
110
// array modifications
111
- template<class T> struct remove_extent; (TODO )
112
- template<class T> struct remove_all_extents; (TODO )
111
+ template<class T> struct remove_extent; (DONE )
112
+ template<class T> struct remove_all_extents; (DONE )
113
113
114
114
// pointer modifications
115
- template<class T> struct remove_pointer; (TODO )
116
- template<class T> struct add_pointer; (TODO )
115
+ template<class T> struct remove_pointer; (NOT-POSSIBLE UNTIL PSUEDO PTRS ARE IMPLEMENTED )
116
+ template<class T> struct add_pointer; (NOT-POSSIBLE UNTIL PSUEDO PTRS ARE IMPLEMENTED )
117
117
118
118
// other transformations
119
119
template<class T> struct type_identity; (DONE)
120
- template<class T> struct remove_cvref; (TODO )
120
+ template<class T> struct remove_cvref; (DONE )
121
121
template<class T> struct decay; (TODO)
122
122
template<bool, class T = void> struct enable_if; (NOT-APPLICABLE)
123
123
template<bool, class T, class F> struct conditional; (DONE)
@@ -166,9 +166,41 @@ struct base_type_forwarder<Trait,matrix<T,N,M> > : Trait<T> {};
166
166
167
167
#if __HLSL_VERSION // HLSL
168
168
169
+
170
+ #define decltype (expr) __decltype (expr)
171
+
172
+ template<class T>
173
+ struct type_identity
174
+ {
175
+ using type = T;
176
+ };
177
+
178
+ namespace impl
179
+ {
180
+ template<class > struct remove_reference;
181
+ }
182
+
183
+ template<class T> struct remove_const : type_identity<T> {};
184
+ template<class T> struct remove_const<const T> : type_identity<T> {};
185
+
186
+ template<class T> struct remove_volatile : type_identity<T> {};
187
+ template<class T> struct remove_volatile<volatile T> : type_identity<T> {};
188
+
189
+ template<class T> struct remove_cv : type_identity<T> {};
190
+ template<class T> struct remove_cv<const T> : type_identity<T> {};
191
+ template<class T> struct remove_cv<volatile T> : type_identity<T> {};
192
+ template<class T> struct remove_cv<const volatile T> : type_identity<T> {};
193
+
194
+ template<class T> struct remove_cvref : remove_cv<typename impl::remove_reference<T>::type> {};
195
+
196
+ template<class T> struct add_const : type_identity<const T> {};
197
+ template<class T> struct add_volatile : type_identity<volatile T> {};
198
+ template<class T> struct add_cv : type_identity<const volatile T> {};
199
+
200
+
169
201
template<class T, T val>
170
202
struct integral_constant {
171
- static const T value = val;
203
+ NBL_CONSTEXPR_STATIC_INLINE T value = val;
172
204
using value_type = T;
173
205
};
174
206
@@ -179,16 +211,10 @@ struct true_type : bool_constant<true> {};
179
211
struct false_type : bool_constant<true > {};
180
212
181
213
template<bool C, class T, class F>
182
- struct conditional
183
- {
184
- using type = T;
185
- };
214
+ struct conditional : type_identity<T> {};
186
215
187
216
template<class T, class F>
188
- struct conditional<false , T, F>
189
- {
190
- using type = F;
191
- };
217
+ struct conditional<false , T, F> : type_identity<F> {};
192
218
193
219
template<bool C, typename T, T A, T B>
194
220
struct conditional_value
@@ -203,8 +229,7 @@ template<class A>
203
229
struct is_same<A,A> : bool_constant<true > {};
204
230
205
231
template<class T>
206
- struct is_void : bool_constant<is_same<T, void >::value> {};
207
-
232
+ struct is_void : bool_constant<is_same<typename remove_cv<T>::type, void >::value> {};
208
233
209
234
template<class T>
210
235
struct is_bounded_array : bool_constant<false > {};
@@ -225,10 +250,7 @@ namespace impl
225
250
{
226
251
227
252
template<typename T, T v>
228
- struct function_info
229
- {
230
- using type = void ;
231
- };
253
+ struct function_info : type_identity<void > {};
232
254
233
255
template<class T>
234
256
struct is_unsigned : bool_constant<
@@ -267,21 +289,21 @@ struct is_signed : bool_constant<
267
289
}
268
290
269
291
template<class T>
270
- struct is_unsigned : impl::base_type_forwarder<impl::is_unsigned, T > {};
292
+ struct is_unsigned : impl::base_type_forwarder<impl::is_unsigned, typename remove_cv<T>::type > {};
271
293
272
294
template<class T>
273
- struct is_integral : impl::base_type_forwarder<impl::is_integral, T > {};
295
+ struct is_integral : impl::base_type_forwarder<impl::is_integral, typename remove_cv<T>::type > {};
274
296
275
297
template<class T>
276
- struct is_floating_point : impl::base_type_forwarder<impl::is_floating_point, T > {};
298
+ struct is_floating_point : impl::base_type_forwarder<impl::is_floating_point, typename remove_cv<T>::type > {};
277
299
278
300
template<class T>
279
- struct is_signed : impl::base_type_forwarder<impl::is_signed, T > {};
301
+ struct is_signed : impl::base_type_forwarder<impl::is_signed, typename remove_cv<T>::type > {};
280
302
281
303
template<class T>
282
304
struct is_scalar : bool_constant<
283
- impl::is_integral<T >::value ||
284
- impl::is_floating_point<T >::value
305
+ impl::is_integral<typename remove_cv<T>::type >::value ||
306
+ impl::is_floating_point<typename remove_cv<T>::type >::value
285
307
> {};
286
308
287
309
template<class T>
@@ -327,12 +349,6 @@ struct is_compound : bool_constant<!is_fundamental<T>::value> {};
327
349
template <class T>
328
350
struct is_aggregate : is_compound<T> {};
329
351
330
- template<class T>
331
- struct type_identity
332
- {
333
- using type = T;
334
- };
335
-
336
352
template<class T>
337
353
struct rank : integral_constant<uint64_t, 0 > { };
338
354
@@ -358,15 +374,106 @@ template<bool B, class T = void>
358
374
struct enable_if {};
359
375
360
376
template<class T>
361
- struct enable_if<true , T>
362
- {
363
- using type = T;
364
- };
377
+ struct enable_if<true , T> : type_identity<T> {};
365
378
366
379
// need this crutch because we can't make `#define typeid` work both on expression and types
367
380
template<typename T>
368
381
struct typeid_t;
369
382
383
+ template<class T>
384
+ struct alignment_of;
385
+
386
+
387
+ // reference stuff needed for semantics
388
+
389
+ // not for "human consumption"
390
+ // dxc doesnt actually allow variables to be references
391
+ // every reference is treated as having 'restrict' qualifier
392
+ // https://godbolt.org/z/dsj99fY96
393
+ namespace impl
394
+ {
395
+
396
+ template<class >
397
+ struct make_void { using type = void ; };
398
+
399
+ template<typename,class =void >
400
+ struct is_reference : bool_constant<true > { };
401
+
402
+ template<typename T>
403
+ struct is_reference<T,typename make_void<T[1 ]>::type> : bool_constant<false > { };
404
+
405
+ template<class T>
406
+ struct declval
407
+ {
408
+ static T member[1 ];
409
+ using reference_type = decltype (member[0 ]);
410
+ };
411
+
412
+ template<class T>
413
+ struct add_lvalue_reference :
414
+ conditional<
415
+ is_reference<T>::value,
416
+ T,
417
+ typename declval<T>::reference_type>
418
+ {
419
+ };
420
+
421
+ template<typename T>
422
+ T remove_reference_impl (T v)
423
+ {
424
+ return v;
425
+ }
426
+
427
+ template<typename T>
428
+ struct remove_reference_helper
429
+ {
430
+ static T member;
431
+ using type = decltype (remove_reference_impl (member));
432
+ };
433
+
434
+ template<typename T>
435
+ struct remove_reference : conditional<is_reference<T>::value, typename remove_reference_helper<T>::type, T> {};
436
+
437
+ }
438
+
439
+ template<class T> struct remove_extent : type_identity<T> {};
440
+ template<class T, uint32_t I> struct remove_extent<T[I]> : type_identity<T> {};
441
+ template<class T> struct remove_extent<T[]> : type_identity<T> {};
442
+
443
+ template <class T>
444
+ struct remove_all_extents : type_identity<T> {};
445
+
446
+ template <class T, uint32_t I>
447
+ struct remove_all_extents<T[I]> : type_identity<typename remove_all_extents<T>::type> {};
448
+
449
+ template <class T>
450
+ struct remove_all_extents<T[]> : type_identity<typename remove_all_extents<T>::type> {};
451
+
452
+ namespace impl
453
+ {
454
+
455
+ template<uint32_t sz> struct int_type :
456
+ conditional<8 ==sz, int64_t, typename conditional<4 ==sz, int32_t, int16_t>::type>{};
457
+
458
+ template<uint32_t sz> struct uint_type :
459
+ type_identity<unsigned typename int_type<sz>::type> {};
460
+ }
461
+
462
+ template<class T>
463
+ struct make_signed : impl::int_type<sizeof (T)>
464
+ {
465
+ _Static_assert (is_integral<T>::value && !is_same<typename remove_cv<T>::type, bool >::value,
466
+ "make_signed<T> requires that T shall be a (possibly cv-qualified) "
467
+ "integral type or enumeration but not a bool type." );
468
+ };
469
+
470
+ template<class T>
471
+ struct make_unsigned : impl::uint_type<sizeof (T)>
472
+ {
473
+ _Static_assert (is_integral<T>::value && !is_same<typename remove_cv<T>::type, bool >::value,
474
+ "make_unsigned<T> requires that T shall be a (possibly cv-qualified) "
475
+ "integral type or enumeration but not a bool type." );
476
+ };
370
477
371
478
#else // C++
372
479
@@ -457,6 +564,25 @@ struct typeid_t : std::integral_constant<uint64_t,typeid(T).hash_code()> {};
457
564
template<bool B, class T = void >
458
565
using enable_if = std::enable_if<B, T>;
459
566
567
+ template<class T>
568
+ using alignment_of = std::alignment_of<T>;
569
+
570
+ template<class T> using remove_const = std::remove_const<T>;
571
+ template<class T> using remove_volatile = std::remove_volatile<T>;
572
+ template<class T> using remove_cv = std::remove_cv<T>;
573
+ template<class T> using add_const = std::add_const<T>;
574
+ template<class T> using add_volatile = std::add_volatile<T>;
575
+ template<class T> using add_cv = std::add_cv<T>;
576
+
577
+ template<class T> using remove_extent = std::remove_extent<T>;
578
+ template<class T> using remove_all_extents = std::remove_all_extents<T>;
579
+
580
+ template<class T>
581
+ using make_signed = std::make_signed<T>;
582
+
583
+ template<class T>
584
+ using make_unsigned = std::make_unsigned<T>;
585
+
460
586
#endif
461
587
462
588
// Overlapping definitions
@@ -494,16 +620,22 @@ struct scalar_type<matrix<T,N,M> >
494
620
}
495
621
}
496
622
497
-
498
623
// deal with typetraits, for now we rely on Clang/DXC internal __decltype(), if it breaks we revert to commit e4ab38ca227b15b2c79641c39161f1f922b779a3
499
624
#ifdef __HLSL_VERSION
500
625
626
+ #define alignof (expr) ::nbl::hlsl::alignment_of<__decltype (expr)>::value
501
627
502
- #define decltype (expr) __decltype (expr)
503
628
// shoudl really return a std::type_info like struct or something, but no `constexpr` and unsure whether its possible to have a `const static SomeStruct` makes it hard to do...
504
- #define typeid (expr) (typeid_t<decltype (expr)>::value)
629
+ #define typeid (expr) (typeid_t<__decltype (expr)>::value)
630
+
631
+ #define NBL_REGISTER_OBJ_TYPE (T, A) namespace nbl { namespace hlsl { \
632
+ template<> struct typeid_t<T> : integral_constant<uint32_t,__COUNTER__> {}; \
633
+ template<> struct alignment_of<T> : integral_constant<uint32_t,A> {}; \
634
+ template<> struct alignment_of<const T> : integral_constant<uint32_t,A> {}; \
635
+ template<> struct alignment_of<typename impl::add_lvalue_reference<T>::type> : integral_constant<uint32_t,A> {}; \
636
+ template<> struct alignment_of<typename impl::add_lvalue_reference<const T>::type> : integral_constant<uint32_t,A> {}; \
637
+ }}
505
638
506
- #define NBL_REGISTER_OBJ_TYPE (T) namespace nbl { namespace hlsl { template<> struct typeid_t<T> : integral_constant<uint32_t,__COUNTER__> {}; }}
507
639
// TODO: find out how to do it such that we don't get duplicate definition if we use two function identifiers with same signature
508
640
#define NBL_REGISTER_FUN_TYPE (fn) namespace nbl { namespace hlsl { template<> struct typeid_t<__decltype (fn)> : integral_constant<uint32_t,__COUNTER__> {}; }}
509
641
// TODO: ideally we'd like to call NBL_REGISTER_FUN_TYPE under the hood, but we can't right now. Also we have a bigger problem, the passing of the function identifier as the second template parameter doesn't work :(
@@ -517,18 +649,17 @@ struct function_info<__decltype(fn),fn> \
517
649
}}}}
518
650
*/
519
651
520
-
521
652
// builtins
522
653
523
654
#define NBL_REGISTER_MATRICES (T) \
524
- NBL_REGISTER_OBJ_TYPE (T) \
525
- NBL_REGISTER_OBJ_TYPE (T ## x4) \
526
- NBL_REGISTER_OBJ_TYPE (T ## x3) \
527
- NBL_REGISTER_OBJ_TYPE (T ## x2) \
655
+ NBL_REGISTER_OBJ_TYPE (T, sizeof (T) ) \
656
+ NBL_REGISTER_OBJ_TYPE (T ## x4, sizeof (T) ) \
657
+ NBL_REGISTER_OBJ_TYPE (T ## x3, sizeof (T) ) \
658
+ NBL_REGISTER_OBJ_TYPE (T ## x2, sizeof (T) ) \
528
659
529
660
#define NBL_REGISTER_TYPES_FOR_SCALAR (T) \
530
- NBL_REGISTER_OBJ_TYPE (T) \
531
- NBL_REGISTER_OBJ_TYPE (T ## 1 ) \
661
+ NBL_REGISTER_OBJ_TYPE (T, sizeof (T) ) \
662
+ NBL_REGISTER_OBJ_TYPE (T ## 1 , sizeof (T) ) \
532
663
NBL_REGISTER_MATRICES (T ## 2 ) \
533
664
NBL_REGISTER_MATRICES (T ## 3 ) \
534
665
NBL_REGISTER_MATRICES (T ## 4 )
0 commit comments