Advertisement
Guest User

Untitled

a guest
May 23rd, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.61 KB | None | 0 0
  1. #include <type_traits>
  2.  
  3. template <class T, std::size_t N>
  4. struct tag {
  5.     friend auto loophole(tag<T,N>);
  6. };
  7.  
  8. template <class T> constexpr T& unsafe_declval_like() noexcept {
  9.     return *std::add_pointer_t<T>{nullptr};
  10. }
  11.  
  12. template <class T, class U, std::size_t N, bool B>
  13. struct fn_def {
  14.     friend auto loophole(tag<T,N>) {
  15.         return ::unsafe_declval_like< std::remove_all_extents_t<U> >(); }
  16. };
  17.  
  18. template <class T, class U, std::size_t N>
  19. struct fn_def<T, U, N, true> {};
  20.  
  21. template <class T, std::size_t N>
  22. struct loophole_ubiq {
  23.     template<class U, std::size_t M>
  24.     static std::size_t ins(...);
  25.    
  26.     template<class U, std::size_t M, std::size_t = sizeof(loophole(tag<T,M>{})) >
  27.     static char ins(int);
  28.  
  29.     template<class U, std::size_t =
  30.                  sizeof(fn_def<T, U, N, sizeof(ins<U, N>(0)) == sizeof(char)>)>
  31.     constexpr operator U&() const noexcept;
  32. };
  33.  
  34. /*****************************/
  35. struct ubiq
  36. {
  37.     template <class T>
  38.     constexpr operator T() const noexcept { return {}; }
  39. };
  40.  
  41. template <typename T>
  42. struct Type {};
  43.  
  44.  
  45. template <class S, typename... l>
  46. struct next_type
  47. {
  48.     using type = void;
  49. };
  50.  
  51. template <class S, typename... l>
  52. requires requires { S{ std::declval<l>()..., ubiq{} }; }
  53. struct next_type<S,l...>
  54. {
  55.     template <std::size_t N>
  56.     struct loophole_type
  57.         : Type< decltype( S{ std::declval<l>()..., loophole_ubiq<S,N>{} }, 0) >
  58.     {
  59.         using type = decltype(loophole(tag<S,N>{}));
  60.     };
  61.  
  62.     // the next member type, or for array member the element type
  63.     using type = typename loophole_type<sizeof...(l)>::type;
  64.  
  65.     template <typename T=type>
  66.     static constexpr bool init_1_brace = requires { S{ std::declval<l>()..., {std::declval<T>()} }; };
  67.  
  68.     static constexpr bool is_array = init_1_brace<type> && !std::is_aggregate_v<type>;
  69. };
  70.  
  71. template <class S, typename... L>
  72. using next_type_t = typename next_type<S,L...>::type;
  73.  
  74. struct A { int a[1]; };
  75. struct B { int a; };
  76. struct C { B b; };
  77. struct D : B {};
  78. struct E : A {};
  79. struct F { int h[1][2]; };
  80.  
  81. static_assert(std::is_same_v< next_type_t<A>, int> &&  next_type<A>::is_array);
  82. static_assert(std::is_same_v< next_type_t<B>, int> && !next_type<B>::is_array);
  83. static_assert(std::is_same_v< next_type_t<C>, B>   && !next_type<C>::is_array);
  84. static_assert(std::is_same_v< next_type_t<D>, B>   && !next_type<D>::is_array);
  85. static_assert(std::is_same_v< next_type_t<E>, A>   && !next_type<E>::is_array);
  86. static_assert(std::is_same_v< next_type_t<F>, int> &&  next_type<F>::is_array);
  87.  
  88. static_assert(std::is_same_v< next_type_t<A,int>, void>);
  89.  
  90. int main() { }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement