Skip to content

Instantly share code, notes, and snippets.

@Zikoel
Created September 7, 2017 09:49
Show Gist options
  • Save Zikoel/132b1ad51d43222ea7a103b5f84925cc to your computer and use it in GitHub Desktop.
Save Zikoel/132b1ad51d43222ea7a103b5f84925cc to your computer and use it in GitHub Desktop.
A way for iterate over complex tuple elements
#include <tuple>
#include <vector>
#include <iostream>
#include <utility>
template <typename ...Types>
struct A
{
std::tuple<std::vector<Types>...> t;
};
namespace detail {
template<typename T>
std::string type_str();
template<>
std::string type_str<int>()
{
return std::string{ "int: " };
}
template<>
std::string type_str<double>()
{
return std::string{ "double: " };
}
template<>
std::string type_str<std::string>()
{
return std::string{ "string: " };
}
}
struct B
{
template<size_t Idx, typename ...Types>
void print_a(std::integral_constant<bool, true>, std::tuple<std::vector<Types>...> & t)
{
using currentTupleType = typename std::tuple_element<Idx, std::decay_t<decltype(t)>>::type;
using currentVectorType = typename currentTupleType::value_type;
for(auto && v : std::get<Idx>(t))
{
std::cout << detail::type_str<currentVectorType>() << v << std::endl;
}
}
template<size_t Idx, typename ...Types>
void print_a(std::integral_constant<bool, false>, std::tuple<std::vector<Types>...> & t)
{
using currentTupleType = typename std::tuple_element<Idx, std::decay_t<decltype(t)>>::type;
using currentVectorType = typename currentTupleType::value_type;
for(auto && v : std::get<Idx>(t))
{
std::cout << detail::type_str<currentVectorType>() << v << std::endl;
}
const size_t step_index = Idx - 1;
print_a<step_index, Types...>( std::integral_constant<bool, step_index == 0>{}, t);
}
template <typename ...Types>
void print_a(A<Types...> & a)
{
const size_t start_index = std::tuple_size<decltype(a.t)>::value -1;
print_a<start_index, Types...>( std::integral_constant<bool, start_index == 0>{}, a.t);
}
};
int main()
{
A<int, double, std::string> a;
std::get<0>(a.t).push_back(1);
std::get<0>(a.t).push_back(2);
std::get<1>(a.t).push_back(1.1);
std::get<1>(a.t).push_back(2.2);
std::get<2>(a.t).push_back("1 str");
std::get<2>(a.t).push_back("2 str");
B b;
b.print_a<int, double, std::string>(a);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment