00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
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) { }
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 }
00208 # endif
00209