nanxing_operator_check.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #ifndef _NANXING_CHECK_OPERATOR_H_
  2. #define _NANXING_CHECK_OPERATOR_H_
  3. #include<type_traits>
  4. #include<iostream>
  5. //这个文件的目的是为了做一些匹配性检查,检查一些泛型的实例化是否能满足一定的要求
  6. //使用SFINAE
  7. //这个头文件的操作需要编译器至少支持C++11才能用,但是在C++20中引入的约束模板类型已经成功的将这些抽象的操作加入语法中
  8. //由于到目前(2024年10月还有部分编译器的默认支持不是C++20,因此还是保留这个文件)
  9. //当然目前libstdc++中模板的判断还是用类似的方法
  10. #define NANXING_TYPETRAIT_TEMPLATE_T_V_ template<typename T ,typename V =void >
  11. #define NANXING_TYPETRAIT_TEMPLATE_T_ template<typename T >
  12. #define NANXING_BASIC_OPERATOR_(Type, Op) nanxing::Op##_admit<Type>::value //注意要写成这样才行
  13. #define NANXING_OPERATOR_FORBIDEN_(Type,Op) nanxing::Op##_forbiden<Type>::value
  14. namespace nanxing
  15. {
  16. template<typename...> //这里用泛型的作用在于为了后面做模板参数匹配
  17. using void_t=void;
  18. NANXING_TYPETRAIT_TEMPLATE_T_V_
  19. struct add_admit:std::false_type{static void p(){std::cout<<"false"<<std::endl;}}; //基础模板类型
  20. //关于这里需要使用void_t修饰,这个是这样的
  21. //这里实际上是做了一个偏特化,将V进行特化,特化为void_t<decltype(std::declval<T>()+std::declval<T>())>
  22. //当我们使用的时候我们实际上是只传入了一个参数,第二个参数使用默认值void,当且仅当偏特化的特化值为void的时候才能成功匹配
  23. //看下面这个例子即可
  24. // template<typename T,typename V=void>
  25. // struct test{static const int value=0;};
  26. // template<typename T>
  27. // struct test<T,void>{static const int value=1;};
  28. //T能否进行加法运算
  29. NANXING_TYPETRAIT_TEMPLATE_T_
  30. struct add_admit<T,void_t<decltype(std::declval<T>()+std::declval<T>())>>:std::true_type{static void p(){std::cout<<"true"<<std::endl;}};
  31. //T能否进行减法运算
  32. NANXING_TYPETRAIT_TEMPLATE_T_V_
  33. struct mut_admit:std::false_type{};
  34. NANXING_TYPETRAIT_TEMPLATE_T_
  35. struct mut_admit<T,void_t<decltype(std::declval<T>()-std::declval<T>())>>:std::true_type{};
  36. //T能否进行比较
  37. NANXING_TYPETRAIT_TEMPLATE_T_V_
  38. struct compare_admit:std::false_type{};
  39. NANXING_TYPETRAIT_TEMPLATE_T_
  40. struct compare_admit<T,void_t<decltype(std::declval<T>()<std::declval<T>())>>:std::true_type{};
  41. //T能否相互赋值
  42. NANXING_TYPETRAIT_TEMPLATE_T_V_
  43. struct equal_admit:std::false_type{};
  44. NANXING_TYPETRAIT_TEMPLATE_T_
  45. struct equal_admit<T,void_t<decltype(std::declval<T>()=std::declval<T>())>>:std::true_type{};
  46. //T能否下标运算
  47. NANXING_TYPETRAIT_TEMPLATE_T_V_
  48. struct index_admit:std::false_type{};
  49. NANXING_TYPETRAIT_TEMPLATE_T_
  50. struct index_admit<T,void_t<decltype(std::declval<T>()[0])>>:std::true_type{};
  51. //T指向的数据能否进行比较运算
  52. NANXING_TYPETRAIT_TEMPLATE_T_V_
  53. struct compare_ptr_admit:std::false_type{};
  54. NANXING_TYPETRAIT_TEMPLATE_T_
  55. struct compare_ptr_admit<T,void_t<decltype(std::declval<T>()[0]==std::declval<T>()[0])>>:std::true_type{};
  56. //T指向的数据能否相互赋值
  57. NANXING_TYPETRAIT_TEMPLATE_T_V_
  58. struct equal_ptr_admit:std::false_type{};
  59. NANXING_TYPETRAIT_TEMPLATE_T_
  60. struct equal_ptr_admit<T,void_t<decltype(std::declval<T>()[0]=std::declval<T>()[0])>>:std::true_type{};
  61. //T类型可以作为可调用对象进行调用
  62. NANXING_TYPETRAIT_TEMPLATE_T_V_
  63. struct fun_admit:std::false_type{};
  64. NANXING_TYPETRAIT_TEMPLATE_T_
  65. struct fun_admit<T,void_t<decltype((std::declval<T>())())>>:std::true_type{};
  66. //T类型允许从一个T类型的实例构造(即拷贝构造)
  67. NANXING_TYPETRAIT_TEMPLATE_T_V_
  68. struct copy_construct_admit:std::false_type{};
  69. NANXING_TYPETRAIT_TEMPLATE_T_
  70. struct copy_construct_admit<T,void_t<decltype(T(std::declval<T>()))>>:std::true_type{};
  71. //T类型允许强制类型转换为int
  72. NANXING_TYPETRAIT_TEMPLATE_T_V_
  73. struct convert_into_int_admit:std::false_type{};
  74. NANXING_TYPETRAIT_TEMPLATE_T_
  75. struct convert_into_int_admit<T,void_t<decltype(static_cast<int>(std::declval<T>()))>>:std::true_type{};
  76. //判断一些操作是不存在的
  77. //不能存在解引用
  78. NANXING_TYPETRAIT_TEMPLATE_T_V_
  79. struct point_forbiden:std::true_type{};
  80. NANXING_TYPETRAIT_TEMPLATE_T_
  81. struct point_forbiden<T,void_t<decltype(*(std::declval<T>()))>>:std::false_type{};
  82. }
  83. #endif