summaryrefslogtreecommitdiff
path: root/include/book_store
diff options
context:
space:
mode:
Diffstat (limited to 'include/book_store')
-rw-r--r--include/book_store/book_count.hh30
-rw-r--r--include/book_store/customer.hh49
-rw-r--r--include/book_store/library.hh13
-rw-r--r--include/book_store/member.hh41
-rw-r--r--include/book_store/person.hh14
-rw-r--r--include/book_store/price.hh18
-rw-r--r--include/book_store/purchase_error.hh26
-rw-r--r--include/book_store/store.hh87
-rw-r--r--include/book_store/utility.hh12
9 files changed, 235 insertions, 55 deletions
diff --git a/include/book_store/book_count.hh b/include/book_store/book_count.hh
index a9c68c1..29e599b 100644
--- a/include/book_store/book_count.hh
+++ b/include/book_store/book_count.hh
@@ -2,7 +2,6 @@
#define BOOK_COUNT_HH
#include <ostream>
-#include <string>
namespace book_store::product {
class book_count {
@@ -16,8 +15,10 @@ public:
book_count() = default;
book_count(book_count_type count) : _count(count) {}
- friend auto operator<<(std::ostream &output_stream, const book_count &price)
- -> std::ostream & {
+ [[nodiscard]] auto value() const noexcept -> book_count_type;
+
+ friend auto operator<<(std::ostream &output_stream,
+ const book_count &price) -> std::ostream & {
output_stream << price._count;
return output_stream;
@@ -27,10 +28,29 @@ public:
return lhs._count == rhs._count;
}
- friend auto operator+(const book_count &lhs, const book_count &rhs)
- -> book_count {
+ friend auto operator+(const book_count &lhs,
+ const book_count &rhs) -> book_count {
return {lhs._count + rhs._count};
}
+
+ friend auto operator<(const book_count &lhs, const book_count &rhs) -> bool {
+ return lhs._count < rhs._count;
+ }
+
+ friend auto operator-(const book_count &lhs,
+ const book_count &rhs) -> book_count {
+ return {lhs._count - rhs._count};
+ }
+
+ friend auto operator%(const book_count &lhs,
+ const book_count &rhs) -> book_count {
+ return {lhs._count % rhs._count};
+ }
+
+ friend auto operator*(const book_count &lhs,
+ const book_count &rhs) -> book_count {
+ return {lhs._count * rhs._count};
+ }
};
} // namespace book_store::product
diff --git a/include/book_store/customer.hh b/include/book_store/customer.hh
new file mode 100644
index 0000000..86f3df6
--- /dev/null
+++ b/include/book_store/customer.hh
@@ -0,0 +1,49 @@
+#ifndef MEMBER_HH
+#define MEMBER_HH
+
+#include <cstddef>
+
+#include "book.hh"
+#include "person.hh"
+#include "price.hh"
+
+namespace book_store::consumer {
+class customer : public person {
+
+private:
+ product::book::book::size_type _books_bought;
+ product::price::usd _amount_spent;
+ bool _is_member;
+
+public:
+ customer(std::string first_name, std::string last_name, std::size_t member_id)
+ : person(std::move(first_name), std::move(last_name), member_id),
+ _books_bought(0), _amount_spent(0) {}
+ customer(std::string first_name, std::string last_name, std::size_t member_id,
+ bool is_member)
+ : person(std::move(first_name), std::move(last_name), member_id),
+ _is_member(is_member) {}
+ customer(std::string first_name, std::string last_name, std::size_t member_id,
+ bool is_member, product::book::size_type books_bought,
+ product::price::usd amount_spent)
+ : person(std::move(first_name), std::move(last_name), member_id),
+ _books_bought(books_bought), _amount_spent(amount_spent),
+ _is_member(is_member) {}
+ customer() = default;
+ customer(const customer &) = default;
+ customer(customer &&) = default;
+
+ [[nodiscard]] auto books_bought() const noexcept -> product::book::size_type;
+ [[nodiscard]] auto amount_spent() const noexcept -> product::price::usd;
+ [[nodiscard]] auto is_member() const noexcept -> bool;
+
+ auto books_bought(product::book::size_type books_bought) noexcept -> void;
+ auto amount_spent(product::price::usd amount_spent) noexcept -> void;
+ auto is_member(bool is_member) noexcept -> void;
+
+ auto operator=(const customer &) -> customer & = default;
+ auto operator=(customer &&) -> customer & = default;
+};
+} // namespace book_store::consumer
+
+#endif // MEMBER_HH
diff --git a/include/book_store/library.hh b/include/book_store/library.hh
new file mode 100644
index 0000000..9044bb9
--- /dev/null
+++ b/include/book_store/library.hh
@@ -0,0 +1,13 @@
+#ifndef PRIMARY_HH
+#define PRIMARY_HH
+
+#include "book_store/store.hh"
+
+namespace book_store::library {
+auto purchase_handler(book_store::store &store) -> void;
+auto populate_books(book_store::store &store, std::size_t library_size) -> void;
+auto populate_consumers(book_store::store &store) -> void;
+auto manage(book_store::store &store) -> void;
+} // namespace book_store::library
+
+#endif // PRIMARY_HH
diff --git a/include/book_store/member.hh b/include/book_store/member.hh
deleted file mode 100644
index 0796a11..0000000
--- a/include/book_store/member.hh
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef MEMBER_HH
-#define MEMBER_HH
-
-#include <cstddef>
-
-#include "book.hh"
-#include "person.hh"
-#include "price.hh"
-
-namespace book_store::consumer {
-class member : person {
-
-private:
- product::book::book::size_type _books_bought;
- product::price::usd _amount_spent;
-
-public:
- member(std::string last_name, std::string first_name, std::size_t member_id)
- : person(std::move(last_name), std::move(first_name), member_id),
- _books_bought(0), _amount_spent(0) {}
- member(std::string last_name, std::string first_name, std::size_t member_id,
- product::book::size_type books_baught,
- product::price::usd amount_spent)
- : person(std::move(last_name), std::move(first_name), member_id),
- _books_bought(books_baught), _amount_spent(amount_spent) {}
- member() = default;
- member(const member &) = default;
- member(member &&) = default;
-
- [[nodiscard]] auto books_bought() const noexcept -> product::book::size_type;
- [[nodiscard]] auto amount_spent() const noexcept -> product::price::usd;
-
- auto books_bought(product::book::size_type books_bought) noexcept -> void;
- auto amount_spent(product::price::usd amount_spent) noexcept -> void;
-
- auto operator=(const member &) -> member & = default;
- auto operator=(member &&) -> member & = default;
-};
-} // namespace book_store::consumer
-
-#endif // MEMBER_HH
diff --git a/include/book_store/person.hh b/include/book_store/person.hh
index 46b9d59..729001a 100644
--- a/include/book_store/person.hh
+++ b/include/book_store/person.hh
@@ -6,26 +6,26 @@
namespace book_store::consumer {
class person {
private:
- std::string _last_name;
std::string _first_name;
+ std::string _last_name;
std::size_t _id;
public:
- person(std::string last_name, std::string first_name, std::size_t person_id)
- : _last_name(std::move(last_name)), _first_name(std::move(first_name)),
+ person(std::string first_name, std::string last_name, std::size_t person_id)
+ : _first_name(std::move(first_name)), _last_name(std::move(last_name)),
_id(person_id) {}
person() = default;
person(const person &) = default;
person(person &&) = default;
- [[nodiscard]] auto last_name() const noexcept -> std::string_view;
[[nodiscard]] auto first_name() const noexcept -> std::string_view;
- [[nodiscard]] auto full_name(bool last_first = false) const noexcept
- -> std::string;
+ [[nodiscard]] auto last_name() const noexcept -> std::string_view;
+ [[nodiscard]] auto
+ full_name(bool last_first = false) const noexcept -> std::string;
[[nodiscard]] auto id() const noexcept -> std::size_t;
- auto last_name(std::string_view last_name) noexcept -> person &;
auto first_name(std::string_view first_name) noexcept -> person &;
+ auto last_name(std::string_view last_name) noexcept -> person &;
auto id(std::size_t person_id) noexcept -> person &;
auto operator=(const person &) -> person & = default;
diff --git a/include/book_store/price.hh b/include/book_store/price.hh
index 39f14b8..223b1e9 100644
--- a/include/book_store/price.hh
+++ b/include/book_store/price.hh
@@ -17,14 +17,16 @@ public:
usd(price_type price) : _price(price) {}
usd(const std::string &price) : _price(std::stod(price)) {}
+ [[nodiscard]] auto value() const noexcept -> price_type;
+
auto operator=(const std::string &value) -> usd & {
_price = std::stod(value);
return *this;
}
- friend auto operator<<(std::ostream &output_stream, const usd &price)
- -> std::ostream & {
+ friend auto operator<<(std::ostream &output_stream,
+ const usd &price) -> std::ostream & {
output_stream << price._price;
return output_stream;
@@ -33,6 +35,18 @@ public:
friend auto operator==(const usd &lhs, const usd &rhs) -> bool {
return std::abs(lhs._price - rhs._price) < 0.0001;
}
+
+ friend auto operator+(const usd &lhs, const usd &rhs) -> usd {
+ return {lhs._price + rhs._price};
+ }
+
+ friend auto operator*(const usd &lhs, const usd &rhs) -> bool {
+ return std::abs(lhs._price * rhs._price) < 0.0001;
+ }
+
+ friend auto operator+=(const usd &lhs, const usd &rhs) -> bool {
+ return std::abs(lhs._price + rhs._price) < 0.0001;
+ }
};
} // namespace book_store::product::price
diff --git a/include/book_store/purchase_error.hh b/include/book_store/purchase_error.hh
new file mode 100644
index 0000000..718ca46
--- /dev/null
+++ b/include/book_store/purchase_error.hh
@@ -0,0 +1,26 @@
+#ifndef PURCHASE_ERROR_HH
+#define PURCHASE_ERROR_HH
+
+#include <string_view>
+
+namespace book_store {
+class purchase_error {
+public:
+ enum purchase_error_type {
+ person_not_found,
+ book_not_found,
+ not_enough_stock,
+ };
+
+private:
+ purchase_error_type _error;
+
+public:
+ purchase_error(purchase_error_type error) : _error(error) {}
+
+ [[nodiscard]] auto error() const noexcept -> purchase_error_type;
+ [[nodiscard]] auto what() const noexcept -> std::string_view;
+};
+} // namespace book_store
+
+#endif // PURCHASE_ERROR_HH
diff --git a/include/book_store/store.hh b/include/book_store/store.hh
new file mode 100644
index 0000000..29c72db
--- /dev/null
+++ b/include/book_store/store.hh
@@ -0,0 +1,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
diff --git a/include/book_store/utility.hh b/include/book_store/utility.hh
new file mode 100644
index 0000000..3971abc
--- /dev/null
+++ b/include/book_store/utility.hh
@@ -0,0 +1,12 @@
+#ifndef UTILITY_HH
+#define UTILITY_HH
+
+#include <string>
+#include <string_view>
+
+namespace book_store::utility {
+auto prompt(std::string_view message) -> std::string;
+auto clear_cerr() -> void;
+} // namespace book_store::utility
+
+#endif // UTILITY_HH