I did for most kinds of objects *WithFinalize and *WithoutFinalize. *WithoutFinalize holds a copy of a C library handle, which should not be finalized when the D struct holding it is destroyed. I wrote even an article on this my “great” idea.
But now I’ve realized that it is probably over-engineering:
I @disable’d copy constructor for *WithFinalize objects to avoid unintended C library calls.
Now containers like RedBlackTree with my objects don’t work because of @disabled this(…) 😦
Now I think it would be better just to wrap every C handle into a D class to be reference counted.
It would in practice be probably even faster, because otherwise I would need to enable the constructor and this would get rid of protection of unintended calling C library functions that copy.
A case when a “great” idea became a hassle when putting into practice.
For now, having too much to rewrite, I return to Python. Goodbye and sorry me with grace, D 🙂
This design mistake has a positive side: I can return to my Python version of XML Boiler, which unlike D version already works.
I should rewrite my D bindings for librdf later without this overengineering and go back to my loved D.
I misused low-level features of D, but D is nevertheless the world’s best programming language.