kolbka_

Bank.h

Feb 12th, 2022 (edited)
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.06 KB | None | 0 0
  1. #ifndef BANK_H
  2. #define BANK_H
  3.  
  4. #include <condition_variable>
  5. #include <iostream>
  6. #include <map>
  7. #include <memory>
  8. #include <mutex>
  9. #include <stdexcept>
  10. #include <string>
  11. #include <vector>
  12. namespace bank {
  13.  
  14. struct transfer_error : std::runtime_error {
  15.     explicit transfer_error(std::string &&message)
  16.         : std::runtime_error(message) {
  17.     }
  18. };
  19.  
  20. struct not_enough_funds_error : transfer_error {
  21.     explicit not_enough_funds_error(const int a, const int b)
  22.         : transfer_error("Not enough funds: " + std::to_string(a) +
  23.                          " XTS available, " + std::to_string(b) +
  24.                          " XTS requested") {
  25.     }
  26. };
  27. struct user;
  28.  
  29. struct transaction {
  30.     // NOLINTNEXTLINE
  31.     const user *const counterparty;
  32.     // NOLINTNEXTLINE
  33.     const int balance_delta_xts;
  34.     // NOLINTNEXTLINE
  35.     const std::string comment;
  36.  
  37.     transaction(const user *tmp, int summa, std::string comment_)
  38.         : counterparty(tmp),
  39.           balance_delta_xts(summa),
  40.           comment(std::move(comment_)) {
  41.     }
  42. };
  43.  
  44. struct user_transactions_iterator {
  45. private:
  46.     int size_ = 0;
  47.     const user *pointer_on_user;
  48.  
  49. public:
  50.     user_transactions_iterator(const int a, const user *pointer)
  51.         : size_(a), pointer_on_user(pointer) {
  52.     }
  53.     transaction wait_next_transaction();
  54. };
  55.  
  56. struct user {
  57. private:
  58.     std::string user_name;
  59.     int balance = 0;
  60.     mutable std::mutex user_mutex;
  61.     std::vector<transaction> operations;
  62.     mutable std::condition_variable cond;
  63.  
  64. public:
  65.     explicit user() = default;
  66.     explicit user(const std::string &new_name)
  67.         : user_name(new_name), balance(100) {
  68.         std::unique_lock ul(user_mutex);
  69.         operations.emplace_back(nullptr, 100,
  70.                                 "Initial deposit for " + new_name);
  71.         cond.notify_all();
  72.     }
  73.  
  74.     void transfer(user &counterparty,
  75.                   int amount_xts,
  76.                   const std::string &comment);
  77.  
  78.     int balance_xts() const {
  79.         std::unique_lock ul(user_mutex);
  80.         return balance;
  81.     }
  82.  
  83.     user_transactions_iterator monitor() const noexcept {
  84.         std::unique_lock ul(user_mutex);
  85.         return {static_cast<int>(operations.size()), this};
  86.     }
  87.  
  88.     template <typename T>
  89.     user_transactions_iterator snapshot_transactions(const T &functor) const {
  90.         std::unique_lock ul(user_mutex);
  91.         functor(operations, balance);
  92.         return {static_cast<int>(operations.size()), this};
  93.     }
  94.  
  95.     [[nodiscard]] std::string name() const noexcept {
  96.         return user_name;
  97.     }
  98.     friend user_transactions_iterator;
  99. };
  100.  
  101. struct ledger {
  102. private:
  103.     std::map<std::string, user> users;
  104.     std::mutex ledger_mutex;
  105.  
  106. public:
  107.     ledger() = default;
  108.     user &get_or_create_user(const std::string &name) noexcept {
  109.         std::unique_lock l(ledger_mutex);
  110.         if (users.count(name) == 0) {
  111.             // cppcheck-suppress stlFindInsert
  112.             users.emplace(name, name);
  113.         }
  114.         return users[name];
  115.     }
  116. };
  117.  
  118. }  // namespace bank
  119.  
  120. #endif
Add Comment
Please, Sign In to add comment