#include <iostream>
#include <vector>

using namespace std;


class P {
  private:
    string nom;
    
  public:
    P(string n) : nom(n) {}
    
    virtual string toString() const {
		return "P_" + nom +"\n" ;
	}
	
	virtual P * adapter(double nbFois) {
		return this;
	}
	
};



class I {
  public:
    I(const P & p_, int a) : p(p_), amount(a) {
	}
	
	string desc() const {
	   string s;
	   s += " " + to_string(amount) + " * ";
	   s += " I_";
	   // call P::toString or PC::toString() ?
	   s += p.toString();
	   
	   return s;
	}
  
  private:
    const P & p;  
    int amount;
  
};


class R {
	
	private:
	  vector<I> is;
	  string nom;
	  
	public:
	   R(string n) : nom(n) {
	   }
	   
	   void add(const P & p, int amount) {
		   I i(p, amount);
		   is.push_back(i);
	   }
	   
	   string toString() const {
		   string s;
		   for (auto i : is) {
			   s += "  ";
			   s += i.desc() + "\n";
		   }
		   return s;
	   }
	   

};


class PC : public P {
	
	private:
	  R r;
	
	
	public:
	
	PC(string n) : P(n), r(n) {
	}
	
	string toString() const {
		string s;
		s += "PC ";
		s += P::toString();
		s += r.toString();
		
		return s;
	}
	
	void addToR(const P & p, int amount) {
		r.add(p, amount);
	}

	PC * adapter(double nbFois) {
		cout << "PC_adapt" << endl;
		return this;
	}
	

};

int main() {

  P p1("abc");
  P p2("def");
  
  PC pc("abc_def");
  pc.addToR(p1, 1);
  pc.addToR(p2, 1);
  
  cout << pc.toString() << endl;
  
  P p3("hij");
  PC pc2("hij_abc_def");
  pc2.addToR(p3, 1);
  pc2.addToR(pc, 2);
  
  cout << pc2.toString() << endl;
  

  return 0;
  
}
