xxxxxxxxxx
void main()
{
Turducken!(immutable(int)) td;
td.bind(123);
(ref immutable(int) value) {
assert(value == 123);
td.bind(456);
assert(value == 123); // kaboom
}(td.value);
}
struct Turducken(T)
{
// The delicious center.
alias Chicken = T;
// Union ensures that the T destructor is not called.
union Duck
{
Chicken chicken; // chicken chicken? chicken!
}
// Struct ensures that moveEmplace and its magic
// constness "tolerant" (violating) memcpy can be used.
struct Turkey
{
Duck duck;
}
Turkey store = Turkey.init; // take you to the turkey store
bool set = false;
// Stick a straw in it to get at the delicious gooey center.
ref T value() in(set) { return store.duck.chicken; }
// And the special sauce:
void bind(T value)
{
import core.lifetime: moveEmplace;
// clean up in case we're back for seconds
unbind;
// Make a destructor-protected copy to stick in our store
Turkey wrapper = Turkey(Duck(value));
// Plow over the existing data in total disregard of constness
() moveEmplace(wrapper, store); }(); {
set = true;
}
// Various condiments:
void unbind()
{
if (set)
{
static if (is(T == struct)) {
destroy(value);
}
set = false;
}
}
// Since we have shielded our value from D's watchful eyes,
// we have to remember to clean up manually
// Clean your dishes!
~this()
{
unbind;
}
}