diff options
| author | Fuwn <[email protected]> | 2024-05-31 00:00:12 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2024-05-31 00:20:41 -0700 |
| commit | 968e1c4af014b7f40bfaa4f57fcc0f38e5e0d847 (patch) | |
| tree | df80525ad0cc9e4b561bfb0772c30ccc5b64b4a2 /include/book_store | |
| parent | feat: initial commit (diff) | |
| download | cst_136_assignment_eight-main.tar.xz cst_136_assignment_eight-main.zip | |
Diffstat (limited to 'include/book_store')
| -rw-r--r-- | include/book_store/book_count.hh | 30 | ||||
| -rw-r--r-- | include/book_store/customer.hh | 49 | ||||
| -rw-r--r-- | include/book_store/library.hh | 13 | ||||
| -rw-r--r-- | include/book_store/member.hh | 41 | ||||
| -rw-r--r-- | include/book_store/person.hh | 14 | ||||
| -rw-r--r-- | include/book_store/price.hh | 18 | ||||
| -rw-r--r-- | include/book_store/purchase_error.hh | 26 | ||||
| -rw-r--r-- | include/book_store/store.hh | 87 | ||||
| -rw-r--r-- | include/book_store/utility.hh | 12 |
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 |