Created
July 29, 2020 14:46
-
-
Save dolinenkov/44972adb7d6a66e9815e1a9d75607394 to your computer and use it in GitHub Desktop.
C++ templates - get element by tuple index and type
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstddef> | |
#include <type_traits> | |
#include <tuple> | |
#include <iostream> | |
namespace tuple_utils { | |
template<typename ElementType, const size_t TypeOrdinal, size_t MatchCounter, size_t OverallCounter, typename Tuple> | |
ElementType & get_by_index_and_type(Tuple && tuple) { | |
using T = std::remove_reference_t<Tuple>; | |
constexpr bool is_of_required_type = std::is_same_v<ElementType, std::tuple_element_t<OverallCounter, T>>; | |
static_assert(OverallCounter < std::tuple_size_v<T>, "Tuple type index out of bounds"); | |
if constexpr (is_of_required_type) { | |
if constexpr (TypeOrdinal == MatchCounter) { | |
return std::get<OverallCounter>(std::forward<Tuple>(tuple)); | |
} | |
else { | |
return get_by_index_and_type<ElementType, TypeOrdinal, MatchCounter + 1, OverallCounter + 1, Tuple>(std::forward<Tuple>(tuple)); | |
} | |
} | |
else { | |
return get_by_index_and_type<ElementType, TypeOrdinal, MatchCounter, OverallCounter + 1, Tuple>(std::forward<Tuple>(tuple)); | |
} | |
} | |
} | |
template<typename Type, size_t Index, typename Tuple> | |
Type & tuple_get(Tuple && tuple) { | |
return tuple_utils::get_by_index_and_type<Type, Index, 0, 0, Tuple>(std::forward<Tuple>(tuple)); | |
} | |
int main(int, char*[]) { | |
auto tuple = std::make_tuple(int(0), double(0.0), int(1)); | |
std::cout << tuple_get<int, 0>(tuple) << std::endl; | |
std::cout << tuple_get<int, 1>(tuple) << std::endl; | |
std::cout << tuple_get<double, 0>(tuple) << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment