
On Sun, Sep 2, 2012 at 12:13 PM, Roland Bock <rbock@eudoxos.de> wrote:
* What is your evaluation of the implementation? I spent some time browsing through the macro code hoping it would help me to solve a problem of my own which looked similar (turned out it wasn't). What's the problem you are trying to solve? (Maybe post it in a separate email thread.) Will do, topic will be "Enum Conversion".
Never being a fan of too much macro code, I have to say that this is very nicely written!
My only concerns: - It seems to me that the implementation is spread over more files than necessary. It made following the call stack a bit tiresome. I refactored the files many times... what's there now makes sense to me, modularity is important given the amount of pp code this lib has. Do you have any specific suggestion on some files that should be merged together? No specific suggestions, I just tried to follow the "requires" through
- I a bit torn between a) Steven's comment who would like to see CONTRACT_OLDOF being replaced by the would-be keyword in a possible future standard b) boost macros being clearly visible as such, leaving translation to future standard keywords to the user of the library, e.g. #define foreach BOOST_FOREACH
I tend towards b). I just replied to Steven's. CONTRACT_OLDOF is a "special" macro so #define oldof CONTRACT_OLDOF won't work (because you can't guarantee proper expansion order that way) but I can provide a CONTRACT_CONFIG_DEFINE_OLDOF_KEYWORD that will #define oldof for you (even if oldof doesn't follow the Boost macro naming standard). Hmm. I wonder if precondition, postcondition, requires etc. might have
On 2012-09-02 19:49, Lorenzo Caminiti wrote: the code and found myself hopping from file to file for every other function. At least it felt that way. the potential to confuse users who are not aware of Boost.Contract? They look like language keywords, but are macros instead. That's why I said I am tending towards b) which would at least define the keyword locally, e.g.
#define precondition BOOST_CONTRACT_PRECONDITION
No, precondition, postcondition, requires, intialize, extends, etc are not macros, only CONTRACT_OLDOF is a macro. The others are indentifiers that have special meaning when used in specified places within the library macros. That's all. In a way these are similar to C++11 virtual specifiers (which are also not keywords) but for the library instead of the language. For example, you could do: #include <contract.hpp> CONTRACT_FUNCTION( void (precondition) ( int x ) precondition( x >= 0 ) ) { } int main ( void ) { precondition(0); return 0; } I advice not to use precondition, etc outside the uses that the lib does. However, if you have existing code with a function, variable, etc named precondition, my lib will leave that alone (as it should). That won't be the case instead if we did #define oldof ... in which case if you have existing code that uses oldof it will be messed up. That said, I can't use the same pp parsing mechanism I use for precondition, etc also for oldof because oldof is nested within the assignment expression (while precondition, etc appear at the beginning of their syntactic element). precondition is the first token so it can be parsed as a specifier: precondition( ... ) // ok odlof is not the first (or last) token (and all other tokens around are arbitrary plus they can contain non-alphanumeric symbols) so it can't be parsed by the pp: auto old_size = oldof size() // nope :( but I can use a macro to get around this: auto old_size = CONTRACT_OLDOF size() // ok
If that is not possible (as with oldof), I could still write:
CONTRACT_CONFIG_DEFINE_OLDOF_KEYWORD // defines oldof
Thanks, --Lorenzo