
From: Stjepan Rajko
I am inclined to think that the implementation you have now (minus the asserts and the nomenclature) covers all of the uses fairly well. Existence of in-between use cases (conditionally monitored values, e.g., log whenever the temperature is over 35 degrees Celsius) leads me to believe that neither of {monitored value, conditional value} should be implemented in terms of the other. I think they should be implemented under a common abstraction, and I think your implementation implements that abstraction (again, minus the asserts and the nomenclature).
I think the current implementation is not the most suitable one for monitored values. The asignment operator is: if( constraint()(v) ) _value() = v; else error_handler()(_value(), v, _constraint()); So calling the monitor (error_handler) excludes assignment of the value, unless the monitor performs the assignment by itself. This is a bit clumsy -- e.g., having the case with logging the temperature if it exceeds a treshold, monitor would not only have to log, but also to assign the value. I see implementation of monitored values' assignment a bit different: if( _monitor(_value, new_value) ) // monitor decides whether the value should be assigned _value = new_value; // but does not perform the assignment by itself Then, conditionally-monitored values extend this by defining the following monitor callback: if( _condition(new_value) ) // no need to invoke the monitor return true; else // invoke the monitor return _monitor(old_value, new_value, _condition); And finally, constrained value would be a conditionally-monitored value, where the condition is the constraint and the inner monitor callback is the error policy.
For now, I would be plenty happy if you just took out the asserts, or made them optional (with defaulting to asserts, if you wish). That way I can at least start experimenting with your library in a monitored_value context, and let you know how it goes (I have use cases for this).
By saying about making the invariant asserts optional you mean something like wrapping them in a conditional compilation macro (like BOOST_CONSTRAINED_VALUE_NO_INVARIANT_ASSERTS) to be able to turn them off globally? I still can't convince myself to the idea of separating invariant from the test. IMO guarantee of the invariant is a strong point of the library. Giving up the guarantee not only may make the library more complicated for the users, but it may also lower the value of the library as a debugging device (since there will be less checks for coherence of the given set of policies, more opportunities to make a bug). Best regards, Robert