// 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. |