Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef BANK_H
- #define BANK_H
- #include <condition_variable>
- #include <iostream>
- #include <map>
- #include <memory>
- #include <mutex>
- #include <stdexcept>
- #include <string>
- #include <vector>
- namespace bank {
- struct transfer_error : std::runtime_error {
- explicit transfer_error(std::string &&message)
- : std::runtime_error(message) {
- }
- };
- struct not_enough_funds_error : transfer_error {
- explicit not_enough_funds_error(const int a, const int b)
- : transfer_error("Not enough funds: " + std::to_string(a) +
- " XTS available, " + std::to_string(b) +
- " XTS requested") {
- }
- };
- struct user;
- struct transaction {
- // NOLINTNEXTLINE
- const user *const counterparty;
- // NOLINTNEXTLINE
- const int balance_delta_xts;
- // NOLINTNEXTLINE
- const std::string comment;
- transaction(const user *tmp, int summa, std::string comment_)
- : counterparty(tmp),
- balance_delta_xts(summa),
- comment(std::move(comment_)) {
- }
- };
- struct user_transactions_iterator {
- private:
- int size_ = 0;
- const user *pointer_on_user;
- public:
- user_transactions_iterator(const int a, const user *pointer)
- : size_(a), pointer_on_user(pointer) {
- }
- transaction wait_next_transaction();
- };
- struct user {
- private:
- std::string user_name;
- int balance = 0;
- mutable std::mutex user_mutex;
- std::vector<transaction> operations;
- mutable std::condition_variable cond;
- public:
- explicit user() = default;
- explicit user(const std::string &new_name)
- : user_name(new_name), balance(100) {
- std::unique_lock ul(user_mutex);
- operations.emplace_back(nullptr, 100,
- "Initial deposit for " + new_name);
- cond.notify_all();
- }
- void transfer(user &counterparty,
- int amount_xts,
- const std::string &comment);
- int balance_xts() const {
- std::unique_lock ul(user_mutex);
- return balance;
- }
- user_transactions_iterator monitor() const noexcept {
- std::unique_lock ul(user_mutex);
- return {static_cast<int>(operations.size()), this};
- }
- template <typename T>
- user_transactions_iterator snapshot_transactions(const T &functor) const {
- std::unique_lock ul(user_mutex);
- functor(operations, balance);
- return {static_cast<int>(operations.size()), this};
- }
- [[nodiscard]] std::string name() const noexcept {
- return user_name;
- }
- friend user_transactions_iterator;
- };
- struct ledger {
- private:
- std::map<std::string, user> users;
- std::mutex ledger_mutex;
- public:
- ledger() = default;
- user &get_or_create_user(const std::string &name) noexcept {
- std::unique_lock l(ledger_mutex);
- if (users.count(name) == 0) {
- // cppcheck-suppress stlFindInsert
- users.emplace(name, name);
- }
- return users[name];
- }
- };
- } // namespace bank
- #endif
Add Comment
Please, Sign In to add comment