From fa3595d69f817ad1a67b7189ed65dbde1ba9f77d Mon Sep 17 00:00:00 2001 From: Fuwn Date: Sun, 26 May 2024 18:01:25 -0700 Subject: feat: initial commit --- source/book.cc | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ source/main.cc | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++ source/member.cc | 23 +++++++++++++ source/person.cc | 43 +++++++++++++++++++++++ source/random.cc | 87 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 354 insertions(+) create mode 100644 source/book.cc create mode 100644 source/main.cc create mode 100644 source/member.cc create mode 100644 source/person.cc create mode 100644 source/random.cc (limited to 'source') diff --git a/source/book.cc b/source/book.cc new file mode 100644 index 0000000..6b0bd6a --- /dev/null +++ b/source/book.cc @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace book_store::product { +using namespace consumer; + +auto book::title() const noexcept -> std::string_view { return this->_title; } + +auto book::authors() const noexcept -> std::vector { + return this->_authors; +} + +auto book::publisher() const noexcept -> std::string_view { + return this->_publisher; +} + +auto book::isbn() const noexcept -> std::string_view { return this->_isbn; } + +auto book::price_usd() const noexcept -> price::usd { return this->_price_usd; } + +auto book::copies() const noexcept -> book::size_type { return this->_copies; } + +auto book::title(std::string_view title) noexcept -> book & { + this->_title = title; + + return *this; +} + +auto book::authors(std::vector authors) -> book & { + this->_authors = std::move(authors); + + return *this; +} + +auto book::author(const class person &author) -> book & { + while (this->_authors.size() < 4) { + this->_authors.emplace_back(author); + + break; + } + + return *this; +} + +auto book::remove_author_by_id(std::size_t author_id) -> book & { + this->_authors.erase( + this->_authors.begin() + + static_cast::difference_type>(author_id)); + + return *this; +} + +auto book::publisher(std::string_view publisher) noexcept -> book & { + this->_publisher = publisher; + + return *this; +} + +auto book::isbn(std::string_view isbn) noexcept -> book & { + this->_isbn = isbn; + + return *this; +} + +auto book::price_usd(price::usd price) noexcept -> book & { + this->_price_usd = price; + + return *this; +} + +auto book::copies(book::size_type copies) noexcept -> book & { + this->_copies = copies; + + return *this; +} + +auto operator<<(std::ostream &output_stream, const book &book) + -> std::ostream & { + output_stream << "Title: " << book._title << '\n'; + output_stream << "Authors: "; + + for (const auto &author : book._authors) { + output_stream << author.full_name() + << ((&author == &book._authors.back()) ? "" : ", "); + } + + output_stream << '\n'; + output_stream << "Publisher: " << book._publisher << '\n'; + output_stream << "ISBN: " << book._isbn << '\n'; + output_stream << "Price: $" << book._price_usd << '\n'; + output_stream << "Copies: " << book._copies << '\n'; + + return output_stream; +} +} // namespace book_store::product diff --git a/source/main.cc b/source/main.cc new file mode 100644 index 0000000..5d262f7 --- /dev/null +++ b/source/main.cc @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +auto main() -> int { + using namespace book_store; + + std::array books; + std::array book_titles; + std::array members; + std::array member_ids; + std::mt19937 random_number_generator(std::random_device{}()); + utility::random::book_random_engine random(random_number_generator); + auto perform = [](std::string_view name, auto action) { + std::cout << name << " ..."; + + action(); + + std::cout << " ok.\n"; + }; + auto clear_cerr = []() { + if (!std::cerr.good()) { + std::cerr.clear(); + } + }; + + perform("populating books and book_titles", [&]() { + for (auto [index, book] : std::ranges::views::enumerate(books)) { + auto random_title = random.title(); + + book_titles[static_cast(index)] = random_title; + book = + product::book{random_title, random.authors(), random.publisher(), + random.isbn(), random.price_usd(), random.copy_count()}; + } + }); + perform("verifying all books are present", [&]() { + for (const auto &title : book_titles) { + if (std::ranges::find(book_titles, title) == book_titles.end()) { + clear_cerr(); + + std::cerr << "error: title not found" << '\n'; + + std::terminate(); + } + } + }); + perform("verifying book copy count increment", [&]() { + for (int i = 0; i < 100; ++i) { + auto &book = books[std::uniform_int_distribution( + 0, books.size() - 1)(random_number_generator)]; + auto copy_count = book.copies(); + auto random_copy_count = static_cast( + std::uniform_int_distribution(0, 100)( + random_number_generator)); + + book.copies(copy_count + random_copy_count); + + if (book.copies() != copy_count + random_copy_count) { + clear_cerr(); + + std::cerr << "error: invalid copy count after increment" << '\n'; + + std::terminate(); + } + } + }); + perform("populating members and member_ids", [&]() { + for (auto [index, member] : std::views::enumerate(members)) { + auto random_name = random.name(); + auto random_surname = random.name(); + auto random_id = random.id(); + + member_ids[static_cast(index)] = random_id; + member = consumer::member{random_name, random_surname, random_id}; + } + }); + perform("verifying all members are present", [&]() { + for (auto member_id : member_ids) { + if (std::ranges::find(member_ids, member_id) == member_ids.end()) { + std::cerr << "error: id not found" << '\n'; + + std::terminate(); + } + } + }); + + return 0; +} diff --git a/source/member.cc b/source/member.cc new file mode 100644 index 0000000..0e8a41c --- /dev/null +++ b/source/member.cc @@ -0,0 +1,23 @@ +#include +#include +#include + +namespace book_store::consumer { +using namespace product; + +auto member::books_bought() const noexcept -> book::size_type { + return this->_books_bought; +} + +auto member::amount_spent() const noexcept -> price::usd { + return this->_amount_spent; +} + +auto member::books_bought(book::size_type books_bought) noexcept -> void { + this->_books_bought = books_bought; +} + +auto member::amount_spent(price::usd amount_spent) noexcept -> void { + this->_amount_spent = amount_spent; +} +} // namespace book_store::consumer diff --git a/source/person.cc b/source/person.cc new file mode 100644 index 0000000..e80e6df --- /dev/null +++ b/source/person.cc @@ -0,0 +1,43 @@ +#include +#include +#include + +#include + +namespace book_store::consumer { +auto person::last_name() const noexcept -> std::string_view { + return this->_last_name; +} + +auto person::first_name() const noexcept -> std::string_view { + return this->_first_name; +} + +auto person::full_name(bool last_first) const noexcept -> std::string { + if (last_first) { + return this->_last_name + ", " + this->_first_name; + } + + return this->_first_name + " " + this->_last_name; +} + +auto person::id() const noexcept -> std::size_t { return this->_id; } + +auto person::last_name(std::string_view last_name) noexcept -> person & { + this->_last_name = last_name; + + return *this; +} + +auto person::first_name(std::string_view first_name) noexcept -> person & { + this->_first_name = first_name; + + return *this; +} + +auto person::id(std::size_t person_id) noexcept -> person & { + this->_id = person_id; + + return *this; +} +} // namespace book_store::consumer diff --git a/source/random.cc b/source/random.cc new file mode 100644 index 0000000..d237b9f --- /dev/null +++ b/source/random.cc @@ -0,0 +1,87 @@ +#include +#include +#include +#include + +#include +#include +#include + +namespace book_store::utility::random { +auto book_random_engine::title() -> std::string { + static std::uniform_int_distribution<> distrubtion{0, 49}; + std::string book_name; + + for (int i = 0; i < 3; ++i) { + book_name += book_title_parts[static_cast( + distrubtion(this->_random_number_generator))]; + book_name += ' '; + } + + book_name.pop_back(); + + return book_name; +} + +auto book_random_engine::name() -> std::string { + static std::uniform_int_distribution<> distrubtion{0, 49}; + + return std::string(names[static_cast( + distrubtion(this->_random_number_generator))]); +} + +auto book_random_engine::author() -> consumer::person { + return consumer::person{this->name(), this->name(), this->id()}; +} + +auto book_random_engine::authors() -> std::vector { + std::vector authors; + static std::uniform_int_distribution<> distrubtion{1, 4}; + auto author_count = distrubtion(this->_random_number_generator); + + authors.reserve(static_cast(author_count)); + + for (int i = 0; i < author_count; ++i) { + authors.push_back(this->author()); + } + + return authors; +} + +auto book_random_engine::publisher() -> std::string { + static std::uniform_int_distribution<> distrubtion{0, 9}; + + return std::string(publishers[static_cast( + distrubtion(this->_random_number_generator))]); +} + +auto book_random_engine::isbn() -> std::string { + static std::uniform_int_distribution<> distrubtion{0, 9}; + std::string isbn; + + for (int i = 0; i < 13; ++i) { + isbn += std::to_string(distrubtion(this->_random_number_generator)); + } + + return isbn; +} + +auto book_random_engine::price_usd() -> double { + static std::uniform_real_distribution<> distrubtion{0.0, 100.0}; + + return distrubtion(this->_random_number_generator); +} + +auto book_random_engine::copy_count() -> product::book::size_type { + static std::uniform_int_distribution<> distrubtion{0, 10000}; + + return static_cast( + distrubtion(this->_random_number_generator)); +} + +auto book_random_engine::id() -> std::size_t { + static std::uniform_int_distribution<> distrubtion{0, 1000000}; + + return static_cast(distrubtion(this->_random_number_generator)); +} +} // namespace book_store::utility::random -- cgit v1.2.3