Advertisement
Tainel

src/base/features/metaprogramming.hpp

Jun 2nd, 2023 (edited)
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.66 KB | Source Code | 0 0
  1. #pragma once
  2.  
  3. #include"base/dependencies/index.hpp"
  4.  
  5. #include"floats.hpp"
  6. #include"integers.hpp"
  7.  
  8. // Type modification from a type to its base version.
  9. template<class Type>struct base{using type=remove_cvref_t<Type>;};
  10. template<class Type>using base_t=base<Type>::type;
  11.  
  12. // Concept for standard integer type aliases.
  13. template<class Type>concept Integer=
  14.     is_same_v<base_t<Type>,s32>||
  15.     is_same_v<base_t<Type>,s64>||
  16.     is_same_v<base_t<Type>,u32>||
  17.     is_same_v<base_t<Type>,u64>;
  18.  
  19. // Concept for all integer type aliases.
  20. template<class Type>concept Whole=
  21.     Integer<Type>||is_same_v<base_t<Type>,s128>||is_same_v<base_t<Type>,u128>;
  22.  
  23. // Concept for all floating point type aliases.
  24. template<class Type>concept Float=
  25.     is_same_v<base_t<Type>,f32>||
  26.     is_same_v<base_t<Type>,f64>||
  27.     is_same_v<base_t<Type>,f80>;
  28.  
  29. // Type modification from a base integer type to its next base version.
  30. template<Integer Int>struct grow_base{using type=void;};
  31. template<>struct grow_base<s32>{using type=s64;};
  32. template<>struct grow_base<s64>{using type=s128;};
  33. template<>struct grow_base<u32>{using type=u64;};
  34. template<>struct grow_base<u64>{using type=u128;};
  35. template<Integer Int>using grow_base_t=grow_base<Int>::type;
  36.  
  37. // Type modification from an integer type to its next base version.
  38. template<Integer Int>struct grow{using type=grow_base_t<base_t<Int>>;};
  39. template<Integer Int>using grow_t=grow<Int>::type;
  40.  
  41. // Type modification from a base integer type to its base signed version.
  42. template<Whole Int>struct sign_base{using type=make_signed_t<Int>;};
  43. template<>struct sign_base<s128>{using type=s128;};
  44. template<>struct sign_base<u128>{using type=s128;};
  45. template<Whole Int>using sign_base_t=sign_base<Int>::type;
  46.  
  47. // Type modification from an integer type to its base signed version.
  48. template<Whole Int>struct sign{using type=sign_base_t<base_t<Int>>;};
  49. template<Whole Int>using sign_t=sign<Int>::type;
  50.  
  51. // Type modification from a base integer type to its base unsigned version.
  52. template<Whole Int>struct unsign_base{using type=make_unsigned_t<Int>;};
  53. template<>struct unsign_base<s128>{using type=u128;};
  54. template<>struct unsign_base<u128>{using type=u128;};
  55. template<Whole Int>using unsign_base_t=unsign_base<Int>::type;
  56.  
  57. // Type modification from an integer type to its base unsigned version.
  58. template<Whole Int>struct unsign{using type=unsign_base_t<base_t<Int>>;};
  59. template<Whole Int>using unsign_t=unsign<Int>::type;
  60.  
  61. // Relative integer type casts.
  62. #define BASE(a)(static_cast<base_t<decltype(a)>>(a))
  63. #define GROW(a)(static_cast<grow_t<decltype(a)>>(a))
  64. #define SIGN(a)(static_cast<sign_t<decltype(a)>>(a))
  65. #define UNSIGN(a)(static_cast<unsign_t<decltype(a)>>(a))
  66.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement