diff --git a/ex02/Makefile b/ex02/Makefile new file mode 100644 index 0000000..9ef76bf --- /dev/null +++ b/ex02/Makefile @@ -0,0 +1,4 @@ +override NAME = ex02.out +override SRC_FILES = main.cpp Bureaucrat.cpp AForm.cpp ShrubberyCreationForm.cpp RobotomyRequestForm.cpp PresidentialPardonForm.cpp + +include ../Makefile diff --git a/ex02/src/AForm.cpp b/ex02/src/AForm.cpp new file mode 100644 index 0000000..8a60333 --- /dev/null +++ b/ex02/src/AForm.cpp @@ -0,0 +1,89 @@ +#include +#include + +AForm::AForm() : name("Vente"), isSigned(false), gradeToSign(150), gradeToExecute(150) { + std::cout << "AForm default constructor called" << std::endl; +} + +AForm::AForm(const AForm& other) : name(other.name), isSigned(other.isSigned), gradeToSign(other.gradeToSign), gradeToExecute(other.gradeToExecute) { + std::cout << "AForm copy constructor called" << std::endl; +} + +AForm::AForm(const std::string& name) : name(name), isSigned(false), gradeToSign(150), gradeToExecute(150) { + std::cout << "AForm (name) constructor called" << std::endl; +} + +AForm::AForm(const std::string& name, const unsigned short gradeToSign, const unsigned short gradeToExecute) : name(name), isSigned(false), gradeToSign(gradeToSign), gradeToExecute(gradeToExecute) { + std::cout << "AForm (name, gradeToSign, gradeToExecute) constructor called" << std::endl; + + if (gradeToSign > 150 || gradeToExecute > 150) + throw GradeTooLowException(); + + if (gradeToSign < 1 || gradeToExecute < 1) + throw GradeTooHighException(); +} + +void AForm::beSigned(Bureaucrat& bureaucrat) { + std::cout << "Be signed called" << std::endl; + + if (bureaucrat.getGrade() > gradeToSign) + throw GradeTooLowException(); + + isSigned = true; +} + +void AForm::execute(Bureaucrat const & executor) const { + if (!isSigned) + throw FormNotSignedException(); + + if (executor.getGrade() > gradeToExecute) + throw GradeTooLowException(); + + executeAction(); +} + +const std::string& AForm::getName() const { + return name; +} + +bool AForm::getIsSigned() const { + return isSigned; +} + +unsigned short AForm::getGradeToSign() const { + return gradeToSign; +} + +unsigned short AForm::getGradeToExecute() const { + return gradeToExecute; +} + +AForm& AForm::operator=(const AForm& other) { + std::cout << "AForm assignment operator called" << std::endl; + + if (this != &other) + isSigned = other.isSigned; + + return *this; +} + +AForm::~AForm() { + std::cout << "AForm destructor called" << std::endl; +} + +const char* AForm::GradeTooHighException::what() const throw() { + return "Grade too high"; +} + +const char* AForm::GradeTooLowException::what() const throw() { + return "Grade too low"; +} + +const char* AForm::FormNotSignedException::what() const throw() { + return "Form is not signed"; +} + +std::ostream& operator<<(std::ostream& ostream, const AForm& form) { + ostream << form.getName() << ", grade to sign " << form.getGradeToSign() << ", grade to execute " << form.getGradeToExecute() << "."; + return ostream; +} diff --git a/ex02/src/AForm.hpp b/ex02/src/AForm.hpp new file mode 100644 index 0000000..c022709 --- /dev/null +++ b/ex02/src/AForm.hpp @@ -0,0 +1,54 @@ +#pragma once + +#include +#include +#include +#include + +class Bureaucrat; + +class AForm { + public: + AForm(); + AForm(const AForm& other); + AForm(const std::string& name); + AForm(const std::string& name, const unsigned short gradeToSign, const unsigned short gradeToExecute); + + void beSigned(Bureaucrat& bureaucrat); + void execute(Bureaucrat const & executor) const; + + const std::string& getName() const; + bool getIsSigned() const; + unsigned short getGradeToSign() const; + unsigned short getGradeToExecute() const; + + AForm& operator=(const AForm& other); + + virtual ~AForm(); + protected: + virtual void executeAction() const = 0; + private: + const std::string name; + + bool isSigned; + + const unsigned short gradeToSign; + const unsigned short gradeToExecute; + + class GradeTooHighException : public std::exception { + public: + const char* what() const throw(); + }; + + class GradeTooLowException : public std::exception { + public: + const char* what() const throw(); + }; + + class FormNotSignedException : public std::exception { + public: + const char* what() const throw(); + }; +}; + +std::ostream& operator<<(std::ostream& ostream, const AForm& form); diff --git a/ex02/src/Bureaucrat.cpp b/ex02/src/Bureaucrat.cpp new file mode 100644 index 0000000..f1c7124 --- /dev/null +++ b/ex02/src/Bureaucrat.cpp @@ -0,0 +1,98 @@ +#include +#include + +Bureaucrat::Bureaucrat() : name("Franck Leboeuf") { + std::cout << "Bureaucrat default constructor called" << std::endl; + setGrade(150); +} + +Bureaucrat::Bureaucrat(const Bureaucrat& other) : name(other.name), grade(other.grade) { + std::cout << "Bureaucrat copy constructor called" << std::endl; +} + +Bureaucrat::Bureaucrat(const std::string& name) : name(name) { + std::cout << "Bureaucrat (name) constructor called" << std::endl; + setGrade(150); +} + +Bureaucrat::Bureaucrat(const std::string& name, const unsigned short grade) : name(name) { + std::cout << "Bureaucrat (name, grade) constructor called" << std::endl; + setGrade(grade); +} + +void Bureaucrat::incrementGrade() { + std::cout << "Increment grade called" << std::endl; + setGrade(grade - 1); +} + +void Bureaucrat::decrementGrade() { + std::cout << "Decrement grade called" << std::endl; + setGrade(grade + 1); +} + +void Bureaucrat::signForm(AForm& form) { + if (form.getIsSigned()) { + std::cout << name << " couldn't sign " << form.getName() << " because it is already signed" << std::endl; + return; + } + + try { + form.beSigned(*this); + std::cout << name << " signed " << form.getName() << std::endl; + } catch (const std::exception& exception) { + std::cout << name << " couldn't sign " << form.getName() << " because " << exception.what() << std::endl; + } +} + +void Bureaucrat::executeForm(AForm const & form) const { + try { + form.execute(*this); + std::cout << name << " executed " << form.getName() << std::endl; + } catch (const std::exception& exception) { + std::cout << name << " couldn't execute " << form.getName() << " because " << exception.what() << std::endl; + } +} + +const std::string& Bureaucrat::getName() const { + return name; +} + +unsigned short Bureaucrat::getGrade() const { + return grade; +} + +Bureaucrat& Bureaucrat::operator=(const Bureaucrat& other) { + std::cout << "Bureaucrat assignment operator called" << std::endl; + + if (this != &other) + grade = other.grade; + + return *this; +} + +Bureaucrat::~Bureaucrat() { + std::cout << "Bureaucrat destructor called" << std::endl; +} + +void Bureaucrat::setGrade(const unsigned short grade) { + if (grade > 150) + throw GradeTooLowException(); + + if (grade < 1) + throw GradeTooHighException(); + + this->grade = grade; +} + +const char* Bureaucrat::GradeTooHighException::what() const throw() { + return "Grade too high"; +} + +const char* Bureaucrat::GradeTooLowException::what() const throw() { + return "Grade too low"; +} + +std::ostream& operator<<(std::ostream& ostream, const Bureaucrat& bureaucrat) { + ostream << bureaucrat.getName() << ", bureaucrat grade " << bureaucrat.getGrade() << "."; + return ostream; +} diff --git a/ex02/src/Bureaucrat.hpp b/ex02/src/Bureaucrat.hpp new file mode 100644 index 0000000..e759198 --- /dev/null +++ b/ex02/src/Bureaucrat.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include +#include + +class AForm; + +class Bureaucrat { + public: + Bureaucrat(); + Bureaucrat(const Bureaucrat& other); + Bureaucrat(const std::string& name); + Bureaucrat(const std::string& name, const unsigned short grade); + + void incrementGrade(); + void decrementGrade(); + + void signForm(AForm& form); + void executeForm(AForm const & form) const; + + const std::string& getName() const; + unsigned short getGrade() const; + + Bureaucrat& operator=(const Bureaucrat& other); + + virtual ~Bureaucrat(); + private: + const std::string name; + + unsigned short grade; + + void setGrade(const unsigned short grade); + + class GradeTooHighException : public std::exception { + public: + const char* what() const throw(); + }; + + class GradeTooLowException : public std::exception { + public: + const char* what() const throw(); + }; +}; + +std::ostream& operator<<(std::ostream& ostream, const Bureaucrat& bureaucrat); diff --git a/ex02/src/PresidentialPardonForm.cpp b/ex02/src/PresidentialPardonForm.cpp new file mode 100644 index 0000000..159316e --- /dev/null +++ b/ex02/src/PresidentialPardonForm.cpp @@ -0,0 +1,36 @@ +#include + +PresidentialPardonForm::PresidentialPardonForm() : AForm("PresidentialPardonForm", 25, 5), target("Arthur Dent") { + std::cout << "PresidentialPardonForm default constructor called" << std::endl; +} + +PresidentialPardonForm::PresidentialPardonForm(const PresidentialPardonForm& other) : AForm(other), target(other.target) { + std::cout << "PresidentialPardonForm copy constructor called" << std::endl; +} + +PresidentialPardonForm::PresidentialPardonForm(const std::string& target) : AForm("PresidentialPardonForm", 25, 5), target(target) { + std::cout << "PresidentialPardonForm (target) constructor called" << std::endl; +} + +void PresidentialPardonForm::executeAction() const { + std::cout << target << " has been pardoned by Zaphod Beeblebrox" << std::endl; +} + +const std::string& PresidentialPardonForm::getTarget() const { + return target; +} + +PresidentialPardonForm& PresidentialPardonForm::operator=(const PresidentialPardonForm& other) { + std::cout << "PresidentialPardonForm assignment operator called" << std::endl; + + if (this != &other) { + AForm::operator=(other); + target = other.target; + } + + return *this; +} + +PresidentialPardonForm::~PresidentialPardonForm() { + std::cout << "PresidentialPardonForm destructor called" << std::endl; +} diff --git a/ex02/src/PresidentialPardonForm.hpp b/ex02/src/PresidentialPardonForm.hpp new file mode 100644 index 0000000..4a0885f --- /dev/null +++ b/ex02/src/PresidentialPardonForm.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +class PresidentialPardonForm : public AForm { + public: + PresidentialPardonForm(); + PresidentialPardonForm(const PresidentialPardonForm& other); + PresidentialPardonForm(const std::string& target); + + const std::string& getTarget() const; + + PresidentialPardonForm& operator=(const PresidentialPardonForm& other); + + virtual ~PresidentialPardonForm(); + + protected: + virtual void executeAction() const; + + private: + std::string target; +}; diff --git a/ex02/src/RobotomyRequestForm.cpp b/ex02/src/RobotomyRequestForm.cpp new file mode 100644 index 0000000..644fb90 --- /dev/null +++ b/ex02/src/RobotomyRequestForm.cpp @@ -0,0 +1,50 @@ +#include +#include +#include + +RobotomyRequestForm::RobotomyRequestForm() : AForm("RobotomyRequestForm", 72, 45), target("Marvin") { + std::cout << "RobotomyRequestForm default constructor called" << std::endl; +} + +RobotomyRequestForm::RobotomyRequestForm(const RobotomyRequestForm& other) : AForm(other), target(other.target) { + std::cout << "RobotomyRequestForm copy constructor called" << std::endl; +} + +RobotomyRequestForm::RobotomyRequestForm(const std::string& target) : AForm("RobotomyRequestForm", 72, 45), target(target) { + std::cout << "RobotomyRequestForm (target) constructor called" << std::endl; +} + +void RobotomyRequestForm::executeAction() const { + static bool seeded = false; + + if (!seeded) { + std::srand(static_cast(std::time(NULL))); + seeded = true; + } + + std::cout << "* Bzzzzzz... Whirrrrr... Vrrrrrrrr... *" << std::endl; + + if (std::rand() % 2) + std::cout << target << " has been robotomized successfully" << std::endl; + else + std::cout << "The robotomy of " << target << " failed" << std::endl; +} + +const std::string& RobotomyRequestForm::getTarget() const { + return target; +} + +RobotomyRequestForm& RobotomyRequestForm::operator=(const RobotomyRequestForm& other) { + std::cout << "RobotomyRequestForm assignment operator called" << std::endl; + + if (this != &other) { + AForm::operator=(other); + target = other.target; + } + + return *this; +} + +RobotomyRequestForm::~RobotomyRequestForm() { + std::cout << "RobotomyRequestForm destructor called" << std::endl; +} diff --git a/ex02/src/RobotomyRequestForm.hpp b/ex02/src/RobotomyRequestForm.hpp new file mode 100644 index 0000000..3b38616 --- /dev/null +++ b/ex02/src/RobotomyRequestForm.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +class RobotomyRequestForm : public AForm { + public: + RobotomyRequestForm(); + RobotomyRequestForm(const RobotomyRequestForm& other); + RobotomyRequestForm(const std::string& target); + + const std::string& getTarget() const; + + RobotomyRequestForm& operator=(const RobotomyRequestForm& other); + + virtual ~RobotomyRequestForm(); + + protected: + virtual void executeAction() const; + + private: + std::string target; +}; diff --git a/ex02/src/ShrubberyCreationForm.cpp b/ex02/src/ShrubberyCreationForm.cpp new file mode 100644 index 0000000..c31c726 --- /dev/null +++ b/ex02/src/ShrubberyCreationForm.cpp @@ -0,0 +1,70 @@ +#include +#include + +ShrubberyCreationForm::ShrubberyCreationForm() : AForm("ShrubberyCreationForm", 145, 137), target("home") { + std::cout << "ShrubberyCreationForm default constructor called" << std::endl; +} + +ShrubberyCreationForm::ShrubberyCreationForm(const ShrubberyCreationForm& other) : AForm(other), target(other.target) { + std::cout << "ShrubberyCreationForm copy constructor called" << std::endl; +} + +ShrubberyCreationForm::ShrubberyCreationForm(const std::string& target) : AForm("ShrubberyCreationForm", 145, 137), target(target) { + std::cout << "ShrubberyCreationForm (target) constructor called" << std::endl; +} + +void ShrubberyCreationForm::executeAction() const { + std::ofstream file((target + "_shrubbery").c_str()); + + if (!file.is_open()) + throw FileCreationException(); + + file + << " _-_ " << std::endl + << " /~~ ~~\\ " << std::endl + << " /~~ ~~\\ " << std::endl + << "{ } " << std::endl + << " \\ _- -_ / " << std::endl + << " ~ \\\\ // ~ " << std::endl + << "_- - | | _- _ " << std::endl + << " _ - | | -_ " << std::endl + << " // \\\\ " << std::endl + << std::endl + << " &&& && & && " << std::endl + << " && &\\/&\\|& ()|/ @, &&" << std::endl + << " &\\/(/&/&||/& /_/)_&/_&" << std::endl + << " &() &\\/&|()|/&\\/ '%\" &" << std::endl + << " &_\\_&&_\\ |& |&&/&__%_/_&" << std::endl + << "& && & &| &| /& & % ()& " << std::endl + << " ()&_---()&\\&\\|&&-&&--%---()~" << std::endl + << " && \\||| " << std::endl + << " ||| " << std::endl + << " ||| " << std::endl + << " ||| " << std::endl + << " , -=-~ .-^- _ " << std::endl; + + file.close(); +} + +const std::string& ShrubberyCreationForm::getTarget() const { + return target; +} + +ShrubberyCreationForm& ShrubberyCreationForm::operator=(const ShrubberyCreationForm& other) { + std::cout << "ShrubberyCreationForm assignment operator called" << std::endl; + + if (this != &other) { + AForm::operator=(other); + target = other.target; + } + + return *this; +} + +ShrubberyCreationForm::~ShrubberyCreationForm() { + std::cout << "ShrubberyCreationForm destructor called" << std::endl; +} + +const char* ShrubberyCreationForm::FileCreationException::what() const throw() { + return "Shrubbery file could not be created"; +} diff --git a/ex02/src/ShrubberyCreationForm.hpp b/ex02/src/ShrubberyCreationForm.hpp new file mode 100644 index 0000000..4545183 --- /dev/null +++ b/ex02/src/ShrubberyCreationForm.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include + +class ShrubberyCreationForm : public AForm { + public: + ShrubberyCreationForm(); + ShrubberyCreationForm(const ShrubberyCreationForm& other); + ShrubberyCreationForm(const std::string& target); + + const std::string& getTarget() const; + + ShrubberyCreationForm& operator=(const ShrubberyCreationForm& other); + + virtual ~ShrubberyCreationForm(); + + class FileCreationException : public std::exception { + public: + const char* what() const throw(); + }; + + protected: + virtual void executeAction() const; + + private: + std::string target; +}; diff --git a/ex02/src/main.cpp b/ex02/src/main.cpp new file mode 100644 index 0000000..ccac43e --- /dev/null +++ b/ex02/src/main.cpp @@ -0,0 +1,255 @@ +#include +#include +#include +#include +#include +#include +#include + +int main() { + { + Bureaucrat franck; + std::cout << franck << std::endl; + franck.incrementGrade(); + std::cout << franck << std::endl; + + Bureaucrat alain("Alain"); + std::cout << alain << std::endl; + alain.incrementGrade(); + std::cout << alain << std::endl; + + Bureaucrat james("James", 1); + std::cout << james << std::endl; + james.decrementGrade(); + std::cout << james << std::endl; + } + + std::cout << "================ Exceptions ================" << std::endl; + { + std::cout << "=== Decrement too low ===" << std::endl; + try { + Bureaucrat franckAlainJamesLeboeuf; + std::cout << franckAlainJamesLeboeuf << std::endl; + franckAlainJamesLeboeuf.decrementGrade(); + } catch (const std::exception& exception) { + std::cout << exception.what() << std::endl; + } + + std::cout << "=== Increment too high ===" << std::endl; + try { + Bureaucrat franckAlainJamesLeboeuf("Franck Alain James Leboeuf", 1); + std::cout << franckAlainJamesLeboeuf << std::endl; + franckAlainJamesLeboeuf.incrementGrade(); + } catch (const std::exception& exception) { + std::cout << exception.what() << std::endl; + } + + std::cout << "=== Construct too low ===" << std::endl; + try { + Bureaucrat franckAlainJamesLeboeuf("Franck Alain James Leboeuf", 151); + } catch (const std::exception& exception) { + std::cout << exception.what() << std::endl; + } + + std::cout << "=== Construct too high ===" << std::endl; + try { + Bureaucrat franckAlainJamesLeboeuf("Franck Alain James Leboeuf", 0); + } catch (const std::exception& exception) { + std::cout << exception.what() << std::endl; + } + } + + // std::cout << "================================ Forms ================================" << std::endl; + // { + // Bureaucrat franck; + // Form vente; + // std::cout << vente << std::endl; + // vente.beSigned(franck); + // std::cout << vente << std::endl; + // Form vente2; + // std::cout << vente2 << std::endl; + // franck.signForm(vente2); + // std::cout << vente2 << std::endl; + + // Bureaucrat alain("Alain"); + // Form contrat("Contrat"); + // std::cout << contrat << std::endl; + // contrat.beSigned(alain); + // std::cout << contrat << std::endl; + // Form contrat2("Contrat2"); + // std::cout << contrat2 << std::endl; + // alain.signForm(contrat2); + // std::cout << contrat2 << std::endl; + + // Bureaucrat james("James", 1); + // Form achat("Achat", 1, 1); + // std::cout << achat << std::endl; + // achat.beSigned(james); + // std::cout << achat << std::endl; + // Form achat2("Achat2", 1, 1); + // std::cout << achat2 << std::endl; + // james.signForm(achat2); + // std::cout << achat2 << std::endl; + + // Bureaucrat franckAlainJamesLeboeuf("Franck Alain James Leboeuf", 1); + // Form contratAlternance("Contrat Alternance", 1, 1); + // std::cout << contratAlternance << std::endl; + // contratAlternance.beSigned(franckAlainJamesLeboeuf); + // std::cout << contratAlternance << std::endl; + // contratAlternance.beSigned(franckAlainJamesLeboeuf); + // std::cout << contratAlternance << std::endl; + // Form contractAlternance2("Contrat Alternance 2", 1, 1); + // franckAlainJamesLeboeuf.signForm(contractAlternance2); + // std::cout << contractAlternance2 << std::endl; + // franckAlainJamesLeboeuf.signForm(contractAlternance2); + // std::cout << contractAlternance2 << std::endl; + // } + + // std::cout << "================ Exceptions ================" << std::endl; + // { + // std::cout << "=== Construct both grade too low ===" << std::endl; + // try { + // Form vente("Vente", 151, 151); + // } catch (const std::exception& exception) { + // std::cout << exception.what() << std::endl; + // } + + // std::cout << "=== Construct both grade too high ===" << std::endl; + // try { + // Form vente("Vente", 0, 0); + // } catch (const std::exception& exception) { + // std::cout << exception.what() << std::endl; + // } + + // std::cout << "=== Construct to sign grade too low ===" << std::endl; + // try { + // Form vente("Vente", 151, 150); + // } catch (const std::exception& exception) { + // std::cout << exception.what() << std::endl; + // } + + // std::cout << "=== Construct to sign grade too high ===" << std::endl; + // try { + // Form vente("Vente", 0, 0); + // } catch (const std::exception& exception) { + // std::cout << exception.what() << std::endl; + // } + + // std::cout << "=== Construct to execute grade too low ===" << std::endl; + // try { + // Form vente("Vente", 150, 151); + // } catch (const std::exception& exception) { + // std::cout << exception.what() << std::endl; + // } + + // std::cout << "=== Construct to execute grade too high ===" << std::endl; + // try { + // Form vente("Vente", 150, 0); + // } catch (const std::exception& exception) { + // std::cout << exception.what() << std::endl; + // } + + // std::cout << "=== Grade to be signed too low ===" << std::endl; + // try { + // Bureaucrat franck; + // Form vente("Vente", 1, 1); + // vente.beSigned(franck); + // } catch (const std::exception& exception) { + // std::cout << exception.what() << std::endl; + // } + + // std::cout << "=== Grade to sign form too low ===" << std::endl; + // try { + // Bureaucrat franck; + // Form vente("Vente", 1, 1); + // franck.signForm(vente); + // } catch (const std::exception& exception) { + // std::cout << exception.what() << std::endl; + // } + // } + + std::cout << "================================ Concrete forms ================================" << std::endl; + { + std::cout << "=== Shrubbery creation ===" << std::endl; + Bureaucrat james("James", 1); + ShrubberyCreationForm jardin("Jardin"); + std::cout << jardin << std::endl; + james.signForm(jardin); + std::cout << jardin << std::endl; + james.executeForm(jardin); + + std::cout << "=== Robotomy request ===" << std::endl; + RobotomyRequestForm marvin("Marvin"); + std::cout << marvin << std::endl; + james.signForm(marvin); + std::cout << marvin << std::endl; + james.executeForm(marvin); + james.executeForm(marvin); + james.executeForm(marvin); + james.executeForm(marvin); + + std::cout << "=== Presidential pardon ===" << std::endl; + PresidentialPardonForm arthur("Arthur Dent"); + std::cout << arthur << std::endl; + james.signForm(arthur); + std::cout << arthur << std::endl; + james.executeForm(arthur); + + std::cout << "=== Execute through base reference ===" << std::endl; + PresidentialPardonForm ford("Ford Prefect"); + AForm& form = ford; + james.signForm(form); + james.executeForm(form); + } + + std::cout << "================ Exceptions ================" << std::endl; + { + std::cout << "=== Execute form not signed ===" << std::endl; + Bureaucrat james("James", 1); + PresidentialPardonForm arthur("Arthur Dent"); + james.executeForm(arthur); + + std::cout << "=== Sign grade too low ===" << std::endl; + Bureaucrat franck; + ShrubberyCreationForm jardin("Jardin"); + franck.signForm(jardin); + std::cout << jardin << std::endl; + + std::cout << "=== Execute grade too low ===" << std::endl; + Bureaucrat alain("Alain", 140); + ShrubberyCreationForm maison("Maison"); + alain.signForm(maison); + std::cout << maison << std::endl; + alain.executeForm(maison); + james.executeForm(maison); + + std::cout << "=== Execute grade boundaries ===" << std::endl; + Bureaucrat zaphod("Zaphod", 45); + RobotomyRequestForm trillian("Trillian"); + zaphod.signForm(trillian); + zaphod.executeForm(trillian); + zaphod.decrementGrade(); + std::cout << zaphod << std::endl; + zaphod.executeForm(trillian); + + std::cout << "=== Execute not signed then grade too low (direct) ===" << std::endl; + try { + Bureaucrat leboeuf; + PresidentialPardonForm pardon("Franck Leboeuf"); + pardon.execute(leboeuf); + } catch (const std::exception& exception) { + std::cout << exception.what() << std::endl; + } + + std::cout << "=== Execute grade too low (direct) ===" << std::endl; + try { + Bureaucrat leboeuf; + Bureaucrat president("President", 1); + PresidentialPardonForm pardon("Franck Leboeuf"); + pardon.beSigned(president); + pardon.execute(leboeuf); + } catch (const std::exception& exception) { + std::cout << exception.what() << std::endl; + } + } +}