|
Boost : |
From: scleary_at_[hidden]
Date: 2000-06-30 15:51:25
> One idea was to have a specialization of the compressed_pair's
> implementation class that is just plain missing the empty class object
> (instead of inheriting from it). The problem with this is that if the
> empty class does something in its constructor/destructor, then that
> something will not happen as it should.
Well, I haven't tried it, but you could try something totally crazy, like
faking a "this" pointer:
// (this code assumes that the empty type is the first() element of
// the compressed_pair, but that shouldn't be too hard to change)
template <typename empty_type, typename non_empty_type>
class gcc_compressed_pair
{
private:
non_empty_type m;
empty_type * fake_this()
{ return reinterpret_cast<empty_type *>(this); }
const empty_type * fake_this() const
{ return reinterpret_cast<const empty_type *>(this); }
public:
gcc_compressed_pair()
{
// Explicitly call default constructor
new (fake_this()) empty_type();
}
explicit gcc_compressed_pair(const non_empty_type & nm)
:m(nm)
{
// Explicitly call default constructor
new (fake_this()) empty_type();
}
explicit gcc_compressed_pair(const empty_type & n)
{
// Explicitly call copy constructor
new (fake_this()) empty_type(n);
}
gcc_compressed_pair(const empty_type & n,
const non_empty_type & nm)
:m(nm)
{
// Explicitly call copy constructor
new (fake_this()) empty_type(n);
}
gcc_compressed_pair(const gcc_compressed_pair & other)
:m(other.m)
{
// Explicitly call copy constructor
new (fake_this()) empty_type(other.first());
}
gcc_compressed_pair & operator=(
const gcc_compressed_pair & other)
{
m = other.m;
// Explicitly call assignment operator
first() = other.first();
}
~gcc_compressed_pair()
{
// Explicitly call destructor
fake_this()->~empty_type();
}
empty_type & first() { return *fake_this(); }
const empty_type & first() const { return *fake_this(); }
non_empty_type & second() { return m; }
const non_empty_type & second() const { return m; }
};
There are two Standard problems with the above solution AFAIK:
1) The binding of the reference for first() is illegal [8.3.2/4] [8.5.3/1]
because a reference *must* refer to a "valid object" (presumably one of the
referred-to type).
2) The reinterpret_cast in fake_this() has unspecified behaviour
[5.2.10/7].
However, I don't think these would cause a problem on most compilers; this
code *is* going to be specific to certain compilers, so maybe you can take a
few liberties.
Just a thought. :)
-Steve
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk