Advertisement
quark_zju

cpp1y_experiment_1.cpp

Jul 25th, 2014
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // compile with -std=c++1y
  2.  
  3. #include <algorithm>
  4. #include <array>
  5. #include <ext/algorithm>
  6. #include <functional>
  7. #include <iterator>
  8. #include <vector>
  9.  
  10. namespace LoDash {
  11.  
  12. using std::begin;
  13. using std::end;
  14. using std::vector;
  15. using std::function;
  16.  
  17. struct LoDash {
  18.   template<typename T>
  19.   auto _pure_typeof(T x) -> typename std::remove_const<typename std::remove_reference<decltype(x)>::type>::type { };
  20.  
  21.   template<typename L>
  22.   void each(const L& list, function<void(decltype(*begin(list))&)> func) {
  23.     for (auto& i: list) func(i);
  24.   }
  25.  
  26.   template<typename L>
  27.   size_t count(const L& list) {
  28.     return (size_t) std::distance(begin(list), end(list));
  29.   }
  30.  
  31.   template<typename L>
  32.   size_t count(const L& list, function<bool(decltype(*begin(list)))> func) {
  33.     return (size_t) std::count_if(begin(list), end(list), func);
  34.   }
  35.  
  36.   template<typename L, typename F>
  37.   auto map(const L& list, F func) -> vector<decltype(func(*begin(list)))>  {
  38.     typedef decltype(func(*begin(list))) FR;
  39.     vector<FR> result;
  40.     result.resize(count(list));
  41.     std::transform(begin(list), end(list), result.begin(), func);
  42.     return result;
  43.   }
  44.  
  45.   template<typename L>
  46.   auto select(const L& list, function<bool(decltype(*begin(list)))> func) -> vector<decltype(_pure_typeof(*begin(list)))> {
  47.     vector<decltype(_pure_typeof(*begin(list)))> result;
  48.     std::copy_if(begin(list), end(list), std::back_inserter(result), func);
  49.     return result;
  50.   }
  51.  
  52.   template<typename L>
  53.   auto sample(const L& list, size_t n) -> vector<decltype(_pure_typeof(*begin(list)))> {
  54.     vector<decltype(_pure_typeof(*begin(list)))> result;
  55.     result.resize(n);
  56.     // random_sample_n is a SGI extension
  57.     __gnu_cxx::random_sample_n(begin(list), end(list), result.begin(), n);
  58.     return result;
  59.   }
  60.  
  61.   template<typename L>
  62.   auto sample(const L& list) -> decltype(_pure_typeof(*begin(list))) {
  63.     std::array<decltype(_pure_typeof(*begin(list))), 1> arr;
  64.     __gnu_cxx::random_sample_n(begin(list), end(list), arr.begin(), 1);
  65.     return arr[0];
  66.   }
  67.  
  68.   template<typename L>
  69.   auto sort(const L& list) -> vector<decltype(_pure_typeof(*begin(list)))> {
  70.     vector<decltype(_pure_typeof(*begin(list)))> result;
  71.     result.reserve(count(list));
  72.     std::copy(begin(list), end(list), std::back_inserter(result));
  73.     std::stable_sort(result.begin(), result.end());
  74.     return result;
  75.   }
  76.  
  77.   template<typename L>
  78.   auto min(const L& list) -> decltype(_pure_typeof(*begin(list))) {
  79.     decltype(_pure_typeof(*begin(list))) result = *begin(list);
  80.     each(list, [&] (auto x) { if (x < result) result = x;});
  81.     return result;
  82.   }
  83.  
  84.   template<typename L>
  85.   auto max(const L& list) -> decltype(_pure_typeof(*begin(list))) {
  86.     decltype(_pure_typeof(*begin(list))) result = *begin(list);
  87.     each(list, [&] (auto x) { if (x > result) result = x;});
  88.     return result;
  89.   }
  90.  
  91.   template<typename L, typename F>
  92.   auto min_by(const L& list, F func) -> decltype(_pure_typeof(*begin(list))) {
  93.     typedef decltype(func(*begin(list))) FR;
  94.     if (count(list) == 0) return FR();
  95.     decltype(_pure_typeof(*begin(list))) result = *begin(list);
  96.     FR val = func(*begin(list));
  97.     each(list, [&] (auto x) { if (x != result) { FR tmp = func(x); if (func(x) < val) {result = x; val = tmp; }}});
  98.     return result;
  99.   }
  100.  
  101.   template<typename L, typename F>
  102.   auto max_by(const L& list, F func) -> decltype(_pure_typeof(*begin(list))) {
  103.     typedef decltype(func(*begin(list))) FR;
  104.     if (count(list) == 0) return FR();
  105.     decltype(_pure_typeof(*begin(list))) result = *begin(list);
  106.     FR val = func(*begin(list));
  107.     each(list, [&] (auto x) { if (x != result) { FR tmp = func(x); if (func(x) > val) {result = x; val = tmp; }}});
  108.     return result;
  109.   }
  110. };
  111.  
  112. }
  113.  
  114. auto _ = LoDash::LoDash();
  115.  
  116. #include <set>
  117. #include <iostream>
  118. #include <string>
  119.  
  120. #define lambda [&]
  121. #define P(r) { std::cout << "[ "; _.each((r), lambda (auto x) { std::cout << x << " ";}); std::cout << "]\n"; }
  122.  
  123. int main(int argc, char const *argv[]) {
  124.   int a[] = {1, 2, 3, 4};
  125.   std::set<int> s = {8, 7, 6, 5};
  126.   std::vector<int> v = {9, 10, 11, 12};
  127.  
  128.   P(a); // 1 2 3 4
  129.   P(s); // 5 6 7 8
  130.   P(v); // 9 10 11 12
  131.  
  132.   P(_.map(s, lambda (auto x) { return -x; })); // -5 -6 -7 -8
  133.   P(_.map(v, lambda (auto x) { return (char)('a' + x); })); // j k l m
  134.   P(_.select(v, lambda (auto x) { return (x & 1); })); // 9 11
  135.   P(_.sample(s, 3));
  136.   P(_.sort(a)); // 1 2 3 4
  137.  
  138.   std::cout << _.sample(a) << "\n"; // 1 or 2 or 3 or 4
  139.   std::cout << _.count(a, lambda (auto x) { return x > 1; }) << "\n"; // 3
  140.   std::cout << _.min(a) << "\n"; // 1
  141.   std::cout << _.min_by(a, lambda (int x) {return -x;}) << "\n"; // 4
  142. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement