/*
 * Person.h    Exercise P-E-M-C, CRTP, Step 2.
 */
#ifndef PERSON_H
#define PERSON_H
#include "CRN.h"
#include <iosfwd>
#include <string>

namespace IDA_Person
{
   class Person
   {
   public:
      virtual ~Person() = default;

      virtual Person* clone() const = 0;

      virtual std::string str() const;

      std::string     get_name() const;
      void            set_name(const std::string&);
      IDA_Person::CRN get_crn() const;
      void            set_crn(const CRN&);

   protected:
      Person(const std::string& name, const IDA_Person::CRN& crn);
      Person(const Person&) = default;
 
   private:
      Person& operator=(const Person&) = delete;

      std::string     name_;
      IDA_Person::CRN crn_;
   };

   std::ostream& operator<<(std::ostream&, const Person&);

   template <typename Base, typename Derived>
   class Person_Cloneable : public Base
   {
   public:
      using Base::Base;  // inheriting constructors

      Base* clone() const override
      {
	 return new Derived(static_cast<const Derived&>(*this));
      }

   protected:
      Person_Cloneable(const Person_Cloneable&) = default;

   private:
      Person_Cloneable& operator=(const Person_Cloneable&) = delete;
   };

} // namespace IDA_Person

#endif