Note that the safe<T> is really safe
. there are several policies of each kind to choose from. One of the exception policies is ignore - but I don't think it currently actually works.
Yes, I know. The second part of my response was more about the fact that you actually have some policies, rather than their exact names. My point was that one of them (or a combination of them) do not incurs any overhead.
What I actually expect is:
a) some wierd bug can't be found. b) in desperation some intern just replaces all the ints with safe<T> c) problem is discovered - the safe... stuff is backed out and everyone (who is old enough) has a beer to congratulate themselves on how smart they are and the product is shipped. d) In some cases, someone might unintentionally leave the safe stuff in - since shipping is already way overdue.
I can't help it but I find your view very depressing ! Why not allow one to remove all the runtime checks ? This would let people use your code with the guarantee that it is always possible to remove the overhead, if needs be. Designing a library as a tool that you remove to ship your real product does not really help. I shamelessly quote myself:
IMHO, it makes no sense to design your library to allow users *not* using it.
e) Or maybe some crusty old geezer who is tired of fixing this stuff after doing 50 times will game the system by doing:
i) change all the int... to my_safe<int> ii) insert
template<typename T> using my_safe<T> = safe<T>;
then in one place in the program he can switch settings for all his integer types - without using macros.
That's exactly what I did, one typedef to rule them all. The ifdef DEBUG was only there to demonstrate a possible usage where checks are only enabled in debug builds.
It's also possible I could use policies to optionally include initialization checking - which I see as relatively expensive.
If you're saying that you might check if a value as been initialized before being used in a policy, then I would argue against it, and that was my whole point. I think that a safe builtin emulator should always be initialized, or *explicitly* left uninitialized[1]. That should have been the correct default for C++. I'm not sure how you will receive this, but as far as I remember, in D, all numeric types are initialized to 0 (or the value given to the constructor), but you can always remove that runtime cost by being explicit about it. If I remember correctly, the syntax is something like this: int i = void; But, with your library, it could be: boost::safe<int> i = boost::uninitialized; // or boost::none, or boost::whatever Which should raise an eyebrow in a code review, and has the advantage of being damn clear. Cheers, [1] This is the only point I am trying to make