
Hi,
From: Rob Stewart
Once you go with a function local static, you have to worry about thread safety.
Even though the local statics are constant? Then the only problem would be initialisation, but doesn't compiler take a proper care of this in multi-threaded implementation?
No.
:-/ (the world is so cruel :P)
Thus, don't force the creation of statics in your design. Ensure that if they are used, it is the choice of the policy writer.
Well, it's not forced - one may easily supply his own bounds specifying policy that pass bounds by value.
I don't understand. So long as the comparison against the boundaries is a comparison against a constant, then the code will be efficient and there's no need for statics.
In case of integrals - yes, and that's how it's done. I was talking about the UDTs case - then no, because every time these constants have to be constructed first, then used in comparison. By using statics I avoid constructing them every time a comparison is done.
static const value_type & min_value() { static const value_type v = MinValueGenerator()(); return v; }
Is there really something that wrong with this design? Is there any danger
I see what you're doing. Why not:
void validate(value_type & value_io);
That function can do the validation any way it sees fit and enables the discontinuous ranges you spoke of previously.
This is exactly the way constrained policies' assign function works (it takes the value and decides whether it's correct), but we're one layer below :) And here, unfortunately, there are more tests that have to be done, not only !(value < min_value || max_value < value): in increment: value < max_value in decrement: min_value < value in wrapping and clipping policies' assign: value < min_value and in other place max_value < value And I'm afraid it doesn't depend on the design, it's just maths.
the value is constructed only once, and every next time min_value() takes only one comparison (static initialisation check) and returning a reference. In return-by-value case every call results
Don't forget that using the function local static, aside form the MT problem, has overhead. The implementation does, in effect
example() { int (in-platform-specific-location) result; if (!compiler-specific-flag) { result = initial-value; compiler-specific-flag = true; } }
when you write this:
example() { static int result(initial-value); }
I didn't forget about it, this is what I meant by saying "comparison (static initialisation check)"
Well, this wouldn't be constrained<int> but constrained< bounded_policies::error< bounds_specifiers::static_bounds<int, 0, 10> > >
That's nasty. Do you need things separated like that? It would be easier to use (though maybe less flexible in some important way) with this:
constrained<bounded<int, 0, 10> >
This is the reason why shortcut aliases are also provided for the most common cases, so you can write: bounded_int<int, 0, 10>::type to get exactly the same effect. It's just like with string that stays for basic_string< char, char_traits<char>, allocator<char> > and it's very flexible yet very simple in the most common cases. Best regards, Robert