
On Thu, Oct 28, 2010 at 5:43 AM, David Abrahams <dave@boostpro.com> wrote:
Dude, are you kidding me?! That is too amazing.
I'm glad other people are excited about it!
Couple of questions:
* What does an explicit concept map look like? You didn't show an example.
I haven't decided on what it will look like just yet, only the fundamental mechanism that will be used under the hood. I'll post the way to specify concept maps when I get there. One thing I'm pretty sure about is that I could make it possible to create default implementations for concept maps which you'd explicitly pull in when their definition is applicable to your type. The default maps would forward associated types from, I.E. iterator traits and directly use all operations directly. Such default maps would likely be specified via a macro interface similar to BOOST_AUTO_FUNCTION. Think something along the lines of a parameter to the macro with a keyword ID of "typename" such as (typename iterator_traits< T >::value_type value_type). The neat thing about this is that since default implementations are specified with such a macro, I can also convert the associated types and expression requirements to something that can trigger SFINAE, meaning that the macro can not only generate a default mapping, but can automatically generate a metafunction that determines if a given type meets all of the requirements that are specified. As for full-on concept maps that specify all of the complicated glue code, they will likely look not too dissimilar from simple traits classes.
* Can you do concept map templates (e.g. all vector<T>s model Container)?
Yes, I believe that should be possible and I'd also consider it a necessity for such a library. However, it may end up being tricky when something has concept maps specified for all vector<T> as well as only vector<bool>, but I haven't gotten to that road just yet. There's likely a creative solution to that problem.
Not (break if not is_forward_iterator<...>) ? ^^
The reason it's "break not" as opposed to "break if not" is because of the problem I talked about earlier -- I can do multiword parameters as long as there isn't a conflict. "break if not" would conflict with "break if". Without getting too into the implementation details, it's because the first word is concatenated with an implementation detail identifier to form a macro which is invoked, then, if it's recognized as the first word of a multi-word id it does it again, etc. The problem is, once it encounters the "if", it can't safely try a further concatenation because if "not" isn't there, there may be a token from an if condition such as a condition starting with "(" or "!" which would cause an error during preprocessor concatenation, despite the fact that the condition looks as though it should be seemingly acceptable. As a side note, I may be able to get around this limitation of conflicts in multiword IDs if I require all parameters that appear after the IDs be surrounded by parentheses, since safely checking ahead for if text is parenthesized is "possible," though hacky, but I don't want to complicate use too much just for this. Another thing to consider is that when your argument is a value, "break if not" should technically work already since "not" will be treated by your compiler there as its actual meaning. You, of course, can't rely on this with arguments that are types. Anyway, while I can't do "break if not" because it conflicts with "break if", I can do "break not if" (and similarly "if" and "not if" as opposed to "if" and "not", etc.) since there would be no conflict. In fact, I recently started doing that very thing before I dropped the final "if" to simplify implementation of the macro and because it was shorter to write out without losing functionality. But now I'm breaking my own rule by talking about the parameter ID names. -- -Matt Calabrese