diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Cage.cc | 48 | ||||
| -rw-r--r-- | src/Cage.hh | 59 | ||||
| -rw-r--r-- | src/Mammal.cc | 33 | ||||
| -rw-r--r-- | src/Mammal.hh | 62 | ||||
| -rw-r--r-- | src/Test.cc | 348 | ||||
| -rw-r--r-- | src/Zoo.cc | 55 | ||||
| -rw-r--r-- | src/Zoo.hh | 61 | ||||
| -rw-r--r-- | src/ZooAnimal.cc | 44 | ||||
| -rw-r--r-- | src/ZooAnimal.hh | 72 | ||||
| -rw-r--r-- | src/meson.build | 3 |
10 files changed, 785 insertions, 0 deletions
diff --git a/src/Cage.cc b/src/Cage.cc new file mode 100644 index 0000000..d6a3aa4 --- /dev/null +++ b/src/Cage.cc @@ -0,0 +1,48 @@ +#include <utility> + +#include "Cage.hh" + +namespace zoo { +void Cage::setCageNumber(int _cageNumber) { + if (validateCageNumber(_cageNumber)) { + this->cageNumber = _cageNumber; + } +} + +void Cage::setCageLocation(std::string _cageLocation) { + this->cageLocation = std::move(_cageLocation); +} + +void Cage::setCageSqFt(int _cageSqFt) { + if (Cage::validateSqFt(_cageSqFt)) { + this->cageSqFt = _cageSqFt; + } +} + +int Cage::getCageNumber() const { return this->cageNumber; } + +std::string Cage::getCageLocation() { return this->cageLocation; } + +int Cage::getCageSqFt() const { return this->cageSqFt; } + +bool Cage::validateSqFt(int _cageSqFt) { + if (_cageSqFt < 2 || _cageSqFt > 100000) { + return false; + } else { + return true; + } +} + +bool Cage::validateCageNumber(int _cageNumber) { + if (this->zoo != nullptr) { + for (std::size_t i = 0; + i < static_cast<std::size_t>(this->zoo->getNumCages()); ++i) { + if (*zoo->getCage(i) == _cageNumber) { + return true; + } + } + } + + return false; +} +} // namespace zoo diff --git a/src/Cage.hh b/src/Cage.hh new file mode 100644 index 0000000..28871c3 --- /dev/null +++ b/src/Cage.hh @@ -0,0 +1,59 @@ +#ifndef CAGE +#define CAGE + +#include <string> +#include <utility> + +#include "Zoo.hh" + +namespace zoo { +/** + * @brief Used to store the location, size, and number of a single cage at the + * zoo + */ +class Cage { +private: + int cageNumber; + int cageSqFt; + std::string cageLocation; + Zoo *zoo; + +public: + explicit Cage(int _cageNumber = 0, int _cageSqFt = 0, + std::string _cageLocation = "", Zoo *_zoo = nullptr) + : cageNumber(_cageNumber), cageSqFt(_cageSqFt), + cageLocation(std::move(_cageLocation)), zoo(_zoo) {} + + /** + * @brief Set the number of a cage + */ + void setCageNumber(int); + /** + * @brief Set the location of a cage + */ + void setCageLocation(std::string); + /** + * @brief Set the square footage of a cage + */ + void setCageSqFt(int); + + /** + * @brief Get the number of a cage + */ + [[nodiscard]] int getCageNumber() const; + /** + * @brief Get the location of a cage + */ + std::string getCageLocation(); + /** + * @brief Get the square footage of a cage + */ + [[nodiscard]] int getCageSqFt() const; + +private: + static bool validateSqFt(int); + bool validateCageNumber(int); +}; +} // namespace zoo + +#endif // CAGE diff --git a/src/Mammal.cc b/src/Mammal.cc new file mode 100644 index 0000000..2763fcc --- /dev/null +++ b/src/Mammal.cc @@ -0,0 +1,33 @@ +#include <utility> + +#include "Mammal.hh" + +namespace zoo { +Mammal::~Mammal() = default; + +void Mammal::setExhibit(std::string _exhibit) { + this->exhibit = std::move(_exhibit); +} + +void Mammal::setName(std::string _name) { this->name = std::move(_name); } + +void Mammal::setCageSizeMin(int _cageSizeMin) { + if (Mammal::validateCageSizeMin(_cageSizeMin)) { + this->cageSizeMin = _cageSizeMin; + } +} + +std::string Mammal::getExhibit() { return this->exhibit; } + +std::string Mammal::getName() { return this->name; } + +int Mammal::getCageSizeMin() const { return this->cageSizeMin; } + +bool Mammal::validateCageSizeMin(int cageSize) { + if (cageSize < 2 || cageSize > 100000) { + return false; + } else { + return true; + } +} +} // namespace zoo diff --git a/src/Mammal.hh b/src/Mammal.hh new file mode 100644 index 0000000..12b3bcb --- /dev/null +++ b/src/Mammal.hh @@ -0,0 +1,62 @@ +#ifndef MAMMAL +#define MAMMAL + +#include <utility> + +#include "ZooAnimal.hh" + +namespace zoo { +/** + * @brief Used to store the name, location, and minimum cage size for a mammal + */ +class Mammal final : public ZooAnimal { +private: + std::string exhibit; + std::string name; + int cageSizeMin; + [[maybe_unused]] int padding; + +public: + explicit Mammal(std::string _exhibit = "", std::string _name = "", + int _cageSizeMin = 0, int _idNumber = 0, int _cageNumber = 0, + int _dateAcquired = 0, std::string _species = "", + Zoo *_zoo = nullptr) + : ZooAnimal(_idNumber, _cageNumber, _dateAcquired, std::move(_species), + _zoo), + exhibit(std::move(_exhibit)), name(std::move(_name)), + cageSizeMin(_cageSizeMin), padding(0) {} + + ~Mammal() override; + + /** + * @brief Set the exhibit of a mammal + */ + void setExhibit(std::string); + /** + * @brief Set the name of a mammal + */ + void setName(std::string); + /** + * @brief Set the cage size of a mammal + */ + void setCageSizeMin(int); + + /** + * @brief Get the exhibit of a mammal + */ + std::string getExhibit(); + /** + * @brief Get the name of a mammal + */ + std::string getName(); + /** + * @brief Get the cage size of a mammal + */ + [[nodiscard]] int getCageSizeMin() const; + +private: + static bool validateCageSizeMin(int); +}; +} // namespace zoo + +#endif // MAMMAL diff --git a/src/Test.cc b/src/Test.cc new file mode 100644 index 0000000..9fa1e9d --- /dev/null +++ b/src/Test.cc @@ -0,0 +1,348 @@ +#include <iostream> +#include <variant> +#include <vector> + +#include "Cage.hh" +#include "Mammal.hh" +#include "Zoo.hh" + +namespace zoo { +template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; +template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>; +} // namespace zoo + +int main() { + zoo::Zoo zoo; + std::vector<zoo::Cage> cages; + std::vector<std::variant<zoo::ZooAnimal, zoo::Mammal>> zooAnimals; + + // Prompt the user to enter up to ten exhibits at the Zoo + std::cout << "enter up to ten exhibit names (negative number to finish):" + << std::endl; + + for (int i = 0; i < 10; ++i) { + std::string exhibit; + + std::cout << "exhibit name #" << i + 1 << ": "; + + std::getline(std::cin, exhibit); + + if (exhibit.starts_with('-')) { + break; + } + + zoo.setExhibit(exhibit); + } + + // Prompt the user to enter up to ten cages at the zoo + std::cout << "\nenter up to ten cage numbers (negative number to finish):" + << std::endl; + + for (int i = 0; i < 10; ++i) { + int cageNumber; + zoo::Cage cage(0, 0, "", &zoo); + + std::cout << "cage number #" << i + 1 << ": "; + std::cin >> cageNumber; + + if (cageNumber < 0) { + break; + } + + zoo.setCage(cageNumber); + cage.setCageNumber(cageNumber); + cages.emplace_back(cage); + } + + // Prompt the user to add information to each of the cages + if (zoo.getNumCages() > 0) { + std::cout << "\nadd information to each of the cages:" << std::endl; + + for (;;) { + int cageNumber; + std::string cageLocation; + int cageSquareFootage; + + std::cout << "available cages numbers: "; + + for (std::size_t i = 0; i < static_cast<std::size_t>(zoo.getNumCages()); + ++i) { + std::cout << *zoo.getCage(i) << " "; + } + + // Various mechanisms have been put in place to ensure that the user's + // choice of cage to edit is a valid cage number which exists in the zoo + // before it can be added as a cage. + std::cout + << "\ncage number to edit (negative number to finish, -1 to go one " + "by one): "; + std::cin >> cageNumber; + + if (cageNumber == -1) { + for (std::size_t i = 0; i < static_cast<std::size_t>(zoo.getNumCages()); + ++i) { + std::cout << "cage #" << *zoo.getCage(i) << "'s location: "; + + std::cin.ignore(); + std::getline(std::cin, cageLocation); + + std::cout << "cage #" << *zoo.getCage(i) << "'s square footage: "; + std::cin >> cageSquareFootage; + + // Make sure the square footage of the cage is within the 2 to 100000 + // range + if (cageSquareFootage < 2 || cageSquareFootage > 100000) { + std::cout << "invalid cage squared footage: must be in range of " + "2-100000, try again." + << std::endl; + + i -= 1; + + continue; + } + + cages.at(i).setCageLocation(cageLocation); + cages.at(i).setCageSqFt(cageSquareFootage); + } + + break; + } + + for (std::size_t i = 0; i < static_cast<std::size_t>(zoo.getNumCages()); + ++i) { + if (*zoo.getCage(i) == cageNumber) { + std::cout << "cage #" << *zoo.getCage(i) << "'s location: "; + + std::cin.ignore(); + std::getline(std::cin, cageLocation); + + std::cout << "cage #" << *zoo.getCage(i) << "'s square footage: "; + std::cin >> cageSquareFootage; + + cages.at(i).setCageLocation(cageLocation); + cages.at(i).setCageSqFt(cageSquareFootage); + } + } + + if (cageNumber < 0) { + break; + } + } + } + + // Prompt the user to add up to twenty animals to the zoo + std::cout << "\nadd up to twenty animals and/ or mammals to the zoo " + "(negative number to finish):" + << std::endl; + + for (int i = 0; i < 20; ++i) { + int idNumber; + int cageNumber; + int dateAcquired; + std::string species; + bool isMammal; + std::string exhibit; + std::string name; + int cageSizeMin; + + std::cout << "animal/ mammal #" << i + 1 << " id number: "; + std::cin >> idNumber; + + if (idNumber < 0) { + break; + } + + std::cout << "animal/ mammal #" << i + 1 << " cage number: "; + std::cin >> cageNumber; + std::cout << "animal/ mammal #" << i + 1 << " date acquired: "; + std::cin >> dateAcquired; + std::cout << "animal/ mammal #" << i + 1 << " species: "; + + std::cin.ignore(); + std::getline(std::cin, species); + + std::cout << "is this animal a mammal? (0 = no, 1 = yes): "; + std::cin >> isMammal; + + if (isMammal) { + zoo::Mammal mammal = zoo::Mammal("", "", 0, idNumber, cageNumber, + dateAcquired, species, &zoo); + + std::cout << "mammal #" << i + 1 << " exhibit: "; + + std::cin.ignore(); + std::getline(std::cin, exhibit); + + std::cout << "mammal #" << i + 1 << " name: "; + + std::getline(std::cin, name); + + std::cout << "mammal #" << i + 1 << " minimum cage size: "; + std::cin >> cageSizeMin; + + mammal.setExhibit(exhibit); + mammal.setName(name); + mammal.setCageSizeMin(cageSizeMin); + zooAnimals.emplace_back(mammal); + } else { + zoo::ZooAnimal zooAnimal = + zoo::ZooAnimal(idNumber, cageNumber, dateAcquired, species, &zoo); + + zooAnimal.setIDNum(idNumber); + zooAnimal.setCageNum(cageNumber); + zooAnimal.setDateAcq(dateAcquired); + zooAnimal.setSpecies(species); + zooAnimals.emplace_back(zooAnimal); + } + } + + // Display all the information about the zoo, cage, zoo animals, and mammals + // owned by the zoo + std::cout << "\nzoo:" << std::endl; + + if (zoo.getNumExhibits() > 0) { + std::cout << " exhibits:" << std::endl; + + for (std::size_t i = 0; i < static_cast<std::size_t>(zoo.getNumExhibits()); + ++i) { + std::cout << " exhibit #" << i + 1 << " name: " << *zoo.getExhibit(i) + << std::endl; + } + + std::cout << std::endl; + } else { + std::cout << " there were no exhibits at the zoo\n" << std::endl; + } + + if (zoo.getNumCages() > 0) { + std::cout << " cages:" << std::endl; + + for (std::size_t i = 0; i < static_cast<std::size_t>(zoo.getNumCages()); + ++i) { + std::cout << " cage #" << i + 1 + << ":\n number: " << cages.at(i).getCageNumber() + << "\n square footage: " << cages.at(i).getCageSqFt() + << "\n location: " << cages.at(i).getCageLocation() + << std::endl; + } + + std::cout << std::endl; + } else { + std::cout << " there were no cages at the zoo\n" << std::endl; + } + + if (!zooAnimals.empty()) { + std::cout << " animals and/ or mammals:" << std::endl; + + for (std::size_t i = 0; i < zooAnimals.size(); ++i) { + std::visit(zoo::overloaded{ + [&](zoo::Mammal &animal) { + std::cout + << " mammal #" << i + 1 + << ":\n id number: " << animal.getIDNum() + << "\n cage number: " << animal.getCageNum() + << "\n date acquired: " << animal.getDateAcq() + << "\n species: " << animal.getSpecies() + << "\n exhibit: " << animal.getExhibit() + << "\n name: " << animal.getName() + << "\n minimum cage size: " + << animal.getCageSizeMin(); + }, + [&](zoo::ZooAnimal &animal) { + std::cout + << " animal #" << i + 1 + << ":\n id number: " << animal.getIDNum() + << "\n cage number: " << animal.getCageNum() + << "\n date acquired: " << animal.getDateAcq() + << "\n species: " << animal.getSpecies(); + }}, + zooAnimals.at(i)); + + std::cout << std::endl; + } + } + + if (!zooAnimals.empty()) { + // Let the user choose to see all information about a specific animal, by + // identification number + std::cout << "\nanimal ids:"; + + for (auto &zooAnimal : zooAnimals) { + std::visit( + [](auto &&animal) { std::cout << "\n " << animal.getIDNum(); }, + zooAnimal); + } + + std::cout << std::endl; + + for (;;) { + int idNumber; + + std::cout << "id number to view (negative number to finish): "; + std::cin >> idNumber; + + if (idNumber < 0) { + break; + } + + for (auto &zooAnimal : zooAnimals) { + std::visit(zoo::overloaded{ + [&](zoo::Mammal &animal) { + if (animal.getIDNum() == idNumber) { + std::cout + << "mammal #" << idNumber + << ":\n id number: " << animal.getIDNum() + << "\n cage number: " << animal.getCageNum() + << "\n date acquired: " << animal.getDateAcq() + << "\n species: " << animal.getSpecies() + << "\n exhibit: " << animal.getExhibit() + << "\n name: " << animal.getName() + << "\n minimum cage size: " + << animal.getCageSizeMin() << std::endl; + } + }, + [&](zoo::ZooAnimal &animal) { + if (animal.getIDNum() == idNumber) { + std::cout + << "animal #" << idNumber + << ":\n id number: " << animal.getIDNum() + << "\n cage number: " << animal.getCageNum() + << "\n date acquired: " << animal.getDateAcq() + << "\n species: " << animal.getSpecies() + << std::endl; + } + }}, + zooAnimal); + } + } + } else { + std::cout << "there were no animals at the zoo" << std::endl; + } + + if (!zooAnimals.empty()) { + std::size_t mammalCount = 0; + + std::cout << "\nmammals names:"; + + for (auto &zooAnimal : zooAnimals) { + std::visit( + [&mammalCount](auto &&animal) { + if constexpr (std::is_same_v<std::decay_t<decltype(animal)>, + zoo::Mammal>) { + std::cout << "\n " << animal.getName(); + + mammalCount += 1; + } + }, + zooAnimal); + } + + if (mammalCount == 0) { + std::cout << " there were no mammals at the zoo"; + } + + std::cout << std::endl; + } + + return 0; +} diff --git a/src/Zoo.cc b/src/Zoo.cc new file mode 100644 index 0000000..41d4ea3 --- /dev/null +++ b/src/Zoo.cc @@ -0,0 +1,55 @@ +#include <algorithm> +#include <utility> + +#include "Zoo.hh" + +namespace zoo { +Zoo::~Zoo() { + delete[] this->exhibits; + delete[] this->cages; +} + +void Zoo::setExhibit(std::string exhibit) { + auto *newExhibits = + new std::string[static_cast<unsigned long>(this->numExhibits + 1)]; + + std::copy(this->exhibits, + this->exhibits + static_cast<unsigned long>(this->numExhibits), + newExhibits); + + delete[] this->exhibits; + + this->exhibits = newExhibits; + this->exhibits[this->numExhibits] = std::move(exhibit); + + this->incrementNumExhibits(); +} + +void Zoo::setCage(int cageNumber) { + int *newCages = new int[static_cast<unsigned long>(this->numCages + 1)]; + + std::copy(this->cages, + this->cages + static_cast<unsigned long>(this->numCages), newCages); + + delete[] this->cages; + + this->cages = newCages; + this->cages[this->numCages] = cageNumber; + + this->incrementNumCages(); +} + +std::string *Zoo::getExhibit(std::size_t exhibitIndex) { + return &this->exhibits[exhibitIndex]; +} + +int *Zoo::getCage(std::size_t cageIndex) { return &this->cages[cageIndex]; } + +int Zoo::getNumExhibits() const { return this->numExhibits; } + +int Zoo::getNumCages() const { return this->numCages; } + +void Zoo::incrementNumExhibits() { this->numExhibits += 1; } + +void Zoo::incrementNumCages() { this->numCages += 1; } +} // namespace zoo diff --git a/src/Zoo.hh b/src/Zoo.hh new file mode 100644 index 0000000..4f4173b --- /dev/null +++ b/src/Zoo.hh @@ -0,0 +1,61 @@ +#ifndef ZOO +#define ZOO + +#include <string> + +namespace zoo { +/** + * @brief Used to store the names of exhibits and cage numbers, in separate + * arrays + */ +class Zoo { +private: + std::string *exhibits; + int *cages; + int numExhibits; + int numCages; + +public: + Zoo() + : exhibits(new std::string[0]()), cages(new int[0]()), numExhibits(0), + numCages(0) {} + + ~Zoo(); + + /** + * @brief Add an exhibit to the zoo + */ + void setExhibit(std::string); + /** + * @brief Add a cage to the zoo + */ + void setCage(int); + + /** + * @brief Get an exhibit's name from the zoo from its ID + * @return An exhibit's name + */ + std::string *getExhibit(std::size_t); + /** + * @brief Get a cage's ID from the zoo from its index + * @return A cage's ID + */ + int *getCage(std::size_t); + /** + * @brief Get the number of exhibits within the zoo + * @return The number of exhibits within the Zoo + */ + [[nodiscard]] int getNumExhibits() const; + /** + * @brief Get the number of cages within the zoo + * @return The number of cages within the Zoo + */ + [[nodiscard]] int getNumCages() const; + +private: + void incrementNumExhibits(); + void incrementNumCages(); +}; +} // namespace zoo + +#endif // ZOO diff --git a/src/ZooAnimal.cc b/src/ZooAnimal.cc new file mode 100644 index 0000000..6bfa1d2 --- /dev/null +++ b/src/ZooAnimal.cc @@ -0,0 +1,44 @@ +#include <utility> + +#include "ZooAnimal.hh" + +namespace zoo { +ZooAnimal::~ZooAnimal() = default; + +void ZooAnimal::setIDNum(int _idNumber) { this->idNumber = _idNumber; } + +void ZooAnimal::setCageNum(int _cageNumber) { + if (validateCageNumber(_cageNumber)) { + this->cageNumber = _cageNumber; + } +} + +void ZooAnimal::setDateAcq(int _dateAcquired) { + this->dateAcquired = _dateAcquired; +} + +void ZooAnimal::setSpecies(std::string _species) { + this->species = std::move(_species); +} + +int ZooAnimal::getIDNum() const { return this->idNumber; } + +int ZooAnimal::getCageNum() const { return this->cageNumber; } + +int ZooAnimal::getDateAcq() const { return this->dateAcquired; } + +std::string ZooAnimal::getSpecies() { return this->species; } + +bool ZooAnimal::validateCageNumber(int _cageNumber) { + if (this->zoo != nullptr) { + for (std::size_t i = 0; + i < static_cast<std::size_t>(this->zoo->getNumCages()); ++i) { + if (*zoo->getCage(i) == _cageNumber) { + return true; + } + } + } + + return false; +} +} // namespace zoo diff --git a/src/ZooAnimal.hh b/src/ZooAnimal.hh new file mode 100644 index 0000000..853fd5d --- /dev/null +++ b/src/ZooAnimal.hh @@ -0,0 +1,72 @@ +#ifndef ZOO_ANIMAL +#define ZOO_ANIMAL + +#include <string> +#include <utility> + +#include "Zoo.hh" + +namespace zoo { +/** + * @brief Used to store the identification number, cage number where the animal + * is kept, species of animal, and date of acquisition + */ +class ZooAnimal { +private: + int idNumber; + int cageNumber; + int dateAcquired; + [[maybe_unused]] int padding; + std::string species; + Zoo *zoo; + +public: + explicit ZooAnimal(int _idNumber = 0, int _cageNumber = 0, + int _dateAcquired = 0, std::string _species = "", + Zoo *_zoo = nullptr) + : idNumber(_idNumber), cageNumber(_cageNumber), + dateAcquired(_dateAcquired), padding(0), species(std::move(_species)), + zoo(_zoo) {} + + virtual ~ZooAnimal(); + + /** + * @brief Set the ID number of a zoo animal + */ + void setIDNum(int); + /** + * @brief Set the cage number of a zoo animal + */ + void setCageNum(int); + /** + * @brief Set the date of acquisition of a zoo animal + */ + void setDateAcq(int); + /** + * @brief Set the species of a zoo animal + */ + void setSpecies(std::string); + + /** + * @brief Get the ID number of a zoo animal + */ + [[nodiscard]] int getIDNum() const; + /** + * @brief Get the cage number of a zoo animal + */ + [[nodiscard]] int getCageNum() const; + /** + * @brief Get the date of acquisition of a zoo animal + */ + [[nodiscard]] int getDateAcq() const; + /** + * @brief Get the species of a zoo animal + */ + std::string getSpecies(); + +private: + bool validateCageNumber(int); +}; +} // namespace zoo + +#endif // ZOO_ANIMAL diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 0000000..d04c840 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,3 @@ +main_source = files('Cage.cc', 'Mammal.cc', 'Test.cc', 'Zoo.cc', 'ZooAnimal.cc') +project_header_files += files('Cage.hh', 'Mammal.hh', 'Zoo.hh', 'ZooAnimal.hh') +project_sources += main_source |