MIF31 - Projet 2013
 All Classes Files Functions Variables Friends
pointeur.h
Go to the documentation of this file.
1 #ifndef POINTEUR_H
2 #define POINTEUR_H
3 
4 
5 #include <string>
6 #include <iostream>
7 #include <sstream>
8 #include <cstddef>
9 #include <new>
10 #include <vector>
11 
12 
13 class compteurPI;
14 template<typename T>
16 template<typename T>
17 std::ostream& operator<<(std::ostream &, const pIntelligent<T> &);
18 template<typename T>
19 class node;
20 template<typename T>
21 class vectorPI;
22 
23 
24 
33 class compteurPI{
34 
35  private:
39  int nbr;
40 
41  public:
48  this->nbr = 0;
49 #ifdef DEBUG
50  std::cerr<<"["<<this<<"] compteurPI::new"<<std::endl;
51 #endif
52  }
53 
61  compteurPI(const compteurPI& csp){
62 #ifdef DEBUG
63  std::cerr<<"["<<this<<"] compteurPI::copy("<<&csp<<")"<<std::endl;
64 #endif
65  this->nbr = csp.nbr;
66  }
67 
77 #ifdef DEBUG
78  std::cerr<<"["<<this<<"] compteurPI::copy("<<&csp<<")"<<std::endl;
79 #endif
80  this->nbr = csp.nbr;
81  return *this;
82  }
83 
90 
96  void add(){
97  nbr++;
98 #ifdef DEBUG
99  std::cerr<<"["<<this<<"] compteurPI::++"<<std::endl;
100 #endif
101  }
102 
108  void remove() {
109  nbr--;
110 #ifdef DEBUG
111  std::cerr<<"["<<this<<"] compteurPI::--"<<std::endl;
112 #endif
113  }
114 
122  int count() const{ return nbr;}
123 };
124 
125 
126 
127 
128 
129 
138 template<typename T>
139 class node{
140 
141  private:
142 
143  protected:
144 
149 
153  std::vector<node<T>*> parents;
154 
158  std::vector<node<T>*> children;
159 
167  int state;
168 
169  public:
175  node(){}
176 
185 #ifdef DEBUG
186  std::cerr<<"["<<this<<"] node::new"<<std::endl;
187 #endif
188  this->ptrI = ptrI;
189  this->state = 0;
190  }
191 
199  node(const node<T>& n){
200 #ifdef DEBUG
201  std::cerr<<"["<<this<<"] node::copy("<<&n<<")"<<std::endl;
202 #endif
203  this->ptrI = n.ptrI;
204  this->state = n.state;
205  }
206 
212  ~node(){
213 #ifdef DEBUG
214  std::cerr<<"["<<this<<"] node::delete"<<std::endl;
215 #endif
216  clear();
217  }
218 
224  void clear(){
225  for(unsigned i = 0; i<parents.size();i++){
226  parents[i]->removeChild(this);
227 #ifdef DEBUG
228  std::cerr<<"["<<this<<"] node::removeParents(erease "<<&parents[i]<<") "<<parents[i]->ptrI->count()<<" refs "<<std::endl;
229 #endif
230  parents.erase(parents.begin()+i);
231  }
232 
233  for(unsigned i = 0; i<children.size();i++){
234  children[i]->removeParent(this);
235 #ifdef DEBUG
236  std::cerr<<"["<<this<<"] node::removeChild(erease "<<&children[i]<<") "<<children[i]->ptrI->count()<<" refs "<<std::endl;
237 #endif
238  children.erase(children.begin()+i);
239  }
240  }
241 
250  bool findChild(const node<T>* n) const{
251  for(unsigned i = 0; i<children.size();i++)
252  if(children[i] == n) return true;
253  return false;
254  }
263  bool findParent(const node<T>* n) const{
264  for(unsigned i = 0; i<parents.size();i++)
265  if(parents[i] == n) return true;
266  return false;
267  }
268 
276  void addParent(node<T>* n){
277 
278  if(!findParent(n)){
279  parents.push_back(n);
280 #ifdef DEBUG
281  std::cerr<<"["<<this<<"] node::addParent("<<&n<<")"<<std::endl;
282 #endif
283  }
284  n->addChild(this);
285  }
286 
287 
296 #ifdef DEBUG
297  std::cerr<<"["<<this<<"] node::removeParents("<<parents.size()<<")"<<std::endl;
298 #endif
299  for(unsigned i = 0; i<parents.size();i++)
300  if(parents[i] == n)
301  parents.erase(parents.begin()+i);
302  }
303 
312 #ifdef DEBUG
313  std::cerr<<"["<<this<<"] node::removeChild("<<children.size()<<")"<<std::endl;
314 #endif
315  for(unsigned i = 0; i<children.size();i++)
316  if(children[i] == n)
317  children.erase(children.begin()+i);
318  }
319 
325  void check(){
326  for(unsigned i=0; i<children.size(); i++)
327  children[i]->state = 1;
328  state = 2;
329  }
330 
338  bool hasChild() const{ return children.size()>0; }
339 
347  bool hasParent() const{ return parents.size()>0; }
348 
359  int getState() const{ return state; }
360 
371  void setState(int n){ state=n; }
372 
382 #ifdef DEBUG
383  std::cerr<<"["<<this<<"] node::affect("<<&n<<")"<<std::endl;
384 #endif
385  this->ptrI = n.ptrI;
386  this->state = n.state;
387  return *this;
388  }
389 
398  bool operator==(const node<T>& n) const {
399  return &this->ptrI == &n.ptrI ;
400  }
401 
402  protected:
410  void addChild(node<T>* n){
411  if(!findChild(n)){
412  children.push_back(n);
413 #ifdef DEBUG
414  std::cerr<<"["<<this<<"] node::addChild("<<&n<<")"<<std::endl;
415 #endif
416  }
417  }
418 
419 };
420 
421 
430 template<typename T> class pIntelligent {
431  template<typename> friend class vectorPI;
432  protected:
433 
434  private:
438  T* pointeur;
439 
443  compteurPI* csp;
444 
448  node<T> n;
449 
453  static vectorPI<T> vRef;
454 
455  public:
466  pIntelligent(T* p=0) {
467  this->pointeur = p;
468 #ifdef DEBUG
469  std::cerr<<"["<<this<<"] pIntelligent::new("<<&pointeur<<")"<<std::endl;
470 #endif
471  csp = new compteurPI();
472  csp->add();
473  n = node<T>(this);
474  vRef.push_back(this);
475  }
476 
489 #ifdef DEBUG
490  std::cerr<<"["<<this<<"] pIntelligent::copy("<<&sp<<")"<<std::endl;
491 #endif
492  this->pointeur = sp.pointeur;
493 
494  csp = sp.csp;
495  csp->add();
496  node<T>& tmp = const_cast<node<T>&>(sp.n);
497  n.addParent(&tmp);
498 
499  //n = sp.n;
500  //vRef.push_back(this);
501  }
502 
513  vRef.check();
514  csp->remove();
515 #ifdef DEBUG
516  std::cerr<<"["<<this<<"] pIntelligent::delete ? "<<&csp<<"=>"<<csp->count()<<" ref"<<std::endl;
517 #endif
518  if(csp->count()==0) {
519  // Retirer les références du node vers fils et parents
520  n.clear();
521  if(pointeur!=NULL){
522  delete pointeur;
523  pointeur = NULL;
524  }
525  if(csp != NULL){
526  delete csp;
527  csp = NULL;
528  }
529 #ifdef DEBUG
530  std::cerr<<"["<<this<<"] pIntelligent::delete OK"<<std::endl;
531 #endif
532  }
533  vRef.erase(this);
534  }
535 
541  void forceDelete(){
542 #ifdef DEBUG
543  std::cerr<<"["<<this<<"] pIntelligent::delete ? "<<&csp<<"=>"<<csp->count()<<" ref"<<std::endl;
544 #endif
545  n.clear();
546  csp->remove();
547  if(csp->count()==0) {
548  // Retirer les références du node vers fils et parents
549  if(pointeur != NULL){
550  delete pointeur;
551  pointeur = NULL;
552  }
553  if(csp != NULL){
554  delete csp;
555  csp = NULL;
556  }
557 #ifdef DEBUG
558  std::cerr<<"["<<this<<"] pIntelligent::delete OK"<<std::endl;
559 #endif
560 
561  }
562  vRef.erase(this);
563  }
564 
580 #ifdef DEBUG
581  std::cerr<<"["<<this<<"] pIntelligent::affect("<<&sp<<")"<<std::endl;
582 #endif
583  n.clear();
584  csp->remove();
585  if(csp->count()==0) {
586  // Retirer les références du node vers fils et parents
587  n.clear();
588  if(pointeur != NULL){
589  delete pointeur;
590  pointeur = NULL;
591  }
592  if(csp != NULL){
593  delete csp;
594  csp = NULL;
595  }
596  }
597 
598  csp = sp.csp;
599  pointeur = sp.pointeur;
600 
601  node<T>& tmp = const_cast<node<T>&>(sp.n);
602  n.addParent(&tmp);
603 
604  csp->add();
605 
606  return *this;
607  }
608 
617  void* operator new(size_t sz){
618  void* m = malloc(sz);
619  return m;
620  }
621 
628  void operator delete(void* m) {
629  free(m);
630  }
631 
640  bool operator==(const pIntelligent<T>& sp) const {
641  return this->pointeur == sp.pointeur;
642  }
643 
649  T* operator->() { return pointeur; }
650 
656  const T* operator->() const { return pointeur; }
657 
663  T& operator*() { return *pointeur; }
664 
670  const T& operator*() const { return *pointeur; }
671 
672 
680  const std::string toString() const {
681  std::ostringstream oss;
682  oss << pointeur ;
683  // oss << " ( nb refs : " << this->count() << " )";
684  return std::string( oss.str());
685  }
686 
694  int count() const{ return csp->count(); }
695 
705  friend std::ostream & operator<< <>(std::ostream &, const pIntelligent<T> &);
706 
707 };
708 
709 
710 
711 
712 
713 
722 template<typename T>
723 class vectorPI{
724  protected:
725 
726  private:
727 
731  std::vector<pIntelligent<T>*> v;
732 
733  public:
740 
749  check();
750  clear();
751  }
752 
761  T& operator[] (int i) {
762  return v[i];
763  }
764 
773  const T operator[] (int i) const {
774  return v[i];
775  }
776 
785  v.push_back(e);
786  }
787 
796  for(unsigned i = 0; i<v.size(); i++)
797  if(v[i]==e) v.erase(v.begin()+i);
798  }
799 
807  int size(){
808  return v.size();
809  }
810 
819  void check(){
820  for(unsigned i=0; i<v.size(); i++){
821  if(v[i]->n.hasParent() || v[i]->count() <= 0) v[i]->n.setState(0);
822  else v[i]->n.setState(1);
823  }
824 
825  bool valide;
826  do{
827  valide = true;
828  for(unsigned i=0; i<v.size(); i++){
829  if(v[i]->n.getState() == 1 ){
830  v[i]->n.check();
831  valide = false;
832  }
833  }
834  }while(!valide);
835 
836  for(unsigned i=0; i<v.size(); i++){
837  if(v[i]->n.getState() == 0 ){
838 
839  v[i]->n.clear();
840  }
841  }
842  }
843 
849  void clear(){
850 
851  while(v.size()>0)
852  v[0]->forceDelete();
853 
854  v.clear();
855  }
856 
857 };
858 
859 
860 
861 
862 template <typename T>
863 std::ostream & operator<<(std::ostream & output, const pIntelligent<T> & sp){
864  output << sp.toString() << std::endl;
865  return output;
866 
867 }
868 
869 
870 //template<typename T> vectorPI<node<T>> pIntelligent<T>::vRef = vectorPI<node<T>>();
871 template<typename T> vectorPI<T> pIntelligent<T>::vRef = vectorPI<T>();
872 
873 
874 
875 #endif