SigUtil  0.95
Utility modules for modern C++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
zip.hpp
Go to the documentation of this file.
1 /*
2 Copyright© 2014 Akihiro Nishimura
3 
4 This software is released under the MIT License.
5 http://opensource.org/licenses/mit-license.php
6 */
7 
8 #ifndef SIG_UTIL_ZIP_HPP
9 #define SIG_UTIL_ZIP_HPP
10 
11 #include "high_order.hpp"
12 
14 
15 namespace sig
16 {
18 
38 template <class... Cs
39 #if (SIG_MSVC_ENV && !(SIG_MSVC_VER <= 140)) || (SIG_GCC_ENV) || (SIG_CLANG_ENV)
40  , typename std::enable_if< And(impl::container_traits<typename impl::remove_const_reference<Cs>::type>::exist...) >::type*& = enabler
41 #endif
42  >
43 auto zip(Cs&&... lists)
44 {
45  return variadicZipWith(
47  [](typename impl::forward_element<Cs>::type... vs){
48  return std::make_tuple(std::forward<typename impl::forward_element<Cs>::type>(vs)...);
49  },
50 #else
52  return std::make_tuple(vs...);
53  },
54 #endif
55  std::forward<Cs>(lists)...
56  );
57 }
58 
59 
61 
81 template <uint Index, class CT,
82  class T = typename std::tuple_element<Index, typename impl::container_traits<typename impl::remove_const_reference<CT>::type>::value_type>::type,
83  class R = std::vector<T>
84 >
85 auto unzip(CT&& list_tuple) ->R
86 {
87  using ET = typename impl::forward_element<CT>::type;
88 
89  R result = impl::container_traits<R>::make(list_tuple.size());
90 
91  for (auto&& t : std::forward<CT>(list_tuple)){
92  impl::container_traits<R>::add_element(result, std::get<Index>(std::forward<ET>(t)));
93  }
94  return result;
95 }
96 
97 namespace impl
98 {
99 template<class CT, uint I = 0,
100  class CTR = typename impl::remove_const_reference<CT>::type,
101  typename std::enable_if<I + 1 == std::tuple_size<typename impl::container_traits<CTR>::value_type>::value, void>::type*& = enabler
102 >
103 auto unzipImpl_(CT&& c_tuple)
104 {
105  return std::make_tuple(unzip<I>(std::forward<CT>(c_tuple)));
106 }
107 template<class CT, uint I = 0,
108  class CTR = typename impl::remove_const_reference<CT>::type,
109  typename std::enable_if<I + 1 < std::tuple_size<typename impl::container_traits<CTR>::value_type>::value, void>::type*& = enabler
110 >
111 auto unzipImpl_(CT&& c_tuple)
112 {
113  return std::tuple_cat(std::make_tuple(unzip<I>(std::forward<CT>(c_tuple))), impl::unzipImpl_<CT, I + 1>(std::forward<CT>(c_tuple)));
114 }
115 } // impl
116 
118 
138 template <class CT>
139 auto unzip(CT&& c_tuple)
140 {
141  return impl::unzipImpl_(std::forward<CT>(c_tuple));
142 }
143 
144 
145 #if SIG_ENABLE_TUPLE_ZIP
146 namespace impl
147 {
148  template <class TC, size_t... Is>
149  auto zipImpl_(TC&& t_lists, std::index_sequence<Is...>)
150  {
151  return zip(std::get<Is>(std::forward<TC>(t_lists))...);
152  }
153 } // impl
154 
156 
167 template <class... Cs>
168 auto zip(std::tuple<Cs...> const& t_lists)
169 {
170  using Indices = std::make_index_sequence<sizeof...(Cs)>;
171  return impl::zipImpl_(t_lists, Indices());
172 }
173 
174 template <class... Cs>
175 auto zip(std::tuple<Cs...>&& t_lists)
176 {
177  using Indices = std::make_index_sequence<sizeof...(Cs)>;
178  return impl::zipImpl_(std::move(t_lists), Indices());
179 }
180 #endif
181 
182 }
183 #endif
auto unzipImpl_(CT &&c_tuple)
Definition: zip.hpp:103
typename std::remove_const< typename std::remove_reference< T >::type >::type type
void * enabler
#define SIG_ENABLE_MOVEITERATOR
auto variadicZipWith(F &&func, C1 &&list1, Cs &&...lists)
n引数高階関数
Definition: high_order.hpp:23
auto zip(Cs &&...lists)
複数のコンテナから、タプルのコンテナを作る
Definition: zip.hpp:43
高階関数
auto unzip(CT &&list_tuple) -> R
タプルのコンテナから、指定したindexのコンテナを取り出す
Definition: zip.hpp:85
Definition: array.hpp:15