|
|
// Slot - Coldstore smartpointers // Copyright (C) 1998,1999 Colin McCormack, // see LICENSE (MD5 f5220f8f599e5e926f37cf32efe3ab68) for terms // $Id: Slot_hh.html,v 1.1.1.1 2000/04/09 01:07:51 skeptopotamus Exp $ #ifndef SLOT_HH #define SLOT_HH #include <iostream.h> #include <string.h> #include <assert.h> class Data; // that to which a Slot maps class UString; class List; class NList; class Tuple; class String; class Range; //class Hash; class Dict; class DictIt; class Builtin; class Symbol; class Namespace; class Error; class Integer; class BigInt; class Real; // [16.21] How do I provide reference counting with copy-on-write // semantics for a hierarchy of classes? // Slot::Data is now the root of a hierarchy of classes, // which probably cause it to have some virtual functions. // Note that class Slot itself will still not have any virtual functions. // The Virtual Constructor Idiom is used to make copies of the Slot::Data objects. // To select which derived class to create, the sample code below uses // the Named Constructor Idiom, but other techniques are possible // (a switch statement in the constructor, etc). // Methods in the derived classes are unaware of the reference counting. /** Slot class - a smart pointer to Data which provides for copy-on-write of the Data it manages Additionally, Slot makes use of pointer alignment to encode additional forms into a pointer: encoded Integers (31 bit integer values) and one additional form which will be used for `immediate' values such as Promise and Future. Note: can't make arrays of Slot - no default constructor */ union Slot { private: /** friend method to permit printing of Slot */ friend ostream& operator<< (ostream&, const Slot &); /** Slot representation of Data* Invariant: data_ is never NULL when being operated on */ mutable Data *data_; /** Slot representation of encoded Integer */ long integer_; protected: /** initialize Slot to NULL */ void init() { data_ = (Data*)0; } /** convert an encoded integer into an instance of Integer */ Data *mkInteger() const; public: /** predicate: is Slot an encoded Integer? */ inline bool isEncInt() const { return (integer_&1) == 1; } //////////////////////////////////// // Slot construction /** default constructor - construct NULL Slot */ Slot(Data *d = NULL); /** construct from const Data* */ Slot(const Data *d); /** Integer constructor - construct Slot from integer */ Slot(int l); /** reference constructor - construct Slot from Data */ Slot(Data &d); /** reference constructor */ //Slot(const Data &d); /** construct Slot from a string @param str string to assign to this */ Slot(const char *str); /** copy constructor - dups reference @param f const Slot& to which to assign this */ Slot(const Slot& f); /** copy constructor - dups reference @param s Slot& to which to assign this */ Slot(Slot &s); /** assignment operator. Initializes Slot @param f Slot& to which to assign this */ Slot& operator= (const Slot& f); /** assignment operator. Initializes Slot @param d Data* to which to assign this */ Slot& operator= (Data *d); /** assignment operator. Initializes Slot @param i integer to which to assign this */ Slot& operator= (int i); ~Slot(); //////////////////////////////////// // Dereferencing Slot /** dereference smartpointer */ Data *operator->() const; /** dereference smartpointer */ operator Data*() const; /** dereference smartpointer */ operator Data&() const; /** dereference smartpointer as sequence */ Slot operator [](int index) const; /** dereference smartpointer accessing underlying sequence */ Slot operator [] (const Slot &) const; //////////////////////////////////// // Typed Dereference - checks rtti type and throws if non-conformant type /** dereference smartpointer as String* */ operator String *() const; /** dereference smartpointer as UString* */ operator UString *() const; /** dereference smartpointer as List* */ operator List *() const; /** dereference smartpointer as List* */ operator NList *() const; /** dereference smartpointer as Tuple* */ operator Tuple *() const; /** dereference smartpointer as Dict* */ operator Dict *() const; /** dereference smartpointer as DictIt* */ operator DictIt *() const; /** dereference smartpointer as Symbol* */ operator Symbol *() const; /** dereference smartpointer as Namespace* */ operator Namespace *() const; /** dereference smartpointer as Error* */ operator Error *() const; /** dereference smartpointer as Builtin* */ operator Builtin *() const; /** dereference smartpointer as Integer* */ operator Integer *() const; /** dereference smartpointer as BigInt* */ operator BigInt *() const; /** dereference smartpointer as Real* */ operator Real *() const; /** dereference smartpointer as int */ operator int() const; operator long() const; /** dereference smartpointer as char* */ operator char*() const; /** return the type pointed to */ const char *typeId() const; /** non-NULL predicate: convert Slot to a bool */ inline operator bool () const { return data_ != (Data*)0; } /** Data ordering over Slot */ int order(const Slot& d) const; /** possible reduction in strength for == */ bool equal(const Slot &d) const; //////////////////////////////////// // type predicates bool isNumeric() const; bool isList() const; bool isString() const; //////////////////////////////////// // comparisons are defined on Data virtuals `order' and `equal' inline bool operator==(const Slot &d) const { return (this == &d) || (integer_ == d.integer_) || equal(d); } inline bool operator!=(const Slot &d) const { return (this != &d) && (integer_ != d.integer_) && !equal(d); } inline bool operator>=(const Slot &d) const { return (this == &d) || (integer_ == d.integer_) || (order(d) >= 0); } inline bool operator>(const Slot &d) const { return (this != &d) && (integer_ != d.integer_) && (order(d) > 0); } inline bool operator<=(const Slot &d) const { return (this == &d) || (integer_ == d.integer_) || (this != &d) && (order(d) <= 0); } inline bool operator< (const Slot &d) const { return (this != &d) && (integer_ != d.integer_) && (order(d) < 0); } //////////////////////////////////// // Vector support (for List) /** consistency check on underlying Data array */ static void check(const Slot *from, size_t len = 1); /** compare two Slots * used by @see Vector::qsort and @see Vector::bsearch */ static int cmp(const Slot *l, const Slot *r) { return l->order(*r); } /** find offset of leftmost NULL element in range */ static int findNull(const Slot *from); /** move a range of Slots without touching them */ static Slot *move(Slot *to, const Slot *from, size_t range) { return (Slot *)memmove(to, from, range * sizeof(Slot)); } /** duplicate a range of Slots perform necessary reference counting */ static Slot *dup(Slot *to, const Slot *from, size_t range); /** destroy the elements of the Slot range */ static void destroy(Slot *from, size_t range) { for (size_t i = 0; i < range; i++) { from[i] = (Data*)0; } } /** initialise default elements in Slot range */ static void init(Slot *from, size_t range) { memset(from, 0, sizeof(Slot) * range); } /** fill a segment of slots with a slot */ static void segFill(Slot *from, const Slot &, int); /** find a single matching T */ static Slot *find(Slot *from, const Slot &_c, size_t range); /** find needle in haystack O(n^2) */ static Slot *search(Slot *from, const Slot *needle, size_t len, size_t range); /** Data ordering over Slot */ static int order(const Slot& d1, const Slot& d2); /** dump this Slot to a stream */ ostream &Dump(ostream& out) const; }; //ostream& operator<< (ostream& out, const Slot & slot); #if 0 // a child of Slot which enforces the type of its referent template <class T> class tSlot : public Slot { public: tSlot(const T *d = NULL) // default constructor to permit arrays to be made : Slot((Data*)T) { assert(T::type == vtbl()); } tSlot(const T &d) // reference constructor : Slot((Data&)d) { assert(T::type == vtbl()); } tSlot(const tSlot<T>& f) // copy constructor - dups reference : Slot((Slot&)f) { assert(T::type == vtbl()); } // dereference smartpointer inline operator T*() const { T* tmp = (T*)(Slot::operator Data*()); assert(T::type == tmp->vtbl()); return tmp; } inline operator T&() const { T& tmp = (T&)(Slot::operator Data&()); assert(T::type == tmp.vtbl()); return tmp; } // dereference smartpointer - returns const inline const T *operator->() const { T *tmp = (T*)(Slot::operator->()); assert(T::type == tmp.vtbl()); return tmp; } }; #endif #endif
Generated by: colin@sharedtech.dhis.org on Sat Nov 6 11:59:24 199. |