fork download
  1. #include <iterator>
  2. #include <algorithm>
  3. #include <tuple>
  4. #include <functional>
  5.  
  6. using std::size_t;
  7.  
  8. template <typename TypeA, typename... Types>
  9. class ZipIterator : public std::iterator<std::random_access_iterator_tag, std::tuple<decltype(*TypeA::begin()), decltype(*Types::begin())...>> {
  10. public:
  11. typedef decltype(TypeA::begin()) TypeAit;
  12. typedef std::tuple<TypeAit, decltype(Types::begin())...> ItT;
  13. typedef std::tuple<decltype(*TypeA::begin()), decltype(*Types::begin())...> DataT;
  14. typedef std::tuple<TypeA*, Types*...> ContainerT;
  15.  
  16. ZipIterator(TypeA first, Types... rest) :
  17. m_index(0) {
  18. if (sizeof...(rest) != 0) {
  19. ZipIterator leftover(rest...);
  20. m_its = std::tuple_cat(std::tuple<TypeAit>(first.begin()), leftover.m_its);
  21. m_containers = std::tuple<TypeA*, Types*...>(first.begin(), leftover.m_containers);
  22. } else {
  23. m_its = std::tuple<TypeAit>(first.begin());
  24. m_containers = std::tuple<TypeA*>(first.begin());
  25. }
  26. }
  27.  
  28. ZipIterator(ZipIterator const& rhs) {
  29. copy(rhs);
  30. }
  31.  
  32. inline ZipIterator& operator=(ZipIterator const& rhs) {
  33. copy(rhs);
  34. }
  35.  
  36. inline ZipIterator& operator+=(int steps) const {
  37. additionImpl(m_its, steps);
  38. return *this;
  39. }
  40.  
  41. inline ZipIterator& operator-=(int steps) const {
  42. subtractionImpl(m_its, steps);
  43. return *this;
  44. }
  45.  
  46. inline DataT operator*() const {
  47. return construct(m_its);
  48. }
  49.  
  50. inline DataT* operator->() const {
  51. return &construct(m_its);
  52. }
  53.  
  54. inline DataT operator[](int rhs) const {
  55. return constructAt(rhs);
  56. }
  57.  
  58. inline ZipIterator& operator++() {
  59. incrementImpl(m_its);
  60. return *this;
  61. }
  62.  
  63. inline ZipIterator& operator--() {
  64. decrementImpl(m_its);
  65. return *this;
  66. }
  67.  
  68. inline ZipIterator operator++(int) {
  69. ZipIterator tmp(*this);
  70. ++this;
  71. return tmp;
  72. }
  73.  
  74. inline ZipIterator operator--(int) {
  75. ZipIterator tmp(*this);
  76. --this;
  77. return tmp;
  78. }
  79.  
  80. inline ZipIterator operator+(int steps) const {
  81. ZipIterator copy(*this);
  82. copy.additionImpl(copy.m_its, steps);
  83. return copy;
  84. }
  85.  
  86. inline ZipIterator operator-(int steps) const {
  87. ZipIterator copy(*this);
  88. copy.subtractionImpl(copy.m_its, steps);
  89. return copy;
  90. }
  91.  
  92. inline int operator-(ZipIterator const& rhs) {
  93. return std::get<0>(m_its) - std::get<0>(rhs.m_its);
  94. }
  95.  
  96. friend inline ZipIterator operator+(int lhs, ZipIterator const& rhs) {
  97. return rhs + lhs;
  98. }
  99.  
  100. friend inline ZipIterator operator-(int lhs, ZipIterator const& rhs) {
  101. return rhs - lhs;
  102. }
  103.  
  104. inline bool operator==(ZipIterator const& rhs) const {
  105. if (valid() || rhs.valid())
  106. return m_its == rhs.m_its;
  107. return true;
  108. }
  109.  
  110. inline bool operator!=(ZipIterator const& rhs) const {
  111. return !(*this == rhs);
  112. }
  113.  
  114. inline bool operator<(ZipIterator const& rhs) const {
  115. return m_its < rhs.m_its;
  116. }
  117.  
  118. inline bool operator<=(ZipIterator const& rhs) const {
  119. return (*this == rhs) || (*this < rhs);
  120. }
  121.  
  122. inline bool operator>=(ZipIterator const& rhs) const {
  123. return !(*this < rhs);
  124. }
  125.  
  126. inline bool operator>(ZipIterator const& rhs) const {
  127. return !(*this <= rhs);
  128. }
  129.  
  130. inline ZipIterator begin() const {
  131. ZipIterator copy(*this);
  132. copy.m_its = beginImpl(copy);
  133. return copy;
  134. }
  135.  
  136. inline ZipIterator end() const {
  137. ZipIterator copy(*this);
  138. copy.m_its = endImpl(copy);
  139. return copy;
  140. }
  141.  
  142. private:
  143. inline void copy(ZipIterator const& copy) {
  144. m_its = copy.m_its;
  145. m_containers = copy.m_containers;
  146. m_index = copy.m_index;
  147. }
  148.  
  149. //Begin
  150.  
  151. template<size_t I = 0, typename... Tp>
  152. inline typename std::enable_if<(I == sizeof...(Tp)), DataT>::type
  153. beginImpl(std::tuple<Tp...> const& its) {
  154. return std::tuple<>();
  155. }
  156.  
  157. template<size_t I = 0, typename... Tp>
  158. inline typename std::enable_if<(I < sizeof...(Tp)), DataT>::type
  159. beginImpl(std::tuple<Tp...> const& its) {
  160. return std::tuple_cat(
  161. std::tuple<decltype(*std::get<I>(its))>(
  162. std::get<I>(m_containers).begin();
  163. ),
  164. constructImpl<I + 1>(its)
  165. );
  166. }
  167.  
  168. //End
  169.  
  170. template<size_t I = 0, typename... Tp>
  171. inline typename std::enable_if<(I == sizeof...(Tp)), DataT>::type
  172. endImpl(std::tuple<Tp...> const& its) {
  173. return std::tuple<>();
  174. }
  175.  
  176. template<size_t I = 0, typename... Tp>
  177. inline typename std::enable_if<(I < sizeof...(Tp)), DataT>::type
  178. endImpl(std::tuple<Tp...> const& its) {
  179. return std::tuple_cat(
  180. std::tuple<decltype(*std::get<I>(its))>(
  181. std::get<I>(m_containers).end();
  182. ),
  183. constructImpl<I + 1>(its)
  184. );
  185. }
  186.  
  187. //Increment
  188.  
  189. template<size_t I = 0, typename... Tp>
  190. inline typename std::enable_if<(I == sizeof...(Tp)), void>::type
  191. incrementImpl(std::tuple<Tp...> const& its) { }
  192.  
  193. template<size_t I = 0, typename... Tp>
  194. inline typename std::enable_if<(I < sizeof...(Tp)), void>::type
  195. incrementImpl(std::tuple<Tp...> const& its) {
  196. ++(std::get<I>(its));
  197. incrementImpl<I + 1>(its);
  198. }
  199.  
  200. //Decrement
  201.  
  202. template<size_t I = 0, typename... Tp>
  203. inline typename std::enable_if<(I == sizeof...(Tp)), void>::type
  204. decrementImpl(std::tuple<Tp...> const& its) { }
  205.  
  206. template<size_t I = 0, typename... Tp>
  207. inline typename std::enable_if<(I < sizeof...(Tp)), void>::type
  208. decrementImpl(std::tuple<Tp...> const& its) {
  209. --(std::get<I>(its));
  210. decrementImpl<I + 1>(its);
  211. }
  212.  
  213. //Addition
  214.  
  215. template<size_t I = 0, typename... Tp>
  216. inline typename std::enable_if<(I == sizeof...(Tp)), void>::type
  217. additionImpl(std::tuple<Tp...> const& its, int steps) { }
  218.  
  219. template<size_t I = 0, typename... Tp>
  220. inline typename std::enable_if<(I < sizeof...(Tp)), void>::type
  221. additionImpl(std::tuple<Tp...> const& its, int steps) {
  222. std::get<I>(its) + steps;
  223. incrementImpl<I + 1>(its);
  224. }
  225.  
  226. //Subtraction
  227.  
  228. template<size_t I = 0, typename... Tp>
  229. inline typename std::enable_if<(I == sizeof...(Tp)), void>::type
  230. subtractionImpl(std::tuple<Tp...> const& its, int steps) { }
  231.  
  232. template<size_t I = 0, typename... Tp>
  233. inline typename std::enable_if<(I < sizeof...(Tp)), void>::type
  234. subtractionImpl(std::tuple<Tp...> const& its, int steps) {
  235. std::get<I>(its) + steps;
  236. decrementImpl<I + 1>(its);
  237. }
  238.  
  239. //Construct
  240.  
  241. template<size_t I = 0, typename... Tp>
  242. inline auto constructImpl(std::tuple<Tp...> const& its) ->
  243. typename std::enable_if<(I == sizeof...(Tp)), typename std::tuple<decltype(*Tp)...>>::type {
  244. return std::tuple<>();
  245. }
  246.  
  247. template<size_t I = 0, typename... Tp>
  248. inline auto constructImpl(std::tuple<Tp...> const& its) ->
  249. typename std::enable_if<(I < sizeof...(Tp)), typename std::tuple<decltype(*Tp)...>>::type {
  250. return std::tuple_cat(
  251. std::tuple<decltype(*std::get<I>(its))>(
  252. *std::get<I>(its)
  253. ),
  254. constructImpl<I + 1>(its)
  255. );
  256. }
  257.  
  258. inline DataT construct() {
  259. if (valid()) {
  260. return constructImpl(m_its);
  261. }
  262. throw StarAlgorithm("Attempted to construct zipped tuple beyond end.");
  263. }
  264.  
  265. //ConstructAt
  266.  
  267. template<size_t I = 0, typename... Tp>
  268. inline typename std::enable_if<(I == sizeof...(Tp)), typename std::tuple<decltype(*Tp)...>>::type
  269. constructAtImpl(std::tuple<Tp...> const& its, size_t index) {
  270. return std::tuple<>();
  271. }
  272.  
  273. template<size_t I = 0, typename... Tp>
  274. inline typename std::enable_if<(I < sizeof...(Tp)), typename std::tuple<decltype(*Tp)...>>::type
  275. constructImpl(std::tuple<Tp...> const& its, size_t index) {
  276. return std::tuple_cat(
  277. std::tuple<decltype(*std::get<I>(its))>(
  278. std::get<I>(its)[index]
  279. ),
  280. constructAtImpl<I + 1>(its, index)
  281. );
  282. }
  283.  
  284. inline DataT constructAt(size_t index) {
  285. if (validAt(index)) {
  286. constructAtImpl(m_its, index);
  287. }
  288. throw StarAlgorithm("Attempting to construct zipped tuple beyond end.");
  289. }
  290.  
  291. //Valid
  292.  
  293. template<size_t I = 0, typename... Tp>
  294. inline typename std::enable_if<(I == sizeof...(Tp)), bool>::type
  295. validImpl(std::tuple<Tp...> const& its) {
  296. return true;
  297. }
  298.  
  299. template<size_t I = 0, typename... Tp>
  300. inline typename std::enable_if<(I < sizeof...(Tp)), bool>::type
  301. validImpl(std::tuple<Tp...> const& its) {
  302. return std::get<I>(its) != std::get<I>(m_containers).end() &&
  303. validImpl<I + 1>(its);
  304. }
  305.  
  306. inline bool valid() {
  307. validImpl(m_its);
  308. }
  309.  
  310. //ValidAt
  311.  
  312. template<size_t I = 0, typename... Tp>
  313. inline typename std::enable_if<(I == sizeof...(Tp)), bool>::type
  314. validAtImpl(std::tuple<Tp...> const& its, size_t index) {
  315. return true;
  316. }
  317.  
  318. template<size_t I = 0, typename... Tp>
  319. inline typename std::enable_if<I < sizeof...(Tp), bool>::type
  320. validAtImpl(std::tuple<Tp...> const& its, size_t index) {
  321. try {
  322. std::get<I>(its)[index];
  323. } catch (AlgorithmException const& e) {
  324. return false;
  325. }
  326. return validAtImpl<I + 1>(its, index);
  327. }
  328.  
  329. inline bool validAt(size_t index) {
  330. validAtImpl(m_its, index);
  331. }
  332.  
  333. ItT m_its;
  334. ContainerT m_containers;
  335. };
  336.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:244:5: error: expected primary-expression before 'return'
prog.cpp:244:5: error: expected '}' before 'return'
prog.cpp:244:5: error: expected '>' before 'return'
prog.cpp:244:25: error: template argument 2 is invalid
prog.cpp:244:26: error: expected '::' before ';' token
prog.cpp:244:26: error: expected identifier before ';' token
prog.cpp: In constructor 'ZipIterator<TypeA, Types>::ZipIterator(TypeA, Types ...)':
prog.cpp:17:7: error: class 'ZipIterator<TypeA, Types>' does not have any field named 'm_index'
prog.cpp:20:7: error: 'm_its' was not declared in this scope
prog.cpp:21:7: error: 'm_containers' was not declared in this scope
prog.cpp:23:7: error: 'm_its' was not declared in this scope
prog.cpp:24:7: error: 'm_containers' was not declared in this scope
prog.cpp: In member function 'ZipIterator<TypeA, Types>& ZipIterator<TypeA, Types>::operator+=(int) const':
prog.cpp:37:18: error: 'm_its' was not declared in this scope
prog.cpp: In member function 'ZipIterator<TypeA, Types>& ZipIterator<TypeA, Types>::operator-=(int) const':
prog.cpp:42:21: error: 'm_its' was not declared in this scope
prog.cpp: In member function 'ZipIterator<TypeA, Types>::DataT ZipIterator<TypeA, Types>::operator*() const':
prog.cpp:47:22: error: 'm_its' was not declared in this scope
prog.cpp:47:27: error: there are no arguments to 'construct' that depend on a template parameter, so a declaration of 'construct' must be available
prog.cpp:47:27: note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
prog.cpp: In member function 'ZipIterator<TypeA, Types>::DataT* ZipIterator<TypeA, Types>::operator->() const':
prog.cpp:51:23: error: 'm_its' was not declared in this scope
prog.cpp:51:28: error: there are no arguments to 'construct' that depend on a template parameter, so a declaration of 'construct' must be available
prog.cpp: In member function 'ZipIterator<TypeA, Types>::DataT ZipIterator<TypeA, Types>::operator[](int) const':
prog.cpp:55:27: error: there are no arguments to 'constructAt' that depend on a template parameter, so a declaration of 'constructAt' must be available
prog.cpp: In member function 'ZipIterator<TypeA, Types>& ZipIterator<TypeA, Types>::operator++()':
prog.cpp:59:19: error: 'm_its' was not declared in this scope
prog.cpp: In member function 'ZipIterator<TypeA, Types>& ZipIterator<TypeA, Types>::operator--()':
prog.cpp:64:19: error: 'm_its' was not declared in this scope
prog.cpp: In member function 'int ZipIterator<TypeA, Types>::operator-(const ZipIterator<TypeA, Types>&)':
prog.cpp:93:24: error: 'm_its' was not declared in this scope
prog.cpp: In member function 'bool ZipIterator<TypeA, Types>::operator==(const ZipIterator<TypeA, Types>&) const':
prog.cpp:105:15: error: there are no arguments to 'valid' that depend on a template parameter, so a declaration of 'valid' must be available
prog.cpp:106:14: error: 'm_its' was not declared in this scope
prog.cpp: In member function 'bool ZipIterator<TypeA, Types>::operator<(const ZipIterator<TypeA, Types>&) const':
prog.cpp:115:12: error: 'm_its' was not declared in this scope
prog.cpp: In member function 'void ZipIterator<TypeA, Types>::copy(const ZipIterator<TypeA, Types>&)':
prog.cpp:144:5: error: 'm_its' was not declared in this scope
prog.cpp:145:5: error: 'm_containers' was not declared in this scope
prog.cpp:146:5: error: 'm_index' was not declared in this scope
prog.cpp: In member function 'typename std::enable_if<(I < sizeof (Tp ...)), std::tuple<decltype (* TypeA:: begin()), decltype (* Types:: begin())...> >::type ZipIterator<TypeA, Types>::beginImpl(const std::tuple<_Args ...>&)':
prog.cpp:162:28: error: 'm_containers' was not declared in this scope
prog.cpp:161:53: error: expected primary-expression before '(' token
prog.cpp:162:49: error: expected ')' before ';' token
prog.cpp:163:14: error: expected primary-expression before ')' token
prog.cpp:163:14: error: expected ';' before ')' token
prog.cpp: In member function 'typename std::enable_if<(I < sizeof (Tp ...)), std::tuple<decltype (* TypeA:: begin()), decltype (* Types:: begin())...> >::type ZipIterator<TypeA, Types>::endImpl(const std::tuple<_Args ...>&)':
prog.cpp:181:28: error: 'm_containers' was not declared in this scope
prog.cpp:180:53: error: expected primary-expression before '(' token
prog.cpp:181:47: error: expected ')' before ';' token
prog.cpp:182:14: error: expected primary-expression before ')' token
prog.cpp:182:14: error: expected ';' before ')' token
prog.cpp: At global scope:
prog.cpp:247:3: error: expected unqualified-id before 'template'
prog.cpp:258:10: error: 'DataT' does not name a type
prog.cpp:269:3: error: expected '(' before 'constructAtImpl'
prog.cpp:269:3: error: expected '>' before 'constructAtImpl'
prog.cpp:269:61: error: template argument 2 is invalid
prog.cpp:269:63: error: expected '::' before '{' token
prog.cpp:269:63: error: expected identifier before '{' token
prog.cpp:269:63: error: expected unqualified-id before '{' token
prog.cpp:275:3: error: expected '(' before 'constructImpl'
prog.cpp:275:3: error: expected '>' before 'constructImpl'
prog.cpp:275:59: error: template argument 2 is invalid
prog.cpp:275:61: error: expected '::' before '{' token
prog.cpp:275:61: error: expected identifier before '{' token
prog.cpp:275:61: error: expected unqualified-id before '{' token
prog.cpp:284:10: error: 'DataT' does not name a type
prog.cpp: In function 'typename std::enable_if<(I < sizeof (Tp ...)), bool>::type validImpl(const std::tuple<_Elements ...>&)':
prog.cpp:302:44: error: 'm_containers' was not declared in this scope
prog.cpp: In function 'bool valid()':
prog.cpp:307:15: error: 'm_its' was not declared in this scope
prog.cpp: In function 'typename std::enable_if<(I < sizeof (Tp ...)), bool>::type validAtImpl(const std::tuple<_Elements ...>&, size_t)':
prog.cpp:323:14: error: expected type-specifier before 'AlgorithmException'
prog.cpp:323:33: error: expected ')' before 'const'
prog.cpp:323:33: error: expected '{' before 'const'
prog.cpp:323:41: error: expected initializer before ')' token
prog.cpp: In function 'bool validAt(size_t)':
prog.cpp:330:17: error: 'm_its' was not declared in this scope
prog.cpp: At global scope:
prog.cpp:333:3: error: 'ItT' does not name a type
prog.cpp:334:3: error: 'ContainerT' does not name a type
prog.cpp:335:1: error: expected declaration before '}' token
stdout

Standard output is empty