fork(2) download
  1. #include <utility>
  2. #include <tuple>
  3.  
  4. template <typename T>
  5. struct unqualified { typedef typename std::remove_cv< typename std::remove_reference<T>::type>::type type; };
  6.  
  7. template <typename... T>
  8. struct stuff{ typedef stuff type;/* contains all the types! */ };
  9.  
  10. template <std::size_t...>
  11. struct indices_list { typedef indices_list type; };
  12.  
  13. template <std::size_t N, std::size_t... I>
  14. struct indices : public indices<N-1, N-1, I...> { };
  15.  
  16. template <std::size_t... I>
  17. struct indices<0, I...> : public indices_list<I...>{ };
  18.  
  19. template <typename T>
  20. struct tuple_indices : public indices<std::tuple_size<typename unqualified<T>::type>::value> { };
  21.  
  22. template <typename TStuff>
  23. auto awesome_tuple_dog( TStuff&& ) {
  24. // The first man gets the oyster, the second man gets the shell
  25. return std::tuple<>{};
  26. }
  27.  
  28. template <typename TStuff, typename TFinalTuple>
  29. auto awesome_tuple_dog( TStuff&&, TFinalTuple&& tuple ) {
  30. // A greater Tuple has been born..
  31. return std::forward<TFinalTuple>( tuple );
  32. }
  33.  
  34. template <std::size_t ...I, std::size_t ...J, typename... Indices, typename Tuple0, typename Tuple1, typename... Tuplen>
  35. auto awesome_tuple_dog( stuff<indices_list<I...>, indices_list<J...>, Indices...>, Tuple0&& t0, Tuple1&& t1, Tuplen&&... tn ) {
  36. // We know for a fact that "stuff" has ever single indices list we need, but some of it is hidden
  37. // behind variadics. We need to unpack every single last one of the indices we need and get the 'I...' we need...
  38. return awesome_tuple_dog(
  39. stuff<Indices...>(), // deal with the next set of indices, and use them to unite the lesser tuples!
  40. std::make_tuple( std::get<I>( std::forward<Tuple0>( t0 ) )..., std::get<J>( std::forward<Tuple1>( t1 ) )... ),
  41. std::forward<Tuplen>( tn )... // keep going, consume the inferior tuples!
  42. );
  43. }
  44.  
  45. template <typename... Tuplen>
  46. auto awesome_tuple_cat( Tuplen&&... tn ) {
  47. // It doens't cut it to just have tuple_indices<Tuplen>()..., because that's another variadic who's contents
  48. // are hard to get at in another function. Need to wrap it up in a 'stuff'
  49. //return awesome_tuple_dog( tuple_indices<Tuplen>()..., std::forward<Tuple0>( t0 ), std::forward<Tuple1>( t1 ) );
  50. return awesome_tuple_dog( stuff<typename tuple_indices<Tuplen>::type...>(), std::forward<Tuplen>( tn )... );
  51. }
  52.  
  53. int main () {
  54. std::tuple<bool, char> a;
  55. std::tuple<short, int> b;
  56. std::tuple<long long> c;
  57. struct {} _ = awesome_tuple_cat( );
  58. struct {} __ = awesome_tuple_cat( a, b );
  59. struct {} ___ = awesome_tuple_cat( a, b, c );
  60.  
  61. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:23:34: warning: ‘awesome_tuple_dog’ function uses ‘auto’ type specifier without trailing return type [enabled by default]
 auto awesome_tuple_dog( TStuff&& ) {
                                  ^
prog.cpp:29:55: warning: ‘awesome_tuple_dog’ function uses ‘auto’ type specifier without trailing return type [enabled by default]
 auto awesome_tuple_dog( TStuff&&, TFinalTuple&& tuple ) {
                                                       ^
prog.cpp:35:125: warning: ‘awesome_tuple_dog’ function uses ‘auto’ type specifier without trailing return type [enabled by default]
 auto awesome_tuple_dog( stuff<indices_list<I...>, indices_list<J...>, Indices...>, Tuple0&& t0, Tuple1&& t1, Tuplen&&... tn ) {
                                                                                                                             ^
prog.cpp:46:40: warning: ‘awesome_tuple_cat’ function uses ‘auto’ type specifier without trailing return type [enabled by default]
 auto awesome_tuple_cat( Tuplen&&... tn ) {
                                        ^
prog.cpp: In function ‘int main()’:
prog.cpp:57:38: error: conversion from ‘std::tuple<>’ to non-scalar type ‘main()::<anonymous struct>’ requested
     struct {} _ = awesome_tuple_cat( );
                                      ^
prog.cpp:58:44: error: conversion from ‘std::tuple<bool, char, short int, int>’ to non-scalar type ‘main()::<anonymous struct>’ requested
     struct {} __ = awesome_tuple_cat( a, b );
                                            ^
prog.cpp: In instantiation of ‘auto awesome_tuple_dog(stuff<indices_list<I ...>, indices_list<J ...>, Indices ...>, Tuple0&&, Tuple1&&, Tuplen&& ...) [with unsigned int ...I = {0u, 1u}; unsigned int ...J = {0u, 1u}; Indices = {indices_list<0u>}; Tuple0 = std::tuple<bool, char>&; Tuple1 = std::tuple<short int, int>&; Tuplen = {std::tuple<long long int>&}]’:
prog.cpp:50:111:   required from ‘auto awesome_tuple_cat(Tuplen&& ...) [with Tuplen = {std::tuple<bool, char>&, std::tuple<short int, int>&, std::tuple<long long int>&}]’
prog.cpp:59:48:   required from here
prog.cpp:42:9: error: no matching function for call to ‘awesome_tuple_dog(stuff<indices_list<0u> >, std::tuple<bool, char, short int, int>, std::tuple<long long int>&)’
         );
         ^
prog.cpp:42:9: note: candidates are:
prog.cpp:23:6: note: template<class TStuff> auto awesome_tuple_dog(TStuff&&)
 auto awesome_tuple_dog( TStuff&& ) {
      ^
prog.cpp:23:6: note:   template argument deduction/substitution failed:
prog.cpp:42:9: note:   candidate expects 1 argument, 3 provided
         );
         ^
prog.cpp:29:6: note: template<class TStuff, class TFinalTuple> auto awesome_tuple_dog(TStuff&&, TFinalTuple&&)
 auto awesome_tuple_dog( TStuff&&, TFinalTuple&& tuple ) {
      ^
prog.cpp:29:6: note:   template argument deduction/substitution failed:
prog.cpp:42:9: note:   candidate expects 2 arguments, 3 provided
         );
         ^
prog.cpp:35:6: note: template<unsigned int ...I, unsigned int ...J, class ... Indices, class Tuple0, class Tuple1, class ... Tuplen> auto awesome_tuple_dog(stuff<indices_list<I ...>, indices_list<J ...>, Indices ...>, Tuple0&&, Tuple1&&, Tuplen&& ...)
 auto awesome_tuple_dog( stuff<indices_list<I...>, indices_list<J...>, Indices...>, Tuple0&& t0, Tuple1&& t1, Tuplen&&... tn ) {
      ^
prog.cpp:35:6: note:   template argument deduction/substitution failed:
prog.cpp:42:9: note:   candidate expects 3 arguments, 1 provided
         );
         ^
prog.cpp:42:9: note:   ‘stuff<indices_list<0u> >’ is not derived from ‘stuff<indices_list<I ...>, indices_list<J ...>, Indices ...>’
prog.cpp:59:48: error: conversion from ‘void’ to non-scalar type ‘main()::<anonymous struct>’ requested
     struct {} ___ = awesome_tuple_cat( a, b, c );
                                                ^
stdout
Standard output is empty