Advertisement
Guest User

HOW TO WRITE IN C++11

a guest
Oct 19th, 2017
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.74 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <atomic>
  3. #include <thread>
  4. #include <memory>
  5. #include <iostream>
  6. #include <mutex>
  7. #include <vector>
  8.  
  9. template<typename T>
  10. struct number
  11. {
  12.         virtual T inc() = 0;
  13.         virtual T load() const = 0;
  14.         virtual void store(T n) = 0;
  15.         virtual bool cond_store(T n, T& des) = 0;
  16. };
  17.  
  18. template<typename T>
  19. struct atomic_number : public number<T>
  20. {
  21.         virtual T atomic_inc() = 0;
  22.         virtual T atomic_load() const = 0;
  23.         virtual void atomic_store(T n) = 0;
  24.         virtual bool compare_and_swap(T val, T& des) = 0;
  25.  
  26.         T inc() override
  27.         {
  28.                 return atomic_inc();
  29.         }
  30.  
  31.         T load() const override
  32.         {
  33.                 return atomic_load();
  34.         }
  35.  
  36.         void store(T n) override
  37.         {
  38.                 atomic_store(n);
  39.         }
  40.  
  41.         bool cond_store(T n, T& des) override
  42.         {
  43.                 return compare_and_swap(n, des);
  44.         }
  45. };
  46.  
  47. template<typename T>
  48. struct my_atomic_number
  49.         : public atomic_number<T>
  50. {
  51.         explicit my_atomic_number(T i)
  52.                 : i_(i)
  53.         {}
  54.  
  55.         T atomic_inc() final
  56.         {
  57.                 return i_.fetch_add(1, std::memory_order_seq_cst);
  58.         }
  59.  
  60.         T atomic_load() const final
  61.         {
  62.                 return i_.load(std::memory_order_seq_cst);
  63.         }
  64.  
  65.         void atomic_store(T n) final
  66.         {
  67.                 i_.store(n, std::memory_order_seq_cst);
  68.         }
  69.  
  70.         bool compare_and_swap(T val, T& des) final
  71.         {
  72.                 return i_.compare_exchange_strong(des,
  73.                                                   val,
  74.                                                   std::memory_order_seq_cst);
  75.         }
  76.  
  77. private:
  78.         std::atomic<T> i_;
  79. };
  80.  
  81. template<typename T>
  82. struct abstract_number;
  83.  
  84. template<typename T>
  85. struct abstract_number_creator_interface
  86. {
  87.         virtual
  88.         std::shared_ptr<abstract_number<T>>
  89.         create_new(T val) = 0;
  90. };
  91.  
  92. template<typename T>
  93. struct abstract_number
  94.         : std::enable_shared_from_this<abstract_number<T>>
  95. {
  96.         abstract_number(std::shared_ptr<number<T>> n,
  97.                         std::shared_ptr<
  98.                                 abstract_number_creator_interface<T>> creator)
  99.                 : n_(n), creator_(creator)
  100.         {
  101.         }
  102.  
  103.         std::shared_ptr<abstract_number<T>>
  104.         operator++(int)
  105.         {
  106.                 T cur = n_->load();
  107.                 T des = cur + 1;
  108.  
  109.                 while(!n_->cond_store(des, cur))
  110.                 {
  111.                         des = cur + 1;
  112.                 }
  113.  
  114.                 auto prev = creator()->create_new(cur);
  115.  
  116.                 return prev;
  117.         }
  118.  
  119.         std::shared_ptr<abstract_number<T>>
  120.         operator++()
  121.         {
  122.                 T val = n_->inc();
  123.  
  124.                 return this->shared_from_this();
  125.         }
  126.  
  127.         std::shared_ptr<abstract_number<T>>
  128.         operator=(std::shared_ptr<abstract_number<T>> other)
  129.         {
  130.                 if(this->shared_from_this() == other)
  131.                         return this->shared_from_this();
  132.  
  133.                 T val = other->value();
  134.                 n_->store(val);
  135.  
  136.                 return this->shared_from_this();
  137.  
  138.         }
  139.  
  140.         std::shared_ptr<abstract_number<T>>
  141.         operator+=(std::shared_ptr<abstract_number<T>> b)
  142.         {
  143.                 T cur = n_->load();
  144.                 T des = cur + b->value();
  145.  
  146.                 while(!n_->cond_store(des, cur))
  147.                 {
  148.                         des = cur + b->value();
  149.                 }
  150.  
  151.                 return this->shared_from_this();
  152.         }
  153.  
  154.         bool operator<=(std::shared_ptr<abstract_number<T>> b)
  155.         {
  156.                 return this->value() <= b->value();
  157.         }
  158.  
  159.         T value() const
  160.         {
  161.                 return n_->load();
  162.         }
  163.  
  164.         std::shared_ptr<abstract_number<T>>
  165.         copy()
  166.         {
  167.                 return creator()->create_new(value());
  168.         }
  169.  
  170.         std::shared_ptr<abstract_number_creator_interface<T>> creator()
  171.         {
  172.                 return creator_;
  173.         }
  174.  
  175. private:
  176.         std::shared_ptr<number<T>> n_;
  177.         std::shared_ptr<abstract_number_creator_interface<T>> creator_;
  178. };
  179.  
  180. template<typename T>
  181. struct number_creator
  182. {
  183.         std::shared_ptr<number<T>> create_new(T val)
  184.         {
  185.                 return std::make_shared<my_atomic_number<T>>(val);
  186.         }
  187. };
  188.  
  189. template<typename T>
  190. struct shared_abstract_number_creator :
  191.         abstract_number_creator_interface<T>,
  192.         std::enable_shared_from_this<shared_abstract_number_creator<T>>
  193. {
  194.  
  195. };
  196.  
  197. template<typename T>
  198. struct abstract_number_creator :
  199.         public shared_abstract_number_creator<T>
  200.  
  201. {
  202.         abstract_number_creator()
  203.                 : ncreator_(std::make_shared<number_creator<T>>())
  204.         {}
  205.  
  206.         std::shared_ptr<abstract_number<T>>
  207.         create_new(T val) override
  208.         {
  209.                 std::unique_lock<std::mutex> lock(mtx_);
  210.  
  211.                 return std::make_shared<abstract_number<T>>(
  212.                                 ncreator_->create_new(val),
  213.                                 this->shared_from_this()
  214.                 );
  215.         }
  216.  
  217. private:
  218.         std::shared_ptr<number_creator<T>> ncreator_;
  219.         std::mutex mtx_;
  220. };
  221.  
  222. template<typename T>
  223. std::ostream& operator<<(std::ostream& os, std::shared_ptr<abstract_number<T>> n)
  224. {
  225.         os << n->value();
  226. }
  227.  
  228. template<typename T, typename X>
  229. void print_numbers(X n0, X n1, X s)
  230. {
  231.         static std::mutex mtx;
  232.  
  233.         std::unique_lock<std::mutex> lock(mtx);
  234.  
  235.         std::cout<<"n0="<<n0<<" n1="<<n1<<" s="<<s<<std::endl;
  236. };
  237.  
  238.  
  239. template<typename T>
  240. static void sum(std::shared_ptr<abstract_number<T>> sum,
  241.                        std::shared_ptr<abstract_number<T>> n0,
  242.                        std::shared_ptr<abstract_number<T>> n1)
  243. {
  244.         auto number_creator = sum->creator();
  245.         auto s = number_creator->create_new(0);
  246.  
  247.         s->operator=(n0);
  248.  
  249.         while(n0->operator<=(n1)) {
  250.  
  251.                 print_numbers<T>(n0, n1, s);
  252.                 s->operator+=(n0->operator++(1));
  253.         }
  254.  
  255.  
  256.         sum->operator=(s);
  257. }
  258.  
  259.  
  260. template<typename T>
  261. struct parallel_sum
  262. {
  263.         T operator()(std::shared_ptr<abstract_number<T>> sum,
  264.                      std::shared_ptr<abstract_number<T>> n0,
  265.                      std::shared_ptr<abstract_number<T>> n1)
  266.         {
  267.                 std::vector<std::thread> pool;
  268.                 auto n = std::thread::hardware_concurrency();
  269.  
  270.                 T slice = (n1->value() - n0->value()) / (T)n;
  271.                 for(decltype(n) i = 0; i < n; ++i)
  272.                 {
  273.  
  274.                         T l = slice * i;
  275.                         T r = slice * (i + 1);
  276.  
  277.                         if(i + 1 == n)
  278.                                 r = n1->value();
  279.  
  280.  
  281.                         auto my_elegant_modern_cpp11_lamda_function_for_extra_code_clarity =
  282.                         [](std::shared_ptr<abstract_number<T>> sum,
  283.                         std::shared_ptr<abstract_number<T>> n0,
  284.                         std::shared_ptr<abstract_number<T>> n1)
  285.                         {
  286.                                 auto number_creator = sum->creator();
  287.                                 auto s = number_creator->create_new(0);
  288.  
  289.                                 s->operator=(n0);
  290.  
  291.                                 while(n0->operator<=(n1)) {
  292.  
  293.                                         print_numbers<T>(n0, n1, s);
  294.                                         s->operator+=(n0->operator++(1));
  295.                                 }
  296.  
  297.  
  298.                                 sum->operator=(s);
  299.                         };
  300.  
  301.                         auto ln0 = n0->creator()->create_new(l);
  302.                         auto rn1 = n1->creator()->create_new(r);
  303.  
  304.                         pool.push_back(std::thread(my_elegant_modern_cpp11_lamda_function_for_extra_code_clarity,
  305.                                                    sum, ln0, rn1));
  306.                 }
  307.  
  308.                 for(auto& t : pool)
  309.                         t.join();
  310.         }
  311. };
  312.  
  313.  
  314. template<typename T>
  315. T do_shit()
  316. {
  317.         auto ncreator = std::make_shared<abstract_number_creator<T>>();
  318.  
  319.         auto sum = ncreator->create_new(0);
  320.         auto n0  = ncreator->create_new(0);
  321.         auto n1  = ncreator->create_new(100);
  322.  
  323.         parallel_sum<T>()(sum, n0, n1);
  324.  
  325.         return sum->value();
  326. }
  327.  
  328.  
  329. int main(int argc, char** argv)
  330. {
  331.         auto shit = do_shit<uint64_t >();
  332.  
  333.  
  334.         // RESULT CAN BE KIND OF UNEXPECTED BUT
  335.         // THIS
  336.         // IS
  337.         // POWER
  338.         // OF
  339.         // C++11
  340.         // FUCK YEAH!
  341.         std::cout << "shit = " << shit << std::endl;
  342.  
  343.  
  344.         return 0;
  345. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement