Advertisement
Guest User

Untitled

a guest
Feb 25th, 2017
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.71 KB | None | 0 0
  1. #include <tuple>
  2. #include <iostream>
  3.  
  4. // FOR EACH
  5. template <size_t CUR, size_t END>
  6. struct ForEachIter_t {
  7.     template <typename CALLABLE, typename...TYPES>
  8.     static void Do(std::tuple<TYPES...>& tpl, CALLABLE&& func) {
  9.         auto& tplItem = std::get<CUR>(tpl);
  10.         func(tplItem);
  11.         ForEachIter_t<CUR + 1, END>::Do(tpl, func);
  12.     }
  13. };
  14.  
  15. template <size_t CUR>
  16. struct ForEachIter_t<CUR, CUR> {
  17.     template <typename CALLABLE, typename...TYPES>
  18.     static void Do(std::tuple<TYPES...>&, CALLABLE&&) {};
  19. };
  20.  
  21. template <typename CALLABLE, typename...TYPES>
  22. void ForEach(std::tuple<TYPES...>& tpl, CALLABLE&& func) {
  23.     constexpr size_t tplSize = std::tuple_size<std::tuple<TYPES...>>::value;
  24.     ForEachIter_t<0, tplSize>::Do(tpl, func);
  25. }
  26.  
  27. // CONCAT
  28. template<size_t DST_BEG, size_t CUR, size_t END>
  29. struct SumIter_t {
  30.     template<typename...T1, typename...T2>
  31.     static void Do(const std::tuple<T2...>& src, std::tuple<T1...>& dst) {
  32.         std::get<DST_BEG + CUR>(dst) = std::get<CUR>(src);
  33.         SumIter_t<DST_BEG, CUR + 1, END>::Do(src, dst);
  34.     }
  35. };
  36.  
  37. template<size_t DST_BEG, size_t CUR>
  38. struct SumIter_t<DST_BEG, CUR, CUR> {
  39.     template<typename...T1, typename...T2>
  40.     static void Do(const std::tuple<T2...>&, const std::tuple<T1...>&) {}
  41. };
  42.  
  43.  
  44. template <typename...T1, typename...T2>
  45. std::tuple<T1..., T2...> ConcatTuple(const std::tuple<T1...>& tpl1, const std::tuple<T2...>& tpl2) {
  46.     std::tuple<T1..., T2...> ret;
  47.     SumIter_t<0, 0, sizeof...(T1)>::Do(tpl1, ret);
  48.     SumIter_t<sizeof...(T1), 0, sizeof...(T2)>::Do(tpl2, ret);
  49.     return ret;
  50. }
  51.  
  52. // FILTER
  53. template <typename T, typename...ARGS>
  54. auto AddElementToEnd(const T& elem, const std::tuple<ARGS...>& tpl) {
  55.     const std::tuple<T> last = std::make_tuple(elem);
  56.     return ConcatTuple(tpl, last);
  57. }
  58.  
  59. template <typename FILTER, typename T, bool FILTERED, typename...ARGS>
  60. struct Filter_t;
  61.  
  62. template <typename FILTER, typename T, typename...ARGS>
  63. struct Filter_t<FILTER, T, true, ARGS...> {
  64.     static std::tuple<ARGS...> Do(const T& elem, const std::tuple<ARGS...>& interim) {
  65.         return interim;
  66.     }
  67. };
  68.  
  69. template <typename FILTER, typename T, typename...ARGS>
  70. struct Filter_t<FILTER, T, false, ARGS...> {
  71.     static auto Do(const T& elem, const std::tuple<ARGS...>& interim) {
  72.         return AddElementToEnd(elem, interim);
  73.     }
  74. };
  75.  
  76. template <size_t CUR, size_t END, typename FILTER>
  77. struct FilterIter_t {
  78.     template <typename...T1, typename...T2>
  79.     static auto Do(const std::tuple<T1...> tpl, const std::tuple<T2...>& interim = std::make_tuple()) {
  80.         using curType = std::remove_const_t<std::remove_reference_t<decltype(std::get<CUR>(tpl))>>;
  81.         constexpr auto filtered = std::is_same<curType, FILTER>::value;
  82.         auto newInterim = Filter_t<FILTER, curType, filtered, T2...>::Do(std::get<CUR>(tpl), interim);
  83.         return FilterIter_t<CUR + 1, END, FILTER>::Do(tpl, newInterim);
  84.     }
  85. };
  86.  
  87. template <size_t CUR, typename FILTER>
  88. struct FilterIter_t<CUR, CUR, FILTER> {
  89.     template <typename...T1, typename...T2>
  90.     static auto Do(std::tuple<T1...> tpl, const std::tuple<T2...>& interim) {
  91.         using curType = typename std::remove_reference<decltype(std::get<CUR>(tpl))>::type;
  92.         constexpr bool filtered = std::is_same<curType, FILTER>::value;
  93.         return Filter_t<FILTER, curType, filtered, T2...>::Do(std::get<CUR>(tpl), interim);
  94.     }
  95. };
  96.  
  97. template<typename FILTER, typename...ARGS>
  98. auto FilterTuple(std::tuple<ARGS...>& tpl) {
  99.     return FilterIter_t<0, sizeof...(ARGS)-1, FILTER>::Do(tpl);
  100. }
  101.  
  102. int main() {
  103.     auto tpl1 = std::make_tuple(100, 1.111, 2u, 3.333f);
  104.     auto tpl2 = std::make_tuple(400, 5.555f, 6u, 7.777);
  105.     auto tplconcat = ConcatTuple(tpl1, tpl2);
  106.     auto filtered = FilterTuple<int>(tplconcat);
  107.  
  108.     ForEach(filtered, [](auto& itm) {
  109.         std::cout << typeid(itm).name() << " -> " << itm << std::endl;
  110.     });
  111.     system("pause");
  112. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement