Advertisement
Guest User

Untitled

a guest
May 22nd, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.18 KB | None | 0 0
  1. #pragma once
  2. #include <utility>
  3.  
  4. using std::forward;
  5. using std::move;
  6. using std::enable_if;
  7.  
  8.  
  9. template <size_t N, typename FIRST, typename... OTHERS>
  10. struct KthType {
  11. typedef typename KthType<N-1, OTHERS...>::type type;
  12. };
  13.  
  14. template <typename FIRST, typename... OTHERS>
  15. struct KthType<0, FIRST, OTHERS...> {
  16. typedef FIRST type;
  17. };
  18.  
  19.  
  20. template <typename FIRST, typename... OTHERS>
  21. class Tuple {
  22. public:
  23. Tuple() = default;
  24.  
  25. Tuple(const Tuple<FIRST, OTHERS...>&) = default;
  26. Tuple(Tuple<FIRST, OTHERS...>&&);
  27.  
  28. template <typename FARG, typename... ARGS>
  29. explicit Tuple(FARG&&, ARGS&&...);
  30.  
  31. Tuple<FIRST, OTHERS...>& operator=(const Tuple<FIRST, OTHERS...>&);
  32. Tuple<FIRST, OTHERS...>& operator=(Tuple<FIRST, OTHERS...>&&);
  33.  
  34. ~Tuple() = default;
  35.  
  36. void swap(Tuple<FIRST, OTHERS...>&);
  37.  
  38. //friends
  39.  
  40. template <size_t N, typename FST, typename... OTH>
  41. friend class GetByNum;
  42.  
  43. template <typename T, typename FST, typename... OTH>
  44. friend class GetByType;
  45.  
  46. template <typename FST, typename... OTH>
  47. friend class Compares;
  48.  
  49. template <typename TUPLE1, typename TUPLE2>
  50. friend class Cat2;
  51.  
  52. private:
  53. FIRST _fst;
  54. Tuple<OTHERS...> _others;
  55.  
  56. Tuple(FIRST&&, Tuple<OTHERS...>&&);
  57. };
  58.  
  59. template <typename T>
  60. class Tuple<T> {
  61. public:
  62. Tuple() = default;
  63.  
  64. Tuple(const Tuple<T>&) = default;
  65. Tuple(Tuple<T>&&);
  66.  
  67. template <typename U>
  68. explicit Tuple(U&&);
  69.  
  70. Tuple<T>& operator=(const Tuple<T>&);
  71. Tuple<T>& operator=(Tuple<T>&&);
  72.  
  73. ~Tuple() = default;
  74.  
  75. void swap(Tuple<T>&);
  76.  
  77. //friends
  78.  
  79. template <size_t N, typename FST, typename... OTH>
  80. friend class GetByNum;
  81.  
  82. template <typename U, typename FST, typename... OTH>
  83. friend class GetByType;
  84.  
  85. template <typename FST, typename... OTH>
  86. friend class Compares;
  87.  
  88. template <typename TUPLE1, typename TUPLE2>
  89. friend class Cat2;
  90.  
  91. private:
  92. T _fst;
  93.  
  94. };
  95.  
  96. // Implementation
  97.  
  98. // Construct
  99.  
  100. template <typename FIRST, typename... OTHERS>
  101. template <typename FARG, typename... ARGS>
  102. Tuple<FIRST, OTHERS...>::Tuple(FARG&& farg, ARGS&&... args):
  103. _fst(forward<FARG>(farg)),
  104. _others(forward<ARGS>(args)...) {}
  105.  
  106. template <typename T>
  107. template <typename U>
  108. Tuple<T>::Tuple(U&& value):_fst(forward<U>(value)) {}
  109.  
  110. template <typename FIRST, typename... OTHERS>
  111. Tuple<FIRST, OTHERS...>::Tuple(Tuple<FIRST, OTHERS...>&& tuple):
  112. _fst(forward<FIRST>(tuple._fst)),
  113. _others(move(tuple._others)) {}
  114.  
  115. template <typename T>
  116. Tuple<T>::Tuple(Tuple<T>&& tuple):
  117. _fst(forward<T>(tuple._fst)) {}
  118.  
  119. template <typename FIRST, typename... OTHERS>
  120. Tuple<FIRST, OTHERS...>::Tuple(FIRST&& fst,
  121. Tuple<OTHERS...>&& oth):
  122. _fst(move(fst)),
  123. _others(move(oth))
  124. {}
  125.  
  126. // Copy
  127.  
  128. template <typename FIRST, typename... ARGS>
  129. Tuple<FIRST, ARGS...>& Tuple<FIRST, ARGS...>::operator=
  130. (Tuple<FIRST, ARGS...>&& tuple) {
  131. _fst = move(tuple._fst);
  132. _others = move(tuple._others);
  133. return *this;
  134. }
  135.  
  136. template <typename T>
  137. Tuple<T>& Tuple<T>::operator=(Tuple<T>&& tuple) {
  138. _fst = move(tuple._fst);
  139. return *this;
  140. }
  141.  
  142.  
  143. template <typename FIRST, typename... ARGS>
  144. Tuple<FIRST, ARGS...>& Tuple<FIRST, ARGS...>::operator=
  145. (const Tuple<FIRST, ARGS...>& tuple) {
  146. _fst = tuple._fst;
  147. _others = tuple._others;
  148. return *this;
  149. }
  150.  
  151. template <typename T>
  152. Tuple<T>& Tuple<T>::operator=(const Tuple<T>& tuple) {
  153. _fst = tuple._fst;
  154. return *this;
  155. }
  156.  
  157.  
  158. template <class T>
  159. struct unwrap_refwrapper {
  160. using type = T;
  161. };
  162.  
  163. template <class T>
  164. struct unwrap_refwrapper<std::reference_wrapper<T> > {
  165. using type = T&;
  166. };
  167.  
  168. template <class T>
  169. using special_decay_t = typename unwrap_refwrapper<typename std::decay<T>::type>::type;
  170.  
  171. template <typename... ARGS>
  172. auto makeTuple(ARGS&&... args) {
  173. return Tuple<special_decay_t<ARGS>...>
  174. (forward<ARGS>(args)...);
  175. }
  176.  
  177. // Swap
  178.  
  179. template <typename FST, typename... OTHERS>
  180. void Tuple<FST, OTHERS...>::swap(Tuple<FST, OTHERS...>& tuple) {
  181. std::swap(_fst, tuple._fst);
  182. std::swap(_others, tuple._others);
  183. }
  184.  
  185. template <typename T>
  186. void Tuple<T>::swap(Tuple<T>& tuple) {
  187. std::swap(_fst, tuple._fst);
  188. }
  189.  
  190. // Get By Num
  191.  
  192. template <size_t N, typename FIRST, typename... OTHERS>
  193. struct GetByNum {
  194. static decltype(auto)
  195. action(Tuple<FIRST, OTHERS...>& tuple) {
  196. return GetByNum<N-1, OTHERS...>::action(tuple._others);
  197. }
  198.  
  199. static decltype(auto)
  200. action(const Tuple<FIRST, OTHERS...>& tuple) {
  201. return GetByNum<N-1, OTHERS...>::action(tuple._others);
  202. }
  203.  
  204. static decltype(auto)
  205. action(Tuple<FIRST, OTHERS...>&& tuple) {
  206. return GetByNum<N-1, OTHERS...>::action(move(tuple._others));
  207. }
  208. };
  209.  
  210. template <typename FIRST, typename... OTHERS>
  211. struct GetByNum<0, FIRST, OTHERS...> {
  212. static FIRST& action(Tuple<FIRST, OTHERS...>& tuple) {
  213. return tuple._fst;
  214. }
  215.  
  216. static const FIRST& action(const Tuple<FIRST, OTHERS...>& tuple) {
  217. return tuple._fst;
  218. }
  219.  
  220. static FIRST&& action(Tuple<FIRST, OTHERS...>&& tuple) {
  221. return move(tuple._fst);
  222. }
  223. };
  224.  
  225. template <size_t N, typename FIRST, typename... OTHERS>
  226. decltype(auto) get(Tuple<FIRST, OTHERS...>& tuple) {
  227. return GetByNum<N, FIRST, OTHERS...>::action(tuple);
  228. };
  229.  
  230. template <size_t N, typename FIRST, typename... OTHERS>
  231. decltype(auto) get(const Tuple<FIRST, OTHERS...>& tuple) {
  232. return GetByNum<N, FIRST, OTHERS...>::action(tuple);
  233. };
  234.  
  235. template <size_t N, typename FIRST, typename... OTHERS>
  236. decltype(auto) get(Tuple<FIRST, OTHERS...>&& tuple) {
  237. return GetByNum<N, FIRST, OTHERS...>::action(move(tuple));
  238. };
  239.  
  240. // Get By Type
  241.  
  242. template <typename T, typename FIRST, typename... OTHERS>
  243. struct GetByType {
  244. static T& action (Tuple<FIRST, OTHERS...>& tuple) {
  245. return GetByType<T, OTHERS...>::action(tuple._others);
  246. }
  247.  
  248. static const T& action (const Tuple<FIRST, OTHERS...>& tuple) {
  249. return GetByType<T, OTHERS...>::action(tuple._others);
  250. }
  251.  
  252. static T&& action (Tuple<FIRST, OTHERS...>&& tuple) {
  253. return GetByType<T, OTHERS...>::action(move(tuple._others));
  254. }
  255. };
  256.  
  257. template <typename T, typename... OTHERS>
  258. struct GetByType<T, T, OTHERS...> {
  259. static T& action (Tuple<T, OTHERS...>& tuple) {
  260. return tuple._fst;
  261. }
  262.  
  263. static T&& action (Tuple<T, OTHERS...>&& tuple) {
  264. return move(tuple._fst);
  265. }
  266.  
  267. static const T& action (const Tuple<T, OTHERS...>& tuple) {
  268. return tuple._fst;
  269. }
  270. };
  271.  
  272. template <typename T, typename FIRST, typename... OTHERS>
  273. T& get(Tuple<FIRST, OTHERS...>& tuple) {
  274. return GetByType<T, FIRST, OTHERS...>::action(tuple);
  275. };
  276.  
  277. template <typename T, typename FIRST, typename... OTHERS>
  278. const T& get(const Tuple<FIRST, OTHERS...>& tuple) {
  279. return GetByType<T, FIRST, OTHERS...>::action(tuple);
  280. };
  281.  
  282. template <typename T, typename FIRST, typename... OTHERS>
  283. T&& get(Tuple<FIRST, OTHERS...>&& tuple) {
  284. return GetByType<T, FIRST, OTHERS...>::action(move(tuple));
  285. };
  286.  
  287. // Compare
  288.  
  289. template <typename FIRST, typename... OTHERS>
  290. struct Compares {
  291. static bool equial(const Tuple<FIRST, OTHERS...>& fst,
  292. const Tuple<FIRST, OTHERS...>& scnd) {
  293. if (fst._fst == scnd._fst) {
  294. return Compares<OTHERS...>::equial(fst._others, scnd._others);
  295. } else {
  296. return false;
  297. }
  298. };
  299.  
  300. static bool less(const Tuple<FIRST, OTHERS...>& fst,
  301. const Tuple<FIRST, OTHERS...>& scnd) {
  302. if (fst._fst == scnd._fst) {
  303. return Compares<OTHERS...>::less(fst._others, scnd._others);
  304. } else {
  305. return fst._fst < scnd._fst;
  306. }
  307. };
  308. };
  309.  
  310. template <typename T>
  311. struct Compares<T> {
  312. static bool equial(const Tuple<T>& fst,
  313. const Tuple<T>& scnd) {
  314. return fst._fst == scnd._fst;
  315. }
  316.  
  317. static bool less(const Tuple<T>& fst,
  318. const Tuple<T>& scnd) {
  319. return fst._fst < scnd._fst;
  320. }
  321. };
  322.  
  323. template <typename FIRST, typename... OTHERS>
  324. bool operator==(const Tuple<FIRST, OTHERS...>& fst,
  325. const Tuple<FIRST, OTHERS...>& scnd) {
  326. return Compares<FIRST, OTHERS...>::equial(fst, scnd);
  327. };
  328.  
  329. template <typename FIRST, typename... OTHERS>
  330. bool operator!=(const Tuple<FIRST, OTHERS...>& fst,
  331. const Tuple<FIRST, OTHERS...>& scnd) {
  332. return not (fst == scnd);
  333. };
  334.  
  335. template <typename FIRST, typename... OTHERS>
  336. bool operator<(const Tuple<FIRST, OTHERS...>& fst,
  337. const Tuple<FIRST, OTHERS...>& scnd) {
  338. return Compares<FIRST, OTHERS...>::less(fst, scnd);
  339. };
  340.  
  341. template <typename FIRST, typename... OTHERS>
  342. bool operator>(const Tuple<FIRST, OTHERS...>& fst,
  343. const Tuple<FIRST, OTHERS...>& scnd) {
  344. return scnd < fst;
  345. };
  346.  
  347. template <typename FIRST, typename... OTHERS>
  348. bool operator>=(const Tuple<FIRST, OTHERS...>& fst,
  349. const Tuple<FIRST, OTHERS...>& scnd) {
  350. return not (fst < scnd);
  351. };
  352.  
  353. template <typename FIRST, typename... OTHERS>
  354. bool operator<=(const Tuple<FIRST, OTHERS...>& fst,
  355. const Tuple<FIRST, OTHERS...>& scnd) {
  356. return not (scnd < fst);
  357. };
  358.  
  359.  
  360. template <typename TUPLE1, typename TUPLE2>
  361. class Cat2;
  362.  
  363. template <typename FST1, typename... OTH1, typename FST2, typename... OTH2>
  364. struct Cat2<Tuple<FST1, OTH1...>, Tuple<FST2, OTH2...> > {
  365. static Tuple<FST1, OTH1..., FST2, OTH2...>
  366. action(Tuple<FST1, OTH1...> ftup,
  367. Tuple<FST2, OTH2...> stup) {
  368. return Tuple<FST1, OTH1..., FST2, OTH2...>
  369. (move(ftup._fst), Cat2<Tuple<OTH1...>,
  370. Tuple<FST2, OTH2...> >::action(move(ftup._others), move(stup)));
  371. }
  372. };
  373.  
  374. template <typename T, typename FST, typename... OTH>
  375. struct Cat2<Tuple<T>, Tuple<FST, OTH...> > {
  376. static Tuple<T, FST, OTH...>
  377. action(Tuple<T> ftup,
  378. Tuple<FST, OTH...> stup) {
  379. return Tuple<T, FST, OTH...>(move(ftup._fst), move(stup));
  380. }
  381. };
  382.  
  383.  
  384. template <typename... TUPS>
  385. struct ResOfCat;
  386.  
  387. template <typename TUP>
  388. struct ResOfCat<TUP> {
  389. typedef TUP type;
  390. };
  391.  
  392. template <typename FST1, typename... OTH1, typename FST2, typename... OTH2>
  393. struct ResOfCat <Tuple<FST1, OTH1...>, Tuple<FST2, OTH2...> > {
  394. typedef Tuple<FST1, OTH1..., FST2, OTH2...> type;
  395. };
  396.  
  397. template <typename TUP1, typename... TUPOTH>
  398. struct ResOfCat <TUP1, TUPOTH...> {
  399. typedef typename ResOfCat<TUP1, typename ResOfCat<TUPOTH...>::type>::type type;
  400. };
  401.  
  402.  
  403. template <typename TUPFST, typename... TUPOTH>
  404. struct Cat {
  405. typedef Cat<TUPOTH...> son;
  406. typedef typename ResOfCat<TUPFST, TUPOTH...>::type result;
  407.  
  408. static result
  409. action(TUPFST fst, TUPOTH... oth) {
  410. return Cat2<TUPFST, typename son::result>::action(move(fst),
  411. son::action(move(oth)...));
  412. }
  413. };
  414.  
  415. template <typename TUP>
  416. struct Cat<TUP> {
  417. typedef TUP result;
  418. static TUP action(TUP tuple) { return tuple; }
  419. };
  420.  
  421. template <typename... TUPS>
  422. decltype(auto) tupleCat(TUPS&&... tups) {
  423. return Cat<std::remove_const_t<std::remove_reference_t<TUPS> >...>::
  424. action(forward<TUPS>(tups)...);
  425. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement