[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Token types with constructor
From: |
Hans Aberg |
Subject: |
Re: Token types with constructor |
Date: |
Tue, 14 Sep 2004 19:08:53 +0200 |
At 12:01 +0200 2004/09/14, Akim Demaille wrote:
> > One can use static_cast instead
>
>Of course.
Noting the problem that the refcounted root class in a polymorphic
hierarchy should normally be virtual, in which case static_cast does not
work. So one has to drop the base class virtuality, and keep in mind to not
duplicate it in a multiple inheritance (not a big problem).
I made a ref<A> class where static_cast & dynamic_cast can be used side by
side (see below). I found that one can handle the 0 pointer problem by
letting ref<A>::operator->() hand over a pointer to a A() object, i.e., if
one want 0 to be given special semantics. I will simplify the writing of a
hierarchy even further.
Rather than supplying a refcount, it assumes that the classes already have
it. One can then use it as follows:
class object_root {...}; // Supplies a refcount.
// If one want to use static_cast, then "virtual" must be dropped.
class A : public virtual object_root {...};
Then use
class semantic_type {
public:
ref<object_root> object_;
...
};
In the typing of grammar variables, one would use ref<A>. This way one gets
an easy, refcounted, static typing which Bison might help keeping track of.
So your concerns of a single polymorphic hierarchy goes away. In fact, the
parser taken away, I found it very hard to program with a single, untyped
polymorphic hierarchy. That is why I started with writing some ref<A>
classes by hand, without using templates.
So it looks as though one can set it up really nice.
template<class A>
class ref {
protected:
A* data_;
static A null_;
public:
typedef ref<A> This;
ref() : data_(0) {}
~ref() { shed(); }
ref(const ref& x) : data_(x.copy()) {}
ref& operator=(const ref& x) {
if (data_ != x.data_) { shed(); data_ = x.copy(); }
return *this;
}
ref(A* rp) : data_(rp) {}
A* copy() const {
#if 0
return (data_ == 0)? 0 : data_->copy();
#else
if (data_ == 0) return 0;
data_->increase_count();
return const_cast<A*>(data_);
#endif
}
void shed() { if (data_ != 0) data_->shed(); }
ref<A> clone() const {
if (data_ == 0) return 0;
return new A(*data_);
}
// Operators that return pointer 0 when applicable:
A* data() { return data_; }
const A* data() const { return data_; }
#if 0 // Causes conflicts with operator&() in class maybe<>.
A* operator&() { return data_; }
const A* operator&() const { return data_; }
#endif
// Operators that return reference to an object A() when applicable:
A* operator->() { return (data_ == 0)? &null_ : data_; }
const A* operator->() const { return (data_ == 0)? &null_ : data_; }
A& operator*() { return (data_ == 0)? null_ : *data_; }
const A& operator*() const { return (data_ == 0)? null_ : *data_; }
#if 1
template<class B>
explicit ref(B* op) : data_(dynamic_cast<A*>(op)) {}
#else
template<class B>
explicit ref(B* op, bool dynamic = true)
: data_(dynamic? dynamic_cast<A*>(op) : static_cast<A*>(op)) {}
#endif
template<class B>
explicit ref(const B& op) : data_(dynamic_cast<A*>(op.copy())) {}
#if 0
template<class T>
struct cast {
T item;
cast(ref& x) : item(dynamic_cast<T>(x.data())) {}
operator T() { return item; }
};
#endif
};
Hans Aberg
- Re: Token types with constructor, (continued)
Re: Token types with constructor, Martin Trautmann, 2004/09/09
Re: Token types with constructor, Hans Aberg, 2004/09/13