Source: Slot.hh


Annotated List
Files
Globals
Hierarchy
Index
// 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.