has_binary_operators.hpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // (C) Copyright Frederic Bron 2009-2011.
  2. // Use, modification and distribution are subject to the
  3. // Boost Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. // It would be nice to get rid of the unnamed namespace here,
  6. // but for now we just turn off inspection reporting :(
  7. // boostinspect:nounnamed
  8. #ifndef TT_HAS_BINARY_OPERATORS_HPP
  9. #define TT_HAS_BINARY_OPERATORS_HPP
  10. #if defined(__GNUC__) && (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ > 40900)
  11. #pragma GCC diagnostic push
  12. #pragma GCC diagnostic ignored "-Wunused-function"
  13. #endif
  14. // test with one template parameter
  15. #define TEST_T(TYPE,RESULT) BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME<TYPE>::value), RESULT)
  16. // test with one template parameter plus return value
  17. #define TEST_TR(TYPE,RET,RESULT) BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME<TYPE,TYPE,RET>::value), RESULT)
  18. // test with two template parameters
  19. #define TEST_TT(TYPE1,TYPE2,RESULT) BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME<TYPE1,TYPE2>::value), RESULT)
  20. // test with two template parameters plus return value
  21. #define TEST_TTR(TYPE1,TYPE2,RET,RESULT) BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME<TYPE1,TYPE2,RET>::value), RESULT)
  22. namespace {
  23. struct without { };
  24. struct ret { };
  25. struct internal { ret operator BOOST_TT_TRAIT_OP (const internal&) const; };
  26. struct external { };
  27. inline ret operator BOOST_TT_TRAIT_OP (const external&, const external&) { return ret(); }
  28. struct comma1_ret { };
  29. struct ret_with_comma1 { comma1_ret operator,(int); };
  30. struct internal_comma1 { ret_with_comma1 operator BOOST_TT_TRAIT_OP (const internal_comma1&) const; };
  31. struct external_comma1 { };
  32. ret_with_comma1 operator BOOST_TT_TRAIT_OP (const external_comma1&, const external_comma1&) { return ret_with_comma1(); }
  33. struct ret_with_comma2 { void operator,(int); };
  34. struct internal_comma2 { ret_with_comma2 operator BOOST_TT_TRAIT_OP (const internal_comma2&) const; };
  35. struct external_comma2 { };
  36. ret_with_comma2 operator BOOST_TT_TRAIT_OP (const external_comma2&, const external_comma2&){ return ret_with_comma2(); }
  37. struct returns_int { int operator BOOST_TT_TRAIT_OP (const returns_int&); };
  38. struct returns_void { void operator BOOST_TT_TRAIT_OP (const returns_void&); };
  39. struct returns_void_star { void *operator BOOST_TT_TRAIT_OP (const returns_void_star&); };
  40. struct returns_double { double operator BOOST_TT_TRAIT_OP (const returns_double&); };
  41. struct ret1 { };
  42. struct convertible_to_ret1 { operator ret1 () const; };
  43. struct returns_convertible_to_ret1 { convertible_to_ret1 operator BOOST_TT_TRAIT_OP (const returns_convertible_to_ret1&); };
  44. struct convertible_to_ret2 { };
  45. struct ret2 { ret2(const convertible_to_ret2); };
  46. struct returns_convertible_to_ret2 { convertible_to_ret2 operator BOOST_TT_TRAIT_OP (const returns_convertible_to_ret2&); };
  47. class Base1 { };
  48. class Derived1 : public Base1 { };
  49. bool operator BOOST_TT_TRAIT_OP (const Base1&, const Base1&) { return true; }
  50. class Base2 { };
  51. struct Derived2 : public Base2 {
  52. Derived2(int); // to check if it works with a class that is not default constructible
  53. };
  54. bool operator BOOST_TT_TRAIT_OP (const Derived2&, const Derived2&) { return true; }
  55. struct tag { };
  56. struct A { };
  57. struct B : public A { };
  58. struct C { };
  59. struct D { };
  60. inline bool operator BOOST_TT_TRAIT_OP (const C&, void*) { return true; }
  61. inline bool operator BOOST_TT_TRAIT_OP (void*, const D&) { return true; }
  62. inline bool operator BOOST_TT_TRAIT_OP (const C&, const D&) { return true; }
  63. struct private_op { private: void operator BOOST_TT_TRAIT_OP (const private_op&) {} };
  64. struct ambiguous_A
  65. {
  66. };
  67. inline bool operator BOOST_TT_TRAIT_OP (const ambiguous_A&, const ambiguous_A&) { return true; }
  68. struct ambiguous_B { operator ambiguous_A()const { return ambiguous_A(); } };
  69. //class internal_private { ret operator BOOST_TT_TRAIT_OP (const internal_private&) const; };
  70. void common() {
  71. TEST_T(void, false);
  72. TEST_TT(void, void, false);
  73. TEST_TTR(void, void, void, false);
  74. TEST_TTR(void, void, int, false);
  75. TEST_T(without, false);
  76. TEST_T(internal, true);
  77. TEST_T(external, true);
  78. TEST_T(internal_comma1, true);
  79. TEST_T(external_comma1, true);
  80. TEST_T(internal_comma2, true);
  81. TEST_T(external_comma2, true);
  82. TEST_T(returns_int, true);
  83. TEST_T(returns_void, true);
  84. TEST_T(returns_void_star, true);
  85. TEST_T(returns_double, true);
  86. TEST_T(returns_convertible_to_ret1, true);
  87. TEST_T(returns_convertible_to_ret2, true);
  88. TEST_T(Base1, true);
  89. TEST_T(Derived1, true);
  90. TEST_T(Base2, false);
  91. TEST_T(Derived2, true);
  92. TEST_TR(without, void, false);
  93. TEST_TR(without, bool, false);
  94. TEST_TR(internal, void, false);
  95. TEST_TR(internal, bool, false);
  96. TEST_TR(internal, ret, true);
  97. TEST_TR(internal_comma1, void, false);
  98. TEST_TR(internal_comma1, bool, false);
  99. TEST_TR(internal_comma1, ret_with_comma1, true);
  100. TEST_TR(internal_comma2, void, false);
  101. TEST_TR(internal_comma2, bool, false);
  102. TEST_TR(internal_comma2, ret_with_comma2, true);
  103. TEST_TR(external, void, false);
  104. TEST_TR(external, bool, false);
  105. TEST_TR(external, ret, true);
  106. TEST_TR(returns_int, void, false);
  107. TEST_TR(returns_int, bool, true);
  108. TEST_TR(returns_int, int, true);
  109. TEST_TR(returns_void, void, true);
  110. TEST_TR(returns_void, bool, false);
  111. TEST_TR(returns_void_star, bool, true);
  112. TEST_TR(returns_double, void, false);
  113. TEST_TR(returns_double, bool, true);
  114. TEST_TR(returns_double, double, true);
  115. TEST_TR(returns_convertible_to_ret1, void, false);
  116. TEST_TR(returns_convertible_to_ret1, ret1, true);
  117. TEST_TR(returns_convertible_to_ret2, ret2, true);
  118. TEST_TR(Base1, bool, true);
  119. TEST_TR(Derived1, bool, true);
  120. TEST_TR(Base2, bool, false);
  121. TEST_TR(Derived2, bool, true);
  122. // compile time error
  123. // TEST_T(internal_private, false);
  124. #if defined(BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION)
  125. // There are some things that pass that wouldn't otherwise do so:
  126. #if !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
  127. TEST_TR(private_op, bool, false);
  128. TEST_T(private_op, false);
  129. #endif
  130. TEST_TR(ambiguous_A, bool, true);
  131. TEST_T(ambiguous_A, true);
  132. TEST_TR(ambiguous_B, bool, true);
  133. TEST_T(ambiguous_B, true);
  134. #endif
  135. }
  136. }
  137. #if defined(__GNUC__) && (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ > 40900)
  138. #pragma GCC diagnostic pop
  139. #endif
  140. #endif