fork download
  1. #include <type_traits>
  2.  
  3. template <int...> struct indexes {};
  4.  
  5. namespace {
  6. template<int a, int... other>
  7. constexpr indexes<a, other...> combine(indexes<other...> deduce);
  8.  
  9. template<int a, int b, typename Enable = void> struct expand_span_; // primary
  10.  
  11. template<int a, int b>
  12. struct expand_span_<a, b, typename std::enable_if< (a==b), void >::type> {
  13. static constexpr indexes<a> dispatch();
  14. };
  15.  
  16. template<int a, int b>
  17. struct expand_span_<a, b, typename std::enable_if< (a<b), void >::type> {
  18. static constexpr decltype(combine<a>(expand_span_<a+1, b>::dispatch()))
  19. dispatch();
  20. };
  21.  
  22. template<int a, int b>
  23. constexpr auto expand_span() -> decltype(expand_span_<a,b>::dispatch());
  24. }
  25.  
  26. template <int a, int b> using span = decltype(expand_span<a,b>());
  27.  
  28. ////////////////////////////////////////////////////////////////
  29. // using indirect template arguments
  30. template<typename> struct indirect_work { };
  31.  
  32. void test_indirect()
  33. {
  34. indirect_work<indexes<1,2,3,4>> x;
  35. indirect_work<span<1,4>> y;
  36.  
  37. x = y; // x and y are of identical types
  38. static_assert(std::is_same<indexes<1,2,3,4>, span<1,4>>::value, "fact check");
  39. }
  40.  
  41. ////////////////////////////////////////////////////////////////
  42. // using direct template arguments
  43. template<int...> struct direct_work { };
  44.  
  45. // deduction alias:
  46. template<int... direct> constexpr direct_work<direct...> deduction_helper(indexes<direct...>);
  47. template <typename Idx> using deduce = decltype(deduction_helper(Idx{}));
  48.  
  49. void test_direct()
  50. {
  51. direct_work<1,2,3,4> x;
  52. deduce<indexes<1,2,3,4>> y;
  53. deduce<span<1,4>> z;
  54.  
  55. static_assert(std::is_same<decltype(x), decltype(y)>::value, "fact check");
  56. static_assert(std::is_same<decltype(x), decltype(z)>::value, "fact check");
  57. }
  58.  
  59. int main()
  60. {
  61. test_indirect();
  62. test_direct();
  63. }
  64.  
Success #stdin #stdout 0s 2892KB
stdin
Standard input is empty
stdout
Standard output is empty