slink.H

00001 
00002 /*
00003   This file is part of Aleph system
00004 
00005   Copyright (c) 2002, 2003, 2004, 2005, 2006
00006   UNIVERSITY LOS ANDES (ULA) Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA  
00007 
00008   - Center of Studies in Microelectronics & Distributed Systems (CEMISID) 
00009   - ULA Computer Science Department
00010   - FUNDACITE Mérida - Ministerio de Ciencia y Tecnología
00011 
00012   PERMISSION TO USE, COPY, MODIFY AND DISTRIBUTE THIS SOFTWARE AND ITS
00013   DOCUMENTATION IS HEREBY GRANTED, PROVIDED THAT BOTH THE COPYRIGHT
00014   NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES OF THE
00015   SOFTWARE, DERIVATIVE WORKS OR MODIFIED VERSIONS, AND ANY PORTIONS
00016   THEREOF, AND THAT BOTH NOTICES APPEAR IN SUPPORTING DOCUMENTATION.
00017 
00018   Aleph is distributed in the hope that it will be useful, but WITHOUT
00019   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00020   or FITNESS FOR A PARTICULAR PURPOSE.
00021 
00022   UNIVERSIDAD DE LOS ANDES requests users of this software to return to 
00023 
00024   Leandro Leon
00025   CEMISID 
00026   Ed La Hechicera 
00027   3er piso, ala sur
00028   Facultad de Ingenieria 
00029   Universidad de Los Andes 
00030   Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA    or
00031 
00032   lrleon@ula.ve
00033 
00034   any improvements or extensions that they make and grant Universidad 
00035   de Los Andes (ULA) the rights to redistribute these changes. 
00036 
00037   Aleph is (or was) granted by: 
00038   - Consejo de Desarrollo Cientifico, Humanistico, Tecnico de la ULA 
00039     (CDCHT)
00040   - Fundacite Mérida
00041 */
00042 
00043 
00044 # ifndef SLINK_H
00045 # define SLINK_H
00046 
00047 # include <aleph.H>
00048 
00049 using namespace Aleph;
00050 
00051 namespace Aleph {
00052 
00061 class Slink
00062 {
00063   protected:
00064     Slink* next;
00065 
00066 public:
00067 
00069   Slink() : next(this) { /* Empty */ }
00070 
00072   Slink(const Slink & link)
00073   {
00074     if (not link.is_empty())
00075       throw std::invalid_argument ("link is not empty");
00076 
00077     next = this; 
00078   }
00079 
00081   Slink & operator = (const Slink & link)
00082   {
00083 
00084     if (&link == this)
00085       return *this;
00086 
00087     if (not is_empty())
00088       throw std::invalid_argument("link is not empty");
00089 
00090     if (not link.is_empty())
00091       throw std::invalid_argument ("link is not empty");
00092 
00093     next = this; 
00094   }
00095 
00097   void reset() 
00098   {
00099 
00100     I(this not_eq NULL);
00101 
00102     next = this; 
00103   }
00104 
00106   bool is_empty() const 
00107   {
00108 
00109     I(this not_eq NULL);
00110 
00111     return next == this; 
00112   }
00113 
00115   Slink * get_next() const 
00116   {
00117 
00118     I(this not_eq NULL);
00119 
00120     return next; 
00121   }
00122 
00130   void insert_next(Slink * p)
00131   {
00132 
00133     I(this not_eq NULL);
00134     I(p not_eq NULL);
00135     I(p->is_empty());
00136 
00137     p->next = next;
00138     next = p;
00139   }
00148   Slink * remove_next()
00149   {
00150 
00151     I(this not_eq NULL);
00152 
00153     Slink * ret_val = next;
00154     next = ret_val->next;
00155     ret_val->reset();
00156 
00157     return ret_val;
00158   }  
00159 };
00160 
00198 # define SLINK_TO_TYPE(type_name, link_name) \
00199 static type_name * slink_to_type(Slink * link) \
00200 { \
00201   type_name * ptr_zero = 0; \
00202   size_t offset_link   = reinterpret_cast<size_t>(&(ptr_zero->link_name)); \
00203   char * address_type  = reinterpret_cast<char*>(link) - offset_link; \
00204   return reinterpret_cast<type_name *>(address_type); \
00205 } 
00206 
00207 } // end namespace Aleph
00208 # endif /* SLINK_H */
00209 

Leandro R. León