Last active
February 18, 2020 17:35
-
-
Save juliusHuelsmann/669f537aeb5e7105386d510d186b24e1 to your computer and use it in GitHub Desktop.
Code snipplet (c++20) for creating conditional tuples; getting a conditional tuple type.
This file contains 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
// Author: Julius Hülsmann | |
// Email: juliusHuelsmann [at] gmail.com, julius.huelsmann [at] data-spree.com | |
// Creation Date: 2020-02-17 | |
// Execution: g++-10.0 -std=c++2a [FILE] | |
#include <initializer_list> | |
#include <tuple> | |
#include <utility> | |
//#define EXECUTION consteval //< c++2a | |
#define EXECUTION constexpr //< prior to cpp 20 XXX: switch if compiled with g++ < 10 | |
namespace dbn { | |
/// Helper struct which allows functions in order to remove certain values from an instance of a | |
/// tuple. | |
template <bool condition, std::size_t s> struct tuple { | |
/// Retain first \p s values from the tuple \p tpl. | |
template <typename Tuple> static inline EXECUTION auto retain(Tuple const &tpl) noexcept { | |
static_assert(s <= std::tuple_size<Tuple>::value, "Invalid tuple reduction size!"); | |
constexpr auto k = condition ? s : std::tuple_size<Tuple>::value; | |
return _reduce(tpl, std::make_index_sequence<s>()); | |
} | |
/// Strip last \p s values from the tuple \p tpl. | |
template <typename Tuple> static inline EXECUTION auto strip(Tuple const &tpl) noexcept { | |
static_assert(s >= 0 && s < std::tuple_size<Tuple>::value, "Invalid tuple reduction size!"); | |
constexpr auto k = condition ? s : 0; | |
return _reduce(tpl, std::make_index_sequence<std::tuple_size<Tuple>::value - s>()); | |
} | |
private: | |
template <typename Tuple, std::size_t... I> | |
static inline EXECUTION auto _reduce(Tuple const &tpl, std::index_sequence<I...>) noexcept { | |
return std::make_tuple(std::get<I>(tpl)...); | |
} | |
}; | |
/// Helper struct which operates on the type of a tuple and instead of the instance as is the case | |
/// in @cmp #tuple. | |
template <bool cond, size_t s, typename is, typename ...args> struct thlp; | |
template <bool cond, size_t s, size_t... i, class... args> | |
struct thlp<cond, s, std::index_sequence<i...>, args...> { | |
static_assert(s <= sizeof...(args), "Requested new tuple size exceeds old one."); | |
using type = std::tuple<std::tuple_element_t<i, std::tuple<args...>>...>; | |
}; | |
template <size_t s, size_t... i, class... a> struct thlp<false, s, std::index_sequence<i...>,a...> { | |
using type = std::tuple<a...>; | |
}; | |
/// Strips sizeof...\p args - \p elementsToKeep last types from tuple if indicated by \p condition. | |
template <bool condition, size_t keep, typename... args> | |
using conditional_tuple_t = thlp<condition, keep, | |
decltype(std::make_index_sequence<keep>()), args...>::type; | |
} // namespace dbn | |
int main() { | |
// Demonstrate usage of the type | |
dbn::conditional_tuple_t<true, 2, int, int, double> fa = std::make_tuple(1, 2); | |
// Demonstration of the value | |
auto const [a, b] = dbn::tuple<true, 2>::retain(std::make_tuple(1, 2, 4)); | |
auto const [aa, bb, c] = dbn::tuple<true, 3>::retain(std::make_tuple(1, 2, 4)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment