Dukales

"is explicit convertible" type trait

Jun 3rd, 2013
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.85 KB | None | 0 0
  1. #!/usr/bin/env bash -vex
  2. WARN="-W -Wall -Wextra -Werror"
  3. g++ -x c++ - -std=gnu++1y $WARN -Ofast -o a <<__EOF && ./a && echo -e "\e[1;32msucceeded\e[0m" || echo -e "\e[1;31mfailed\e[0m"
  4. // http://stackoverflow.com/questions/16893992/
  5. #include <type_traits>
  6.  
  7. #include <cstdlib>
  8.  
  9. #if 0
  10. using A = float;
  11. using B = double;
  12. using C = long double;
  13. #elif 0
  14. struct A { A() = delete; ~A() = delete; A(A const &) = delete; A(A &&) = delete; A & operator = (A const &) = delete; A & operator = (A &&) = delete; };
  15. struct B { B() = delete; ~B() = delete; B(B const &) = delete; B(B &&) = delete; B & operator = (B const &) = delete; B & operator = (B &&) = delete; };
  16. struct C { C() = delete; ~C() = delete; C(C const &) = delete; C(C &&) = delete; C & operator = (C const &) = delete; C & operator = (C &&) = delete; };
  17. #elif 1
  18. struct A {};
  19. struct B {};
  20. struct C {};
  21. #endif
  22.  
  23. struct AA
  24. {
  25.     explicit operator A const & () const;
  26.     explicit operator A & ();
  27.     explicit operator B (); // note '=9.a' below
  28. };
  29.  
  30. struct BB
  31. {
  32.     explicit operator B const & () const;
  33.     explicit operator B & ();
  34.     explicit operator A () const; // note '=9.c' below
  35. };
  36.  
  37. struct CC
  38. {
  39.     explicit operator C const & () const;
  40.     explicit operator C & ();
  41. };
  42.  
  43. #if 0
  44. template< typename From, typename To, typename Enabler = void >
  45. struct is_explicitly_convertible
  46.     : std::false_type
  47. {
  48.  
  49. };
  50.  
  51. namespace details
  52. {
  53.  
  54. template< typename T >
  55. auto retval() -> T;
  56.  
  57. }
  58.  
  59. template< typename From, typename To >
  60. struct is_explicitly_convertible< From, To, typename std::enable_if< (std::is_fundamental< typename std::remove_reference< From >::type >::value && std::is_fundamental< typename std::remove_reference< decltype(static_cast< To >(details::retval< From >())) >::type >::value) >::type >
  61.     : std::true_type
  62. {
  63.  
  64. };
  65.  
  66. template< typename From, typename To >
  67. struct is_explicitly_convertible< From, To, typename std::enable_if< std::is_member_function_pointer< decltype(&std::remove_reference< From >::type::operator To) >::value >::type >
  68.     : std::integral_constant< bool, ((std::is_const< typename std::remove_reference< From >::type >::value && std::is_same< To (std::remove_reference< From >::type::*)() const, decltype(&std::remove_reference< From >::type::operator To) >::value) || !std::is_const< typename std::remove_reference< From >::type >::value) && (!std::is_lvalue_reference< To >::value || std::is_const< typename std::remove_reference< To >::type >::value || !std::is_const< typename std::remove_reference< From >::type >::value) >
  69. {
  70.  
  71. };
  72. #elif 0
  73. template< typename From, typename To, typename Enabler = void >
  74. struct is_explicitly_convertible
  75.     : std::false_type
  76. {
  77.  
  78. };
  79.  
  80. template< typename From, typename To >
  81. struct is_explicitly_convertible< From, To, typename std::conditional< true, void, decltype(static_cast< To >(std::declval< From >())) >::type >
  82.     : std::true_type
  83. {
  84.  
  85. };
  86. #elif 0
  87. template< class U, class T >
  88. struct is_explicitly_convertible
  89. {    
  90.     enum : bool { value = (std::is_constructible< T, U >::value && !std::is_convertible< U, T >::value) };
  91. };
  92. #elif 1
  93. template< typename From, typename To >
  94. struct is_explicitly_convertible
  95.     : std::is_constructible< To, From >
  96. {
  97.  
  98. };
  99. #endif
  100.  
  101. namespace
  102. {
  103.  
  104. static_assert(is_explicitly_convertible< double, double >::value, "1");
  105. static_assert(is_explicitly_convertible< double &, double >::value, "2");
  106. static_assert(is_explicitly_convertible< double const, double >::value, "3");
  107. static_assert(is_explicitly_convertible< double const &, double >::value, "4");
  108.  
  109. static_assert(is_explicitly_convertible< double, double const & >::value, "5");
  110. static_assert(is_explicitly_convertible< double &, double const & >::value, "6");
  111. static_assert(is_explicitly_convertible< double const, double const & >::value, "7");
  112. static_assert(is_explicitly_convertible< double const &, double const & >::value, "8");
  113.  
  114. static_assert(!is_explicitly_convertible< double, double & >::value, "9"); // not a ref
  115. static_assert(is_explicitly_convertible< double &, double & >::value, "10");
  116. static_assert(!is_explicitly_convertible< double const, double & >::value, "11");
  117. static_assert(!is_explicitly_convertible< double const &, double & >::value, "12");
  118.  
  119. static_assert(is_explicitly_convertible< double, double const >::value, "13");
  120. static_assert(is_explicitly_convertible< double &, double const >::value, "14");
  121. static_assert(is_explicitly_convertible< double const, double const >::value, "15");
  122. static_assert(is_explicitly_convertible< double const &, double const >::value, "16");
  123.  
  124. static_assert(is_explicitly_convertible< AA const &, A const & >::value, "=&1.a");
  125. static_assert(is_explicitly_convertible< CC const &, C const & >::value, "=&1.b");
  126. static_assert(is_explicitly_convertible< BB const &, B const & >::value, "=&1.c");
  127. static_assert(!is_explicitly_convertible< AA const &, A & >::value, "&1.a");
  128. static_assert(!is_explicitly_convertible< CC const &, C & >::value, "&1.b");
  129. static_assert(!is_explicitly_convertible< BB const &, B & >::value, "&1.c");
  130.  
  131. static_assert(is_explicitly_convertible< AA const, A const & >::value, "=1.a");
  132. static_assert(is_explicitly_convertible< CC const, C const & >::value, "=1.b");
  133. static_assert(is_explicitly_convertible< BB const, B const & >::value, "=1.c");
  134. //static_assert(!is_explicitly_convertible< AA const, A >::value, "=2.a"); // ???????????????
  135. //static_assert(!is_explicitly_convertible< CC const, C >::value, "=2.b");
  136. //static_assert(!is_explicitly_convertible< BB const, B >::value, "=2.c");
  137. static_assert(!is_explicitly_convertible< AA const, A & >::value, "=3.a"); // good!
  138. static_assert(!is_explicitly_convertible< CC const, C & >::value, "=3.b"); //
  139. static_assert(!is_explicitly_convertible< BB const, B & >::value, "=3.c"); //
  140. static_assert(!is_explicitly_convertible< AA const, A && >::value, "=4.a"); // not interesting
  141. static_assert(!is_explicitly_convertible< CC const, C && >::value, "=4.b"); //
  142. static_assert(!is_explicitly_convertible< BB const, B && >::value, "=4.c"); //
  143. static_assert(!is_explicitly_convertible< AA const, B const & >::value, "=5.a");
  144. static_assert(!is_explicitly_convertible< AA const, C const & >::value, "=5.b");
  145. static_assert(!is_explicitly_convertible< BB const, A const & >::value, "=5.c");
  146. static_assert(!is_explicitly_convertible< BB const, C const & >::value, "=6.a");
  147. static_assert(!is_explicitly_convertible< CC const, A const & >::value, "=6.b");
  148. static_assert(!is_explicitly_convertible< CC const, B const & >::value, "=6.c");
  149. static_assert(!is_explicitly_convertible< AA const, B & >::value, "=7.a");
  150. static_assert(!is_explicitly_convertible< AA const, C & >::value, "=7.b");
  151. static_assert(!is_explicitly_convertible< BB const, A & >::value, "=7.c");
  152. static_assert(!is_explicitly_convertible< BB const, C & >::value, "=8.a");
  153. static_assert(!is_explicitly_convertible< CC const, A & >::value, "=8.b");
  154. static_assert(!is_explicitly_convertible< CC const, B & >::value, "=8.c");
  155. static_assert(!is_explicitly_convertible< AA const, B >::value, "=9.a"); // very subtle moment (see class AA above)
  156. static_assert(!is_explicitly_convertible< AA const, C >::value, "=9.b");
  157. static_assert(is_explicitly_convertible< BB const, A >::value == std::is_constructible< A, A && >::value, "=9.c"); // (see class BB above)
  158. static_assert(!is_explicitly_convertible< BB const, C >::value, "=10.a");
  159. static_assert(!is_explicitly_convertible< CC const, A >::value, "=10.b");
  160. static_assert(!is_explicitly_convertible< CC const, B >::value, "=10.c");
  161.  
  162. static_assert(is_explicitly_convertible< AA, A & >::value, "~1.a");
  163. static_assert(is_explicitly_convertible< CC, C & >::value, "~1.b");
  164. static_assert(is_explicitly_convertible< BB, B & >::value, "~1.c");
  165. //static_assert(!is_explicitly_convertible< AA, A >::value, "~2.a"); // ???????????????
  166. //static_assert(!is_explicitly_convertible< CC, C >::value, "~2.b");
  167. //static_assert(!is_explicitly_convertible< BB, B >::value, "~2.c");
  168. static_assert(is_explicitly_convertible< AA, A const & >::value, "~3.a"); // convertible
  169. static_assert(is_explicitly_convertible< CC, C const & >::value, "~3.b"); //
  170. static_assert(is_explicitly_convertible< BB, B const & >::value, "~3.c"); //
  171. static_assert(!is_explicitly_convertible< AA, B const & >::value, "~4.a");
  172. static_assert(!is_explicitly_convertible< AA, C const & >::value, "~4.b");
  173. static_assert(!is_explicitly_convertible< BB, A const & >::value, "~4.c");
  174. static_assert(!is_explicitly_convertible< BB, C const & >::value, "~5.a");
  175. static_assert(!is_explicitly_convertible< CC, A const & >::value, "~5.b");
  176. static_assert(!is_explicitly_convertible< CC, B const & >::value, "~5.c");
  177.  
  178. static_assert(std::is_convertible< double, double const & >::value, "5*");
  179. static_assert(!std::is_convertible< double, double & >::value, "9*");
  180.  
  181. }
  182.  
  183. struct X { X(X &&) = delete; }; struct Y { explicit operator X (); }; static_assert(!is_explicitly_convertible< Y, X >::value, "?");
  184.  
  185. int main()
  186. {
  187.     return EXIT_SUCCESS;
  188. }
  189. __EOF
Advertisement
Add Comment
Please, Sign In to add comment