Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

nci/suif/suif2b/extratypes/tos/referenced_item.h

Go to the documentation of this file.
00001 /* file "referenced_item.h" */
00002 
00003 
00004 /*
00005        Copyright (c) 1996, 1997 Stanford University
00006 
00007        All rights reserved.
00008 
00009        This software is provided under the terms described in
00010        the "suif_copyright.h" include file.
00011 */
00012 
00013 #include <common/suif_copyright.h>
00014 
00015 #ifndef STY_REFERENCED_ITEM_H
00016 #define STY_REFERENCED_ITEM_H
00017 
00018 #include "suifkernel/suifkernel_forwarders.h"
00019 
00020 /*
00021       This is the definition of the referenced_item class, which is
00022       for internal use by sty, the first-level main library of the
00023       SUIF system.
00024 */
00025 
00026 
00027 /*
00028       The idea of this class is that for various interfaces in sty, we
00029       want to pass back to the user a reference to something internal
00030       (reference not meaning necessarily a C++ reference, but the more
00031       general sense of the word reference).  Essentially, a pointer is
00032       being returned that the user can then later pass to other
00033       methods of the interface.  But some implementations of a
00034       particular interface may pass pointers to structures they keep
00035       anyway, while other implementations may build the internal
00036       structures on-the-fly when a reference to them is requested by
00037       the user.  An example of this is a handle for an element in a
00038       tos, which in a linked-list implementation is a pointer to an
00039       item in the list while in an array implementation it's an
00040       auxiliary structure that is only constructed when such a handle
00041       is requested by the user.  We want to be able to delete the
00042       specially constructed structure when the user is done with the
00043       reference to it.  We handle this by passing a special handle
00044       class to the user where the handle contains only one field, the
00045       pointer.  The only differences between the pointer itself and
00046       the handle are that the handle will tell the pointer when the
00047       handle is copied or de-allocated and if necessary deallocate it
00048       when the last reference is de-allocated.  We implement this by
00049       having all such internal structures inherit from this pure
00050       virtual class, referenced_item.
00051 
00052       Having a class wrapped around the pointer given to a user also
00053       gives the added benefit of making it somewhat harder to
00054       circumvent the separation of interface and implementation.
00055       Since pointer casts happen all over the place and are entirely
00056       necessary in C++ to move up the class heirarchy, it's tempting
00057       to simply cast a pointer a user is given to get access to the
00058       internals of what the user knows it points to.  The wrapper
00059       class makes it hard enough to discourage such usage.
00060 
00061       Note that it's important to have a single class for all things
00062       that the user is going to get a handle to so that
00063       behind-the-scenes one class can use the handle it gets from a
00064       component class to give to the user as a totally different kind
00065       of handle.  The handle classes should have different types for
00066       better type checking.  That means that some classes will
00067       actually have to be made dependent on the internals of the
00068       handle for another class (though only to the extent of knowing
00069       that the handle is just a wrapper for a referenced_item
00070       pointer).  This is a small reduction in modularity, but it is
00071       necessary to get efficient implementations the way these
00072       interfaces are structured.
00073  */
00074 //#include "sty_basics.h"
00075 
00076 class referenced_item
00077   {
00078 private:
00079     //    virtual void virtual_function_table_hack(void);
00080 
00081 protected:
00082     referenced_item(void)  { }
00083 
00084 public:
00085     virtual ~referenced_item(void)  { }
00086 
00087     virtual void add_ref(void) = 0;
00088     virtual void remove_ref(void) = 0;
00089     virtual bool delete_me(void) = 0;
00090   };
00091 
00092 class ri_reference
00093   {
00094 private:
00095     //    virtual void virtual_function_table_hack(void);
00096 
00097 protected:
00098     referenced_item *_data;
00099 
00100     void old_ref(referenced_item *old_data)
00101       {
00102         if (old_data != 0)
00103           {
00104             old_data->remove_ref();
00105             if (old_data->delete_me())
00106                 delete old_data;
00107           }
00108       }
00109 
00110     ri_reference(const ri_reference &) : _data(0) {};
00111     ri_reference &operator=(const ri_reference &) { suif_assert(0); return *this; }
00112 
00113     ri_reference(void) : _data(0) {}
00114     ri_reference(referenced_item *init_data) : _data(init_data)
00115       {
00116         if (init_data != 0)
00117             init_data->add_ref();
00118       }
00119     virtual ~ri_reference(void)  { old_ref(_data); }
00120 
00121 public:
00122     /* no public constructors or destructors should exist here */
00123 
00124     bool is_null(void) const  { return _data == 0; }
00125 
00126     /* DANGER!  The following allows access to the raw referenced_item
00127      * pointer.  Avoid using this if at all possible.  If it is used,
00128      * the user is responsible for seeing that add_ref() and
00129      * remove_ref() are called when appropriate on the resulting
00130      * pointer. */
00131     referenced_item *raw_referenced_item(void) const  { return _data; }
00132     void set_raw_referenced_item(referenced_item *new_data)
00133       {
00134         if (new_data != 0)
00135             new_data->add_ref();
00136         old_ref(_data);
00137         _data = new_data;
00138       }
00139   };
00140 
00141 
00142 #endif /* STY_REFERENCED_ITEM_H */

Generated at Mon Jul 31 13:41:51 2000 for NCI SUIF by doxygen 1.1.2 written by Dimitri van Heesch, © 1997-2000