Advertisement
Guest User

Untitled

a guest
May 20th, 2018
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.54 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <utility>
  4. #include <cassert>
  5. #include <functional>
  6. #include <algorithm>
  7.  
  8.  
  9. template<class...>
  10. class Tuple;
  11.  
  12. template <>
  13. class Tuple<> {
  14. public:
  15.     void swap(Tuple&) {}
  16.    
  17.     bool operator ==(const Tuple&) const {
  18.         return true;
  19.     }
  20.     bool operator !=(const Tuple&) const {
  21.         return false;
  22.     }
  23.     bool operator <=(const Tuple&) const {
  24.         return true;
  25.     }
  26.     bool operator >=(const Tuple&) const {
  27.         return true;
  28.     }
  29.     bool operator <(const Tuple&) const {
  30.         return false;
  31.     }
  32.     bool operator >(const Tuple&) const {
  33.         return false;
  34.     }
  35.    
  36. };
  37.  
  38. template<class First, class... Others>
  39. class Tuple<First, Others...> {
  40. public:
  41.     Tuple() : _first() {}
  42.    
  43.     Tuple(const Tuple&) = default;
  44.     Tuple(Tuple&&) noexcept = default;
  45.    
  46.     template<class T, class... U>
  47.     explicit Tuple(T&& first, U&&... others) noexcept : _first(std::forward<T>(first)), _other(std::forward<U>(others)...) {}
  48.    
  49.    
  50.    
  51.     Tuple& operator=(const Tuple&) = default;
  52.     Tuple& operator=(Tuple&&) = default;
  53.    
  54.    
  55.     template <class... U>
  56.     friend class Tuple;
  57.    
  58.     void swap(Tuple& other) {
  59.         std::swap(_first, other._first);
  60.         _other.swap(other._other);
  61.     }
  62.    
  63.     bool operator ==(const Tuple& t) const {
  64.         return _first == t._first && _other == t._other;
  65.     }
  66.    
  67.     bool operator < (const Tuple& t) const {
  68.         return _first < t._first || (_first == t._first && _other < t._other);
  69.     }
  70.    
  71.     bool operator > (const Tuple& t) const {
  72.         return _first > t._first || (_first == t._first && _other > t._other);
  73.     }
  74.    
  75.     bool operator !=(const Tuple& t) const {
  76.         return !(*this == t);
  77.     }
  78.    
  79.     bool operator <=(const Tuple& t) const {
  80.         return !(*this > t);
  81.     }
  82.    
  83.     bool operator >=(const Tuple& t) const {
  84.         return !(*this < t);
  85.     }
  86.    
  87.     template<size_t I, class Tpl, typename std::enable_if_t<(I > 0), int> = 0>
  88.     decltype(auto) Get(Tpl&& t) {
  89.         return Get<I - 1>(t._other);
  90.     }
  91.    
  92.     template<size_t I, class Tpl, typename std::enable_if_t<(I == 0), int> = 0>
  93.     decltype(auto) Get(Tpl&& t) {
  94.         return (std::forward<Tpl>(t)._first);
  95.     }
  96.    
  97.     template <typename T, typename Tpl, typename std::enable_if_t<std::is_same<decltype(std::decay_t<Tpl>::_first), T>::value, int> = 0>
  98.     decltype(auto) Get(Tpl&& t) {
  99.         return (std::forward<Tpl>(t)._first);
  100.     }
  101.    
  102.     template <typename T, typename Tpl, typename std::enable_if_t<!std::is_same<decltype(std::decay_t<Tpl>::_first), T>::value, int> = 0>
  103.     decltype(auto) Get(Tpl&& t) {
  104.         return Get<T>(std::forward<Tpl>(t)._other);
  105.     }
  106.    
  107.     template<class T, class U>
  108.     decltype(auto) getTuple(T&& l, U&& r) {
  109.         return mergeTuple(std::move(l), std::move(r));
  110.     }
  111.    
  112.     template <class T>
  113.     decltype(auto) getTuple(Tuple<> tup, T&& t) {
  114.         return std::move(t);
  115.     }
  116.    
  117.     template<class F, class... Others1, class... Others2>
  118.     decltype(auto) getTup(Tuple<F, Others1...>&& tup1, Tuple<Others2...>&& tup2) {
  119.         return Tuple<F, Others1..., Others2...>(std::move(tup1._first), tupleCat2(std::move(tup1._other), std::move(tup2)));
  120.     }
  121.    
  122.    
  123.     template <typename... Others1>
  124.     decltype(auto) getTup(Tuple<>, Tuple<Others1...>&& tup) {
  125.         return std::move(tup);
  126.     }
  127.    
  128. private:
  129.     First _first;
  130.     Tuple<Others...> _other;
  131.     explicit Tuple(First&& first, Tuple<Others...>&& tup) noexcept : _first(std::move(first)), _other(std::move(tup)) {}
  132. };
  133.  
  134.  
  135.  
  136. template <size_t I, class Tpl>
  137. decltype(auto) get(Tpl&& t){
  138.     return t.template Get<I, Tpl>(std::forward<Tpl>(t));
  139. }
  140.  
  141. template <class T, class Tpl>
  142. decltype(auto) get(Tpl&& t) {
  143.     return t.template Get<T, Tpl>(std::forward<Tpl>(t));
  144. }
  145.  
  146. template<class... Args>
  147. decltype(auto) makeTuple(Args&&... args) {
  148.     return Tuple<std::decay_t<Args>...>(std::forward<Args>(args)...);
  149. }
  150.  
  151. template<class Tup1, class Tup2>
  152. decltype(auto) tupleCat2(Tup1&& tup1, Tup2&& tup2) {
  153.     return tup1.getTup(std::move(tup1), std::move(tup2));
  154. }
  155.  
  156. template <class Tup>
  157. decltype(auto) tupleCat2(Tuple<>, Tup&& tup) {
  158.     return std::move(tup);
  159. }
  160.  
  161. template<class Tup1, class... Others>
  162. decltype(auto) tupleCat(Tup1&& tup, Others&&... others) {
  163.     return tupleCat2(std::forward<Tup1>(tup), tupleCat(std::forward<Others>(others)...));
  164. }
  165.  
  166. template <class Tup>
  167. decltype(auto) tupleCat(Tup&& tup) {
  168.     return std::move(tup);
  169. }
  170.  
  171.  
  172. void test_tuple() {
  173.    
  174.     {
  175.         Tuple<int, std::string, long> tuple;
  176.     }
  177.    
  178.     {
  179.         int test_int = 5;
  180.         std::string test_string = "Hello";
  181.         Tuple<int, std::string> tuple(test_int, test_string);
  182.     }
  183.    
  184.     {
  185.         int test_int = 5;
  186.         std::string test_string = "Hello";
  187.         std::vector<int> test_vector(10, 5);
  188.         Tuple<int, std::string, std::vector<int>> tuple(test_int, test_string, std::move(test_vector));
  189.     }
  190.    
  191.     {
  192.         std::string test_string = "Hello";
  193.         std::vector<int> test_vector(10, 5);
  194.         Tuple<std::string, std::vector<int>> tuple(std::move(test_string), std::move(test_vector));
  195.     }
  196.    
  197.     {
  198.         Tuple<int> first(5);
  199.         auto second = first;
  200.         first.swap(second);
  201.        
  202.         auto third = std::move(first);
  203.        
  204.         assert(third == second);
  205.     }
  206.    
  207.     {
  208.         Tuple<int> first(12);
  209.         auto second = first;
  210.         assert(get<0>(first) == get<0>(second));
  211.        
  212.         second = Tuple<int>(14);
  213.         assert(get<0>(second) == 14);
  214.        
  215.         first.swap(second);
  216.         assert(get<0>(second) == 12);
  217.         assert(get<0>(first) == 14);
  218.        
  219.         int&& test_int = get<0>(std::move(first));
  220.         assert(test_int == 14);
  221.     }
  222.    
  223.     {
  224.         Tuple<int, long> tuple(12, 16);
  225.         assert(get<int>(tuple) == 12);
  226.         assert(get<long>(tuple) == 16);
  227.        
  228.         int test_int_lv = get<int>(tuple);
  229.         int&& test_int_rv = get<int>(std::move(tuple));
  230.         assert(test_int_lv == test_int_rv);
  231.     }
  232.    
  233.     {
  234.         Tuple<int, std::string, std::vector<int>> tuple = makeTuple(5, std::string("test"), std::vector<int>(2, 5));
  235.         get<2>(tuple)[1] = 2;
  236.         assert(get<2>(tuple)[1] == 2);
  237.     }
  238.    
  239.     {
  240.         int test_int = 1;
  241.         auto tuple = makeTuple(test_int, std::ref(test_int));
  242.         test_int = 2;
  243.         assert(get<0>(tuple) == 1);
  244.         assert(get<1>(tuple) == 2);
  245.     }
  246.    
  247.     {
  248.         std::vector<std::tuple<int, std::string, float>> v;
  249.         v.emplace_back(2, "baz", -0.1);
  250.         v.emplace_back(2, "bar", 3.14);
  251.         v.emplace_back(1, "foo", 100.1);
  252.         std::sort(v.begin(), v.end());
  253.        
  254.         assert(get<0>(v[0]) == 1);
  255.         assert(get<0>(v[1]) == 2);
  256.         assert(get<0>(v[2]) == 2);
  257.        
  258.         assert(get<1>(v[0]) == std::string("foo"));
  259.         assert(get<1>(v[1]) == std::string("bar"));
  260.         assert(get<1>(v[2]) == std::string("baz"));
  261.     }
  262.    
  263.     {
  264.         auto tuple = makeTuple(1, "hello");
  265.         auto test_tuple = tupleCat(tuple, tuple, makeTuple(5, 10));
  266.        
  267.         assert(get<0>(test_tuple) == get<2>(test_tuple));
  268.         assert(get<4>(test_tuple) == 5);
  269.     }
  270.    
  271.    
  272.     for (int i = 0; i < 10000; ++i) {
  273.         Tuple<int, std::vector<int>> tuple(4, std::vector<int>(10000, 5));
  274.         assert(get<int>(tuple) == 4);
  275.     }
  276.    
  277. }
  278.  
  279. int main() {
  280.     test_tuple();
  281.     std::cout << 0;
  282.     return 0;
  283. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement