Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <tuple>
- #include <iostream>
- // FOR EACH
- template <size_t CUR, size_t END>
- struct ForEachIter_t {
- template <typename CALLABLE, typename...TYPES>
- static void Do(std::tuple<TYPES...>& tpl, CALLABLE&& func) {
- auto& tplItem = std::get<CUR>(tpl);
- func(tplItem);
- ForEachIter_t<CUR + 1, END>::Do(tpl, func);
- }
- };
- template <size_t CUR>
- struct ForEachIter_t<CUR, CUR> {
- template <typename CALLABLE, typename...TYPES>
- static void Do(std::tuple<TYPES...>&, CALLABLE&&) {};
- };
- template <typename CALLABLE, typename...TYPES>
- void ForEach(std::tuple<TYPES...>& tpl, CALLABLE&& func) {
- constexpr size_t tplSize = std::tuple_size<std::tuple<TYPES...>>::value;
- ForEachIter_t<0, tplSize>::Do(tpl, func);
- }
- // CONCAT
- template<size_t DST_BEG, size_t CUR, size_t END>
- struct SumIter_t {
- template<typename...T1, typename...T2>
- static void Do(const std::tuple<T2...>& src, std::tuple<T1...>& dst) {
- std::get<DST_BEG + CUR>(dst) = std::get<CUR>(src);
- SumIter_t<DST_BEG, CUR + 1, END>::Do(src, dst);
- }
- };
- template<size_t DST_BEG, size_t CUR>
- struct SumIter_t<DST_BEG, CUR, CUR> {
- template<typename...T1, typename...T2>
- static void Do(const std::tuple<T2...>&, const std::tuple<T1...>&) {}
- };
- template <typename...T1, typename...T2>
- std::tuple<T1..., T2...> ConcatTuple(const std::tuple<T1...>& tpl1, const std::tuple<T2...>& tpl2) {
- std::tuple<T1..., T2...> ret;
- SumIter_t<0, 0, sizeof...(T1)>::Do(tpl1, ret);
- SumIter_t<sizeof...(T1), 0, sizeof...(T2)>::Do(tpl2, ret);
- return ret;
- }
- // FILTER
- template <typename T, typename...ARGS>
- auto AddElementToEnd(const T& elem, const std::tuple<ARGS...>& tpl) {
- const std::tuple<T> last = std::make_tuple(elem);
- return ConcatTuple(tpl, last);
- }
- template <typename FILTER, typename T, bool FILTERED, typename...ARGS>
- struct Filter_t;
- template <typename FILTER, typename T, typename...ARGS>
- struct Filter_t<FILTER, T, true, ARGS...> {
- static std::tuple<ARGS...> Do(const T& elem, const std::tuple<ARGS...>& interim) {
- return interim;
- }
- };
- template <typename FILTER, typename T, typename...ARGS>
- struct Filter_t<FILTER, T, false, ARGS...> {
- static auto Do(const T& elem, const std::tuple<ARGS...>& interim) {
- return AddElementToEnd(elem, interim);
- }
- };
- template <size_t CUR, size_t END, typename FILTER>
- struct FilterIter_t {
- template <typename...T1, typename...T2>
- static auto Do(const std::tuple<T1...> tpl, const std::tuple<T2...>& interim = std::make_tuple()) {
- using curType = std::remove_const_t<std::remove_reference_t<decltype(std::get<CUR>(tpl))>>;
- constexpr auto filtered = std::is_same<curType, FILTER>::value;
- auto newInterim = Filter_t<FILTER, curType, filtered, T2...>::Do(std::get<CUR>(tpl), interim);
- return FilterIter_t<CUR + 1, END, FILTER>::Do(tpl, newInterim);
- }
- };
- template <size_t CUR, typename FILTER>
- struct FilterIter_t<CUR, CUR, FILTER> {
- template <typename...T1, typename...T2>
- static auto Do(std::tuple<T1...> tpl, const std::tuple<T2...>& interim) {
- using curType = typename std::remove_reference<decltype(std::get<CUR>(tpl))>::type;
- constexpr bool filtered = std::is_same<curType, FILTER>::value;
- return Filter_t<FILTER, curType, filtered, T2...>::Do(std::get<CUR>(tpl), interim);
- }
- };
- template<typename FILTER, typename...ARGS>
- auto FilterTuple(std::tuple<ARGS...>& tpl) {
- return FilterIter_t<0, sizeof...(ARGS)-1, FILTER>::Do(tpl);
- }
- int main() {
- auto tpl1 = std::make_tuple(100, 1.111, 2u, 3.333f);
- auto tpl2 = std::make_tuple(400, 5.555f, 6u, 7.777);
- auto tplconcat = ConcatTuple(tpl1, tpl2);
- auto filtered = FilterTuple<int>(tplconcat);
- ForEach(filtered, [](auto& itm) {
- std::cout << typeid(itm).name() << " -> " << itm << std::endl;
- });
- system("pause");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement