1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
#ifndef BOOK_STORE_HH
#define BOOK_STORE_HH
#include <cctype>
#include <cstddef>
#include <functional>
#include <optional>
#include <string_view>
#include <utility>
#include <vector>
#include <book_store/book.hh>
#include <book_store/book_count.hh>
#include <book_store/customer.hh>
#include <book_store/price.hh>
#include <book_store/purchase_error.hh>
namespace book_store {
class store {
private:
using books_type = std::vector<product::book>;
using customer_type = consumer::customer;
using customer_container = std::vector<customer_type>;
// An `std::unordered_map` would be more appropriate here, but
// here we are. While we aren't using a proper database, we can
// take these liberties.
using transactions_type = std::vector<std::pair<std::size_t, product::book>>;
using discount_percent_type = double;
using size_type = std::size_t;
size_type _books_max_size;
size_type _customers_max_size;
books_type _books;
customer_container _customers;
transactions_type _transactions;
product::price::usd _membership_fee;
discount_percent_type _membership_discount_percent;
public:
store() = default;
store(size_type books_max_size, size_type customers_max_size)
: _books_max_size(books_max_size),
_customers_max_size(customers_max_size) {}
store(size_type books_max_size, size_type customers_max_size,
product::price::usd membership_fee,
discount_percent_type membership_discount_percent)
: _books_max_size(books_max_size),
_customers_max_size(customers_max_size),
_membership_fee(membership_fee),
_membership_discount_percent(membership_discount_percent) {}
store(const store &) = default;
store(store &&) = default;
auto append_book(const product::book &book) -> void;
auto append_customer(const customer_type &person) -> void;
auto
purchase_book(size_type person_id, std::string_view isbn,
product::book_count count) -> std::optional<purchase_error>;
auto tick_year() -> void;
auto membership_fee(product::price::usd fee) -> void;
auto
membership_discount_percent(discount_percent_type discount_percent) -> void;
[[nodiscard]] auto books_size() const noexcept -> size_type;
[[nodiscard]] auto people_size() const noexcept -> size_type;
[[nodiscard]] auto books_max_size() const noexcept -> size_type;
[[nodiscard]] auto people_max_size() const noexcept -> size_type;
[[nodiscard]] auto membership_fee() const noexcept -> product::price::usd;
[[nodiscard]] auto
membership_discount_percent() const noexcept -> discount_percent_type;
auto find_person_by_id(size_type person_id) -> std::optional<customer_type>;
auto find_book_by_isbn(std::string_view isbn)
-> std::optional<std::reference_wrapper<product::book>>;
auto
find_books_by_title(std::string_view title) -> std::vector<product::book>;
auto
find_books_by_author(std::string_view name) -> std::vector<product::book>;
auto transactions_by_id(size_type person_id) -> std::vector<product::book>;
auto books() -> books_type &;
auto people() -> customer_container &;
auto operator=(const store &) -> store & = default;
auto operator=(store &&) -> store & = default;
};
} // namespace book_store
#endif // BOOK_STORE_HH
|