--- /dev/null
+#include "Bureaucrat.h"
+
+Bureaucrat::Bureaucrat()
+{
+}
+
+Bureaucrat::Bureaucrat(const std::string &name, int grade)
+ : m_name(name)
+ , m_grade(grade)
+{
+ if (grade < HIGHEST_GRADE)
+ throw (Bureaucrat::GradeTooHighException());
+ else if (grade > LOWEST_GRADE)
+ throw (Bureaucrat::GradeTooLowException());
+}
+
+Bureaucrat::Bureaucrat(const Bureaucrat &other)
+{
+ *this = other;
+}
+
+Bureaucrat::~Bureaucrat()
+{
+}
+
+Bureaucrat &Bureaucrat::operator=(const Bureaucrat &other)
+{
+ if (this == &other)
+ return (*this);
+ return (*this);
+}
+
+const std::string &Bureaucrat::getName() const
+{
+ return (m_name);
+}
+
+int Bureaucrat::getGrade() const
+{
+ return (m_grade);
+}
+
+void Bureaucrat::promote()
+{
+ if (m_grade == HIGHEST_GRADE)
+ throw (Bureaucrat::GradeTooHighException());
+ --m_grade;
+}
+
+void Bureaucrat::demote()
+{
+ if (m_grade == LOWEST_GRADE)
+ throw (Bureaucrat::GradeTooLowException());
+ ++m_grade;
+}
+
+std::ostream &operator<<(std::ostream &ostream, const Bureaucrat &bureaucrat)
+{
+ ostream << bureaucrat.getName() << ", bureaucrat of grade " << bureaucrat.getGrade();
+ return (ostream);
+}
+
+Bureaucrat::GradeTooLowException::GradeTooLowException()
+ : std::runtime_error::runtime_error("Bureaucrat grade cannot be lower")
+{
+}
+
+Bureaucrat::GradeTooLowException::GradeTooLowException(const Bureaucrat::GradeTooLowException &other)
+ : std::runtime_error::runtime_error(other.what())
+{
+}
+
+Bureaucrat::GradeTooLowException::~GradeTooLowException() throw()
+{
+}
+
+Bureaucrat::GradeTooLowException &Bureaucrat::GradeTooLowException::operator=(const Bureaucrat::GradeTooLowException &other)
+{
+ std::runtime_error::operator = (other);
+ return (*this);
+}
+
+Bureaucrat::GradeTooHighException::GradeTooHighException()
+ : std::runtime_error::runtime_error("Bureaucrat grade cannot be higher")
+{
+}
+
+Bureaucrat::GradeTooHighException::GradeTooHighException(const Bureaucrat::GradeTooHighException &other)
+ : std::runtime_error::runtime_error(other.what())
+{
+}
+
+Bureaucrat::GradeTooHighException::~GradeTooHighException() throw()
+{
+}
+
+Bureaucrat::GradeTooHighException &Bureaucrat::GradeTooHighException::operator=(const Bureaucrat::GradeTooHighException &other)
+{
+ std::runtime_error::operator = (other);
+ return (*this);
+}
--- /dev/null
+#ifndef BUREAUCRAT_H
+# define BUREAUCRAT_H
+
+#include <string>
+#include <stdexcept>
+#include <iostream>
+
+class Bureaucrat
+{
+ private:
+ const std::string m_name;
+ int m_grade;
+
+ static const int LOWEST_GRADE = 150;
+ static const int HIGHEST_GRADE = 1;
+
+ Bureaucrat();
+ Bureaucrat(const Bureaucrat &other);
+
+ Bureaucrat &operator=(const Bureaucrat &other);
+
+ public:
+ Bureaucrat(const std::string &name, int grade);
+ ~Bureaucrat();
+
+ const std::string &getName() const;
+ int getGrade() const;
+ void promote();
+ void demote();
+
+ class GradeTooLowException;
+ class GradeTooHighException;
+};
+
+std::ostream &operator<<(std::ostream &ostream, const Bureaucrat &bureaucrat);
+
+class Bureaucrat::GradeTooLowException : public std::runtime_error
+{
+ public:
+ GradeTooLowException();
+ GradeTooLowException(const GradeTooLowException &other);
+ ~GradeTooLowException() throw();
+
+ GradeTooLowException &operator=(const GradeTooLowException &other);
+};
+
+class Bureaucrat::GradeTooHighException : public std::runtime_error
+{
+ public:
+ GradeTooHighException();
+ GradeTooHighException(const GradeTooHighException &other);
+ ~GradeTooHighException() throw();
+
+ GradeTooHighException &operator=(const GradeTooHighException &other);
+};
+
+#endif // BUREAUCRAT_H
--- /dev/null
+CC := c++
+CFLAGS = -std=c++98 -Wall -Wextra -Werror -Wpedantic
+
+ifneq ("$(wildcard .debug)","")
+ CFLAGS += -g
+endif
+
+RM := rm -f
+
+INCDIR := inc
+INCDIR += $(addsuffix /inc, $(SUBPROJECTS));
+ifneq ($(INCLUDE),)
+ INCLUDE := $(addprefix -I, $(INCDIR))
+endif
+
+SRCDIR := .
+
+SOURCES := main.cpp \
+ Bureaucrat.cpp \
+
+SOURCES := $(addprefix $(SRCDIR)/, $(SOURCES))
+
+OBJECTS := $(SOURCES:.cpp=.o)
+
+NAME := bureaucrat
+
+all : $(NAME)
+
+debug : .debug
+ $(MAKE) all
+
+nodebug :
+ $(RM) .debug
+ $(MAKE) re
+
+.% :
+ $(MAKE) fclean
+ touch $@
+
+$(NAME) : $(OBJECTS)
+ $(CC) $(CFLAGS) -o $@ $^ $(LINKS)
+
+%.o : %.cpp
+ $(CC) $(CFLAGS) -o $@ -c $< $(INCLUDE)
+
+clean :
+ $(RM) $(OBJECTS)
+
+fclean : clean
+ $(RM) $(NAME)
+
+re : fclean
+ $(MAKE) all
--- /dev/null
+#include "Bureaucrat.h"
+
+void lifecycle(const std::string &name, int grade)
+{
+ Bureaucrat b(name, grade);
+
+ std::cout << b << ", has been created.\n";
+ b.promote();
+ std::cout << b << ", has just been promoted.\n";
+ b.demote();
+ b.demote();
+ std::cout << b << ", has just been demoted twice.\n";
+}
+
+int main()
+{
+ try
+ {
+ lifecycle("Zero", 0);
+ }
+ catch (const Bureaucrat::GradeTooHighException &exception)
+ {
+ std::cout << "High grade: " << exception.what() << '\n';
+ }
+ catch (const Bureaucrat::GradeTooLowException &exception)
+ {
+ std::cout << "Low grade: " << exception.what() << '\n';
+ }
+ try
+ {
+ lifecycle("One", 1);
+ }
+ catch (const Bureaucrat::GradeTooHighException &exception)
+ {
+ std::cout << "High grade: " << exception.what() << '\n';
+ }
+ catch (const Bureaucrat::GradeTooLowException &exception)
+ {
+ std::cout << "Low grade: " << exception.what() << '\n';
+ }
+ try
+ {
+ lifecycle("Two", 2);
+ }
+ catch (const Bureaucrat::GradeTooHighException &exception)
+ {
+ std::cout << "High grade: " << exception.what() << '\n';
+ }
+ catch (const Bureaucrat::GradeTooLowException &exception)
+ {
+ std::cout << "Low grade: " << exception.what() << '\n';
+ }
+ try
+ {
+ lifecycle("Hundred", 100);
+ }
+ catch (const Bureaucrat::GradeTooHighException &exception)
+ {
+ std::cout << "High grade: " << exception.what() << '\n';
+ }
+ catch (const Bureaucrat::GradeTooLowException &exception)
+ {
+ std::cout << "Low grade: " << exception.what() << '\n';
+ }
+ try
+ {
+ lifecycle("Hundred Forty Nine", 149);
+ }
+ catch (const Bureaucrat::GradeTooHighException &exception)
+ {
+ std::cout << "High grade: " << exception.what() << '\n';
+ }
+ catch (const Bureaucrat::GradeTooLowException &exception)
+ {
+ std::cout << "Low grade: " << exception.what() << '\n';
+ }
+ try
+ {
+ lifecycle("Hundred Fifty", 150);
+ }
+ catch (const Bureaucrat::GradeTooHighException &exception)
+ {
+ std::cout << "High grade: " << exception.what() << '\n';
+ }
+ catch (const Bureaucrat::GradeTooLowException &exception)
+ {
+ std::cout << "Low grade: " << exception.what() << '\n';
+ }
+ try
+ {
+ lifecycle("Hundred Fifty One", 151);
+ }
+ catch (const Bureaucrat::GradeTooHighException &exception)
+ {
+ std::cout << "High grade: " << exception.what() << '\n';
+ }
+ catch (const Bureaucrat::GradeTooLowException &exception)
+ {
+ std::cout << "Low grade: " << exception.what() << '\n';
+ }
+ return (0);
+}