tpl_binNode.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 TPL_BINNODE_H
00045 # define TPL_BINNODE_H
00046  
00047 # include <ahDefs.H>
00048 # include <ahAssert.H>
00049 
00050 namespace Aleph {
00051 
00052 struct Empty_Node 
00053 {
00054   Empty_Node() { /* empty */ }
00055 
00056   Empty_Node(SentinelCtor) { /* empty */ }
00057 
00058   void reset() { /* empty */ }
00059 
00060   Empty_Node & get_data() 
00061   { 
00062     throw std::domain_error("Empty_Node has not data"); 
00063   }
00064 };
00065 
00066 # define INIT_CLASS_BINNODE(Name, height, Control_Data)       \
00067     template <typename Key>                                   \
00068 class Name : public Control_Data                              \
00069 {                                                             \
00070 public:                                                       \
00071                                                               \
00072   static const size_t MaxHeight = height;                     \
00073   static Name * const NullPtr;                                \
00074                                                               \
00075   typedef Key key_type;                                       \
00076                                                               \
00077 private:                                                      \
00078                                                               \
00079   Key    key;                                                 \
00080   Name * lLink;                                               \
00081   Name * rLink;                                               \
00082                                                               \
00083 public:                                                       \
00084                                                               \
00085   Key & get_key() { return key; }                             \
00086                                                               \
00087   const Key & get_key() const { return key; }                 \
00088                                                               \
00089   Name *& getL() { return lLink; }                            \
00090                                                               \
00091   Name *& getR() { return rLink; }                            \
00092                                                               \
00093   Name(const Key& k) : key(k), lLink(NullPtr), rLink(NullPtr) \
00094   {                                                           \
00095     /* Empty */                                               \
00096   }                                                           \
00097                                                               \
00098   Name(const Control_Data & control_data, const Key & k) :    \
00099     Control_Data(control_data),                               \
00100     key(k), lLink(NullPtr), rLink(NullPtr)                    \
00101   {                                                           \
00102     /* Empty */                                               \
00103   }                                                           \
00104                                                               \
00105   Name(const Name & node) :                                   \
00106     Control_Data(node),                                       \
00107     key(node.key), lLink(NullPtr), rLink(NullPtr)             \
00108   {                                                           \
00109     /* Empty */                                               \
00110   }                                                           \
00111                                                               \
00112   Name(const Control_Data & control_data) :                   \
00113     Control_Data(control_data),                               \
00114     lLink(NullPtr), rLink(NullPtr)                            \
00115   {                                                           \
00116     /* Empty */                                               \
00117   }                                                           \
00118                                                               \
00119   Name() : lLink(NullPtr), rLink(NullPtr)                     \
00120   {                                                           \
00121     /* Empty */                                               \
00122   }                                                           \
00123                                                               \
00124   void reset()                                                \
00125   {                                                           \
00126     Control_Data::reset();                                    \
00127     rLink = lLink = NullPtr;                                  \
00128   }                                                           \
00129                                                               \
00130   static Name * key_to_node(Key & __key)                      \
00131   {                                                           \
00132     Name * node_zero = 0;                                     \
00133     size_t offset = (size_t) &(node_zero->key);               \
00134     char * addr = &__key;                                     \
00135                                                               \
00136     return (Name*) (addr - offset);                           \
00137   }
00138 
00168 # define DECLARE_BINNODE(Name, height, Control_Data)              \
00169 INIT_CLASS_BINNODE(Name, height, Control_Data)                    \
00170 };                                                                \
00171                                                                   \
00172 template <typename Key> Name<Key> * const Name<Key>::NullPtr = NULL; \
00173                                                                   \
00174 INIT_CLASS_BINNODE(Name##Vtl, height, Control_Data)               \
00175 virtual ~Name##Vtl() { /* empty */ }                              \
00176 };                                                                \
00177                                                                   \
00178 template <typename Key> Name##Vtl<Key> * const Name##Vtl<Key>::NullPtr = NULL
00179 
00213 # define DECLARE_BINNODE_SENTINEL(Name, height, Control_Data)    \
00214 INIT_CLASS_BINNODE(Name, height, Control_Data)                   \
00215   Name(SentinelCtor) :                                           \
00216     Control_Data(sentinelCtor), lLink(NullPtr), rLink(NullPtr) {}\
00217   static Name sentinel_node;                                     \
00218 };                                                               \
00219                                                                  \
00220 template <typename Key>                                          \
00221 Name<Key> Name<Key>::sentinel_node(sentinelCtor);                \
00222                                                                  \
00223 template <typename Key>                                          \
00224 Name<Key> * const Name<Key>::NullPtr = &Name<Key>::sentinel_node;\
00225                                                                  \
00226 INIT_CLASS_BINNODE(Name##Vtl, height, Control_Data)              \
00227 virtual ~Name##Vtl() { /* empty */ }                             \
00228 private:                                                         \
00229   Name##Vtl(SentinelCtor) :                                      \
00230     Control_Data(sentinelCtor), lLink(NullPtr), rLink(NullPtr) {}\
00231   static Name##Vtl sentinel_node;                                \
00232 };                                                               \
00233                                                                  \
00234 template <typename Key>                                          \
00235 Name##Vtl<Key> Name##Vtl<Key>::sentinel_node(sentinelCtor);      \
00236                                                                  \
00237 template <typename Key>                                          \
00238 Name##Vtl<Key> * const Name##Vtl<Key>::NullPtr =                 \
00239   &Name##Vtl<Key>::sentinel_node
00240 
00243 # define LLINK(p) ((p)->getL())
00244 
00247 # define RLINK(p) ((p)->getR())
00248 
00251 # define KEY(p)   ((p)->get_key()) 
00252 
00253 DECLARE_BINNODE(BinNode, 1024, Empty_Node);
00283 } // end namespace Aleph
00284 
00285 # endif
00286 

Leandro R. León