/*

UTILISATION DE L'OPERATEUR XOR

Liste doublement chaînée avec le ou exclusif.
Le pointeur est remplacé par un ou exclusif entre les pointeurs amont et aval.
Liste A B C D
Pointeur  A = 0 ^ B  B = A ^ C  C = B ^ D  D = C ^ 0 
->  B = A ^ 0  C = B ^ A  D = C ^ B  0 = D ^ C = NUL 
<-  0 = A ^ B  A = B ^ C  B = C ^ D  C = D ^ 0 

Il est possible de remplacer le ou exclusif par une autre opération
Exemple avec + et - :
Liste A B C D
Pointeur  A = 0 + B  B = A + C  C = B + D  D = C + 0 
->  B = A - 0  C = B - A  D = C - B  0 = D - C = NUL 
<-  0 = A - B  A = B - C  B = C - D  C = D - 0 
*/
#include <iostream.h>  // intervertir a et b inline void swap (int & a, int & b) { a ^= b; b ^= a; a ^= b; }
template <typename T> class list; template <typename T> class node { friend class list<T>; private: T data; node * prevnext; node(T _data) : data(_data) {} // public: // T getData() { return data;} // T operator()() { return data;} }; template <typename T> class list { private: node<T> * head, * tail; public: list() { head = tail = NULL;} #pragma warn -inl ~list() { node<T> * tmp, * dummy = head, * next = NULL; while (dummy) { tmp = dummy; (int)dummy = (int)dummy -> prevnext ^ (int)next; next = tmp; delete tmp; } } #pragma warn +inl T getDataHead() { return head -> data;} T getDataTail() { return tail -> data;} // node<T> * getHead() const { return head;} // node<T> * getTail() const { return tail;} #define add_at_(Head, Tail)\ \ node<T> * add_at_##Head(T data)\ {\ node<T> * t = new node<T>(data);\ t -> prevnext = Head;\ if (Head) (int)Head -> prevnext ^= (int)t;\ else Tail = t;\ return Head = t;\ } add_at_(head, tail) add_at_(tail, head) void inverse() { // node<T> * n = head; head = tail; tail = n; //(int)head ^= (int)tail; //(int)tail ^= (int)head; //(int)head ^= (int)tail; swap((int)head, (int)tail); } typedef void (* function)(T); #define list_(Head, Tail)\ \ void list_##Head(function func)\ {\ node<T> * tmp, * dummy = Head, * next = NULL;\ while (dummy)\ {\ func(dummy -> data);\ tmp = dummy;\ (int)dummy = (int)dummy -> prevnext ^ (int)next;\ next = tmp;\ }\ } #pragma warn -inl list_(head, tail) list_(tail, head) #pragma warn +inl #define del_(Head)\ \ void del_##Head()\ {\ if(head)\ {\ if(head == tail)\ {\ delete head;\ head = tail = NULL;\ }\ else\ {\ node<T> * tmp = Head;\ if (Head -> prevnext)\ {\ (int)Head -> prevnext -> prevnext ^= (int)Head;\ Head = Head -> prevnext;\ }\ delete tmp;\ }\ }\ } del_(head); del_(tail); #pragma warn -inl unsigned long countNodes() { unsigned long nodes = 0; node<T> * tmp, * dummy = head, * next = NULL; while (dummy) { nodes++; tmp = dummy; (int)dummy = (int)dummy -> prevnext ^ (int)next; next = tmp; } return nodes; } void insertValue(T _data) { node<T> * tmp, * next = NULL, * dummy = head, * newNode = new node<T>(_data); while (dummy && dummy -> data < newNode -> data) { tmp = dummy; (int)dummy = (int)dummy -> prevnext ^ (int)next; next = tmp; } (int)newNode -> prevnext = (int)next ^ (int)dummy; if (dummy) (int)dummy -> prevnext = (int)dummy -> prevnext ^ (int)next ^ (int)newNode; else tail = newNode; if (next) (int)next -> prevnext = (int) next -> prevnext ^ (int)dummy ^ (int)newNode; else head = newNode; } #pragma warn +inl }; inline void func(int data) { cout << data << " "; } void main() { list<int> * l = new list<int>(); for(int i = 0; i <= 9; i++) l -> add_at_tail(i); l -> list_head(func); cout << endl; l -> inverse(); l -> list_head(func); cout << endl; l -> list_tail(func); cout << endl; l -> inverse(); l -> list_tail(func); cout << endl << l -> getDataHead() << " " << l -> getDataTail(); delete l; }