Boost.Generic, C++0x Concepts, and C++1y Concepts

Hey everyone, It's been a while since I've made an appearance on this list, but I was contacted regarding the recent discussion of concepts here and Lorenzo's taking the reins of a concept library, and decided to poke my head in. First, I apologize to the community for not getting Boost.Generic on the sandbox earlier (if you are unfamiliar with Boost.Generic, see my 2011 BoostCon talk http://blip.tv/boostcon/boost-generic-concepts-without-concepts-5262126 and/or the corresponding slides https://github.com/boostcon/2011_presentations/raw/master/thu/Boost.Generic.... ). I've gotten numerous emails about it since 2011 and I decided to commit the current state of Boost.Generic to the sandbox today. It is still based on the "old" concepts of C++0x with pseudo-signatures. You can find it in the "generic" subdirectory of the sandbox. That said, I'm not sure anyone even cares about Boost.Generic anymore given that the standard seems to be diverging from how it originally was approaching concepts, but here it is anyway. Similarly, I'm not sure there is any interest from people for me to continue developing Boost.Generic, so I guess this is a check for interest again. And, very briefly, without getting too political here (not that my opinion has any bearing) but I personally do not agree with some of the recent design changes for what may turn out to be C++1y concepts -- specifically I think pseudo-signatures were better overall and the C++0x form of associated types was much more useful than what is currently described, especially concerning associated type deduction, which no longer appears to be possible. But I don't think this discussion is suitable for the Boost mailing list and I don't want to ruffle too many feathers beyond that, so I'll take that elsewhere. For this reason, though, I [currently] do not have a desire to support that form of concepts in my library, though I do plan to resume work on Boost.Generic. A recap of what's gone on since my Boostcon talk, for anyone who even remembers it -- I haven't been actively developing Boost.Generic for over a year as I have been busy with other things, but coincidentally in the past couple of weeks I've gone back to it and decided to update some things due to a trick I realized I could use to get full compatibility with the C++0x working paper for explicit concept map templates (N2914's 14.10.3.2 paragraph 3 highlights why it's non-trivial, see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2914.pdf). Since then, I've had renewed interest in the project and have updated various facilities. Stuff that changed since my presentation back in 2011 -- it now supports variadic concepts using the syntax ,,, (see line 28 of boost/generic/std_concept/concepts/predicate.hpp for a simple example). All 135 of the concepts from N2914 are now implemented, though not all are working, especially ones that are not auto and use refinement (I'm still in the process of making the concept map backend changes). All of the std_concepts/concepts tests should be working, and same with std_concept/support_concepts tests, with GCC and Clang only failing on FreeStoreAllocatable (in slightly different ways). I'm updating some of the implementation to use the new Boost.Preprocessor variadic macro support that didn't exist when I started development, and Boost.Generic now also is starting to use Edward Diener's variadic_macro_data_library that's in the sandbox. I've only recently test on GCC 4.7 and Clang 3.1, both with libstdc++ on Windows. I don't think any other compilers will be able to handle it because of the amount of C++11 features currently in use... Visual C++ in particular will likely have no chance of compiling ANY of it, even if you use the fully preprocessed form of the library that I provided on the sandbox. Specifically, I currently require the updated C++11 SFINAE support, variadic templates, and template aliases, among other features which I don't believe Visual C++ yet supports. If you want to see how to use the library, for now you'll have to watch the talk, look at the slides, and/or go into generic/test/libs/generic/test/std_concept and examine the tests that are there (the latter will probably be the most enlightening in terms of using the predefined concepts). As for the tests, the ones you should look at if you want to understand how to use the predefined concepts are in the test directory's std_concept/concepts and std_concept/support_concepts subdirectories. If you want to see the syntax for creating your own concepts, the ones in std_concept/concepts are the best choice to look at, as they are simple and most do not require compiler intrinsics, unlike the support_concepts which rely on C++11 type_traits and the C++0x std::True concept. I also recently integrated Boost.Wave support to easily generate preprocessed versions of all of the concepts in the library. You can use the preprocessed headers, including Dave's suggested #line support, without having to run Boost.Wave yourself. To do this you just define a couple of macros when you build the tests. This decreases build times by over 50% on both Clang and GCC -- the tests for me in Clang go from over 7 minutes to just over 3 minutes if I use the preprocessed headers. To activate this support you need the two defines in the following format (easiest to just define them via the command-line) // NOTE: Do not use quotes around the path -- also realize that the path ends in the middle of the word generic, This is necessary. #define BOOST_GENERIC_PREPROCESSED_ROOT put_your_COMPLETE_path_to_boost_sandbox_here/generic/include/boost/gen // Also #define BOOST_GENERIC_USE_PREPROCESSED_HEADERS This will use completely preprocessed concepts, with errors properly pointing to the non-preprocessed headers, and effectively gets rid of all of the "from macro invocation" notes you'd see in clang and gcc 4.8 whenever you hit one of the Boost.Generic generated static_asserts in the non-preprocessed form. It is recommended that you use the preprocessed form unless you are making changes to the library-provided concepts, since compile-times are greatly reduced by using them and error messages are improved. Anyway, as I said, I do not personally like the direction that concepts seem to be going and so I do not currently have much of an interest in implementing what is currently proposed, however, buried somewhere in the source of Boost.Generic I believe is an early implementation of the library that was more similar to how concepts are specified in N3351, though I stopped maintaining it a long time ago -- it allowed for the specification of givens and arbitrary expression matching similar to the current design, with a brief demonstration given in my 2011 Boostcon talk (slide 20: https://github.com/boostcon/2011_presentations/raw/master/thu/Boost.Generic....). It might be useful to revive this now that standard concepts may be going in that direction, but again, I do not think this is a good idea and was why I was convinced by others to switch development to pseudo-signatures to begin with. -- -Matt Calabrese

On Thu, Sep 27, 2012 at 12:20 PM, Matt Calabrese <rivorus@gmail.com> wrote:
Hey everyone,
Hi Matt, good to see you back!
It's been a while since I've made an appearance on this list, but I was contacted regarding the recent discussion of concepts here and Lorenzo's taking the reins of a concept library, and decided to poke my head in. First, I apologize to the community for not getting Boost.Generic on the sandbox earlier (if you are unfamiliar with Boost.Generic, see my 2011 BoostCon talk http://blip.tv/boostcon/boost-generic-concepts-without-concepts-5262126 and/or the corresponding slides https://github.com/boostcon/2011_presentations/raw/master/thu/Boost.Generic.... ). I've gotten numerous emails about it since 2011 and I decided to commit the current state of Boost.Generic to the sandbox today. It is still based on the "old" concepts of C++0x with pseudo-signatures. You can find it in the "generic" subdirectory of the sandbox. That said, I'm not sure anyone even cares about Boost.Generic anymore given that the standard seems to be diverging from how it originally was approaching concepts, but here it is anyway.
I will definitely take a look at your code (I've been scouting to find it somewhere in the last few months but without success, I'm really glad you are putting it into the sandbox). Thanks, --Lorenzo

On Thu, Sep 27, 2012 at 3:32 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
I will definitely take a look at your code
As a warning, I hope by looking at my code you don't mean looking at it's implementation, heh. A lot of the preprocessor stuff is somewhat of an undocumented mess and I had to hand-roll many macros as it was developed before VMD existed and before Boost.Preprocessor were updated for variadics. A lot of the low-level backend preprocessor stuff is also very old and stems from a time before I understood how to make good use of the preprocessor. If I continue development, I'm probably going to rewrite a lot of the low-level stuff, hopefully even sharing some of your contract code, as I imagine there are a lot of similar ideas between the libraries. I'd also really like to experiment with getting rid of some of the parentheses, as you and I talked about last year. At this point, though, I'm not sure anyone is going to be interested in seeing Boost.Generic given that the new C++1y concepts are so different. -- -Matt Calabrese

On Thu, Sep 27, 2012 at 12:48 PM, Matt Calabrese <rivorus@gmail.com> wrote:
On Thu, Sep 27, 2012 at 3:32 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
I will definitely take a look at your code
As a warning, I hope by looking at my code you don't mean looking at it's implementation, heh.
Yes, I meant the impl also but don't worry, I understand it's a work-in-progress.
A lot of the preprocessor stuff is somewhat of an undocumented mess and I had to hand-roll many macros as it was developed before VMD existed and before Boost.Preprocessor were updated for variadics. A lot of the low-level backend preprocessor stuff is also very old and stems from a time before I understood how to make good use of the preprocessor.
I'd probably be more interested in the part of the impl that expands the macro code to implement concepts, not necessarily the pp stuff.
If I continue development, I'm probably going to rewrite a lot of the low-level stuff, hopefully even sharing some of your contract code, as I imagine there are a lot of similar ideas between the libraries. I'd also really like to experiment with getting rid of some of the parentheses, as you and I talked about last year.
It might help to start by taking a look at contract/detail/preprocessor/traits/. Also, this is a possible syntax I had in mind for C++0x concept definitions: http://contractpp.svn.sourceforge.net/viewvc/contractpp/releases/contractpp_...
At this point, though, I'm not sure anyone is going to be interested in seeing Boost.Generic given that the new C++1y concepts are so different.
I can't speak for this yet because I'm just now looking into C++1y concepts. Thanks. --Lorenzo

On Thu, Sep 27, 2012 at 4:00 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
I'd probably be more interested in the part of the impl that expands the macro code to implement concepts, not necessarily the pp stuff.
Refer to boost/generic/concept.hpp line 253 BOOST_GENERIC_CONCEPT_IMPL_VALID_ It's probably hard to decipher since, as you probably realize, pretty much everything needs to go into its own, separate metafunction and everything needs to be expanded inside of template specialization argument lists in order for SFINAE to take place, and all of the associated types of the concept need to be template arguments to every single one of those metafunctions for SFINAE to work with them as well. Also, on the macro side, in order to reduce compile times, I avoid making multiple passes over the top-level macro arguments and instead preprocess it all at once, putting code that will eventually go into different locations into different boost preprocessor sequence elements, and then I pull those out individually at the end. This succeeded at greatly reducing compile-times, but it makes the code harder to read.
It might help to start by taking a look at contract/detail/preprocessor/traits/. Also, this is a possible syntax I had in mind for C++0x concept definitions:
http://contractpp.svn.sourceforge.net/viewvc/contractpp/releases/contractpp_...
Looks great. I'll probably do most of that eventually, but I'd like to save those changes for later, since what is in currently works and I'd rather focus on new features first before I overhaul the interface. I can't speak for this yet because I'm just now looking into C++1y concepts.
Given those that are associated with the paper, I assume that I may be unique in this stance, though I could still be persuaded otherwise. My main concerns are that the C++0x concepts very clearly matched with the notion of archetypes (which I don't think N3351 even mentioned IIRC). When you wrote a C++0x concept, it wasn't all that dissimilar from declaring a type that models that concept, which, in my opinion, is a big advantage, and it is also makes it fairly clear what archetypes you can except from that concept. When I started Boost.Generic, I took the N3351 style approach but was persuaded to adopt pseudo-signatures instead because of the drawbacks of the ad-hoc expression-style approach (not just because it didn't match up with C++0x concepts) so I'm having trouble going back now. As for associated types, it seems like C++1y concepts are just relying on C++98-style template type traits classes, with concepts only doing verification on those type traits. To me this all just seems like a step backward from what would have been C++0x concepts. I look at iterator_traits as being a hack that came about because there is no direct way to properly create concepts and concept maps with associated types in C++98. Now that there is a chance to eliminate the need for it, aside from legacy code, I'd rather not miss that opportunity, especially given that C++0x concepts were very close to being a standard part of the language and essentially removed the need for things such as iterator_traits (not to mention that they removed the need for things like an explicit iterator category, which these new concepts still have to rely on to some extent). So perhaps this is simpler, but it seems to me like it's also less functional, and that is something I don't agree with. The one thing that I'm really a big fan of in N3351 is its considerable use of axioms, but I just don't see any rationale for the drastic departure from C++0x concepts. -- -Matt Calabrese

On Thu, Sep 27, 2012 at 5:09 PM, Matt Calabrese <rivorus@gmail.com> wrote:
On Thu, Sep 27, 2012 at 4:00 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
I'd probably be more interested in the part of the impl that expands the macro code to implement concepts, not necessarily the pp stuff.
Refer to boost/generic/concept.hpp line 253 BOOST_GENERIC_CONCEPT_IMPL_VALID_
It's probably hard to decipher since, as you probably realize, pretty much everything needs to go into its own, separate metafunction and everything needs to be expanded inside of template specialization argument lists in order for SFINAE to take place, and all of the associated types of the concept need to be template arguments to every single one of those metafunctions for SFINAE to work with them as well. Also, on the macro side, in order to reduce compile times, I avoid making multiple passes over the top-level macro arguments and instead preprocess it all at once, putting code that will eventually go into different locations into different boost preprocessor sequence elements, and then I pull those out individually at the end. This succeeded at greatly reducing compile-times, but it makes the code harder to read.
Also, if you want to simply see the preprocessor output, refer to the "*.hei" files in the include directories. These are the pre-preprocessed forms of the standard concepts, individually. -- -Matt Calabrese

On Thu, Sep 27, 2012 at 2:09 PM, Matt Calabrese <rivorus@gmail.com> wrote:
On Thu, Sep 27, 2012 at 4:00 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
It might help to start by taking a look at contract/detail/preprocessor/traits/. Also, this is a possible syntax I had in mind for C++0x concept definitions:
http://contractpp.svn.sourceforge.net/viewvc/contractpp/releases/contractpp_...
Looks great. I'll probably do most of that eventually, but I'd like to save those changes for later, since what is in currently works and I'd rather focus on new features first before I overhaul the interface.
Makes sense. Also be careful that Boost.Contract increases compilation times x30!! Essentially the lib does the following steps (1) macros parse the syntax (pp), (2) macros expand code that implements the contracts (pp), (3) the expanded code (there's a lot of template meta-programming here) is compiled (compiler). I don't know how the x30 is distributed between (1), (2), and (3) (I still have to analyze and optimize that) but if you were to adopt the syntax you'll start paying the overhead that comes from (1)--(2) and (3) instead will be specific to your lib. --Lorenzo

On Thu, Sep 27, 2012 at 8:45 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
On Thu, Sep 27, 2012 at 2:09 PM, Matt Calabrese <rivorus@gmail.com> wrote:
On Thu, Sep 27, 2012 at 4:00 PM, Lorenzo Caminiti <lorcaminiti@gmail.com wrote:
It might help to start by taking a look at contract/detail/preprocessor/traits/. Also, this is a possible syntax I had in mind for C++0x concept definitions:
http://contractpp.svn.sourceforge.net/viewvc/contractpp/releases/contractpp_...
Looks great. I'll probably do most of that eventually, but I'd like to save those changes for later, since what is in currently works and I'd rather focus on new features first before I overhaul the interface.
Makes sense. Also be careful that Boost.Contract increases compilation times x30!! Essentially the lib does the following steps (1) macros parse the syntax (pp), (2) macros expand code that implements the contracts (pp), (3) the expanded code (there's a lot of template meta-programming here) is compiled (compiler). I don't know how the x30 is distributed between (1), (2), and (3) (I still have to analyze and optimize that) but if you were to adopt the syntax you'll start paying the overhead that comes from (1)--(2)
Right. Well, with respect to concepts at least, preprocessing overhead isn't as big of a deal for me anymore as it used to be, since concepts change very often -- as I mentioned, using the pre-preprocessed headers I provide (that are trivial to generate with the Boost.Wave driver) decreases compilation speed for Boost.Generic tests by over 50% by getting rid of all of the complex preprocessor metaprogramming, so even if using your macros behind the scenes increases compilation times because of preprocessing, I don't think it would matter too much in practice. Besides, I doubt your approach would be considerably slower or faster than what I'm doing right now. The interface is now much more important than preprocessing time. -- -Matt Calabrese

On Thu, Sep 27, 2012 at 8:57 PM, Matt Calabrese <rivorus@gmail.com> wrote:
Right. Well, with respect to concepts at least, preprocessing overhead isn't as big of a deal for me anymore as it used to be, since concepts change very often
*since concepts DON'T change very often, in case that wasn't clear. -- -Matt Calabrese

On Thu, Sep 27, 2012 at 5:58 PM, Matt Calabrese <rivorus@gmail.com> wrote:
On Thu, Sep 27, 2012 at 8:57 PM, Matt Calabrese <rivorus@gmail.com> wrote:
Right. Well, with respect to concepts at least, preprocessing overhead isn't as big of a deal for me anymore as it used to be, since concepts change very often
*since concepts DON'T change very often, in case that wasn't clear.
Yes, of course. That's a big difference with respect to Boost.Contract where the macros are used in the user code so I can't pre-compile stuff in the lib to speed up things. (Using pre-compiled headers in the user code reduced re-compilation time of the users code from x30 to x2 but users still have to wait a long time when they compile their headers for the 1st time and if they significantly change their contracts as many of the pre-compiled header will need to be re-compiled.) --Lorenzo

On Thu, Sep 27, 2012 at 9:11 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
Yes, of course. That's a big difference with respect to Boost.Contract where the macros are used in the user code so I can't pre-compile stuff in the lib to speed up things. (Using pre-compiled headers in the user code reduced re-compilation time of the users code from x30 to x2 but users still have to wait a long time when they compile their headers for the 1st time and if they significantly change their contracts as many of the pre-compiled header will need to be re-compiled.)
Yeah, that's a truly enormous speed-up. It's too bad preprocessor code is not that easy to profile. I don't know about you, but it was sometimes a bit of a guessing game and trial-and-error for me before settling in on the approach that I ended up with. -- -Matt Calabrese

On Thu, Sep 27, 2012 at 6:38 PM, Matt Calabrese <rivorus@gmail.com> wrote:
On Thu, Sep 27, 2012 at 9:11 PM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
Yes, of course. That's a big difference with respect to Boost.Contract where the macros are used in the user code so I can't pre-compile stuff in the lib to speed up things. (Using pre-compiled headers in the user code reduced re-compilation time of the users code from x30 to x2 but users still have to wait a long time when they compile their headers for the 1st time and if they significantly change their contracts as many of the pre-compiled header will need to be re-compiled.)
Yeah, that's a truly enormous speed-up. It's too bad preprocessor code is not that easy to profile. I don't know about you, but it was sometimes a bit of a guessing game and trial-and-error for me before settling in on the approach that I ended up with.
Honestly, I didn't even try to profile/optimize Boost.Contract pp code yet. I'm not sure if I'll try to count the number of macro expansions, the depth of macro expansion, etc... maybe using clang or Eclipse... I don't know yet. For a project with 122 files and 15,471 lines of code, Boost.Contract increased compilation time x26 when all contracts are enabled and x2 when contracts are disabled (with respect to the same code without the Boost.Contract macros which is the baseline at x1): http://contractpp.svn.sourceforge.net/viewvc/contractpp/releases/contractpp_... In both cases contracts enabled/disabled, the parsing macro code it there so _maybe_ that's not where the bottle neck it. When contracts are disabled the macros expand just to the function declaration signature. When contracts are enabled the macros expand to the contract checking code so maybe the bottle neck is in expanding this code (pp) and then compiling it (compiler). But this is just speculation, I need to profile and optimize Boost.Contract pp and non-pp code. --Lorenzo

On Fri, Sep 28, 2012 at 5:18 AM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
Honestly, I didn't even try to profile/optimize Boost.Contract pp code yet. I'm not sure if I'll try to count the number of macro expansions, the depth of macro expansion, etc... maybe using clang or Eclipse... I don't know yet.
I didn't use it at the time, but Boost.Wave should be able to help a lot with that. It has pragmas for tracing the macro expansion process and for timing. With _Pragma, it should even be possible to trace and time individual parts of a single overall macro expansion. http://www.boost.org/doc/libs/1_51_0/libs/wave/doc/supported_pragmas.html -- -Matt Calabrese

On Fri, Sep 28, 2012 at 9:03 AM, Matt Calabrese <rivorus@gmail.com> wrote:
On Fri, Sep 28, 2012 at 5:18 AM, Lorenzo Caminiti <lorcaminiti@gmail.com>wrote:
Honestly, I didn't even try to profile/optimize Boost.Contract pp code yet. I'm not sure if I'll try to count the number of macro expansions, the depth of macro expansion, etc... maybe using clang or Eclipse... I don't know yet.
I didn't use it at the time, but Boost.Wave should be able to help a lot with that. It has pragmas for tracing the macro expansion process and for timing. With _Pragma, it should even be possible to trace and time individual parts of a single overall macro expansion. http://www.boost.org/doc/libs/1_51_0/libs/wave/doc/supported_pragmas.html
Cool! I'll keep it in mind for when I start Boost.Contract profiling and optimization. It probably makes sense to profile and optimize on a couple of pp and compilers anyways (because most of the pp and template meta-programming code will likely perform differently on different platforms) so maybe Wave, GCC, and MSVC... Thanks. --Lorenzo

on Thu Sep 27 2012, Matt Calabrese <rivorus-AT-gmail.com> wrote:
Hey everyone,
It's been a while since I've made an appearance on this list,
Hey, good to hear from you; welcome back!
but I was contacted regarding the recent discussion of concepts here and Lorenzo's taking the reins of a concept library, and decided to poke my head in. First, I apologize to the community for not getting Boost.Generic on the sandbox earlier (if you are unfamiliar with Boost.Generic, see my 2011 BoostCon talk http://blip.tv/boostcon/boost-generic-concepts-without-concepts-5262126 and/or the corresponding slides https://github.com/boostcon/2011_presentations/raw/master/thu/Boost.Generic.... ). I've gotten numerous emails about it since 2011 and I decided to commit the current state of Boost.Generic to the sandbox today.
Thanks!
It is still based on the "old" concepts of C++0x with pseudo-signatures. You can find it in the "generic" subdirectory of the sandbox. That said, I'm not sure anyone even cares about Boost.Generic anymore given that the standard seems to be diverging from how it originally was approaching concepts,
I would not draw too many conclusions from the recent EWG proposals. It remains unclear to many of us that the "valid expressions" approach is technically or ergonomically feasible.
but here it is anyway. Similarly, I'm not sure there is any interest from people for me to continue developing Boost.Generic, so I guess this is a check for interest again.
+1
And, very briefly, without getting too political here (not that my opinion has any bearing) but I personally do not agree with some of the recent design changes for what may turn out to be C++1y concepts -- specifically I think pseudo-signatures were better overall and the C++0x form of associated types was much more useful than what is currently described, especially concerning associated type deduction, which no longer appears to be possible. But I don't think this discussion is suitable for the Boost mailing list and I don't want to ruffle too many feathers beyond that, so I'll take that elsewhere.
You should bring it to https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/std-discussi... or https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/std-proposal....
For this reason, though, I [currently] do not have a desire to support that form of concepts in my library, though I do plan to resume work on Boost.Generic.
+1
A recap of what's gone on since my Boostcon talk, for anyone who even remembers it -- I haven't been actively developing Boost.Generic for over a year as I have been busy with other things, but coincidentally in the past couple of weeks I've gone back to it and decided to update some things due to a trick I realized I could use to get full compatibility with the C++0x working paper for explicit concept map templates (N2914's 14.10.3.2 paragraph 3 highlights why it's non-trivial, see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2914.pdf).
? That seems to cover implicit (not explicit) concept maps: 14.10.3.2 Implicit concept maps for refined concepts [concept.refine.maps]
Since then, I've had renewed interest in the project and have updated various facilities. Stuff that changed since my presentation back in 2011 -- it now supports variadic concepts using the syntax ,,, (see
So clever. -- Dave Abrahams BoostPro Computing Software Development Training http://www.boostpro.com Clang/LLVM/EDG Compilers C++ Boost

On Thu, Oct 4, 2012 at 5:25 PM, Dave Abrahams <dave@boostpro.com> wrote:
I would not draw too many conclusions from the recent EWG proposals. It remains unclear to many of us that the "valid expressions" approach is technically or ergonomically feasible.
Yeah, this is sort of my conclusion. I really don't understand the move away from pseudo-signatures, the lack of mention of archetypes, lack of associated type deduction, etc. I think what I'm going to try to do is finish Boost.Generic following N2914 along side of Lorenzo's N3351 implementation (and preferably start sharing backend implementation of some things). At that point, perhaps we'll have two reasonable implementations of the ideas presented in both and people will actually be able to determine which proposal they feel is more suitable for standardization. It also makes it easy to experiment with different library specifications as well. Right now, I get the sense that some people definitely want concepts in some form but don't necessarily have an understanding of all of the nuances of the different approaches (let alone the larger capabilities), making it difficult to make a sound judgment on the benefits and drawbacks of each. If people have a chance to actually use both implementations, especially developers of generic libraries, it will hopefully make the debate at least a little less theoretical than it currently is.
You should bring it to
https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/std-discussi... or https://groups.google.com/a/isocpp.org/forum/?fromgroups#!forum/std-proposal... .
Once I finish all of the explicit concept map changes and properly document the library, I'll do that. Right now the tests, slides, and N2914 are the only documentation.
? That seems to cover implicit (not explicit) concept maps:
14.10.3.2 Implicit concept maps for refined concepts [concept.refine.maps]
It affects the implicit generation of concept maps of less-refined concepts based on explicit concept maps of a more-refined concept -- in a world of all auto concepts, none of this is comes into play (which is why Boost.Generic works perfectly fine in all tested cases for concepts that make even heavy use of refinement, as long as the concepts involved are auto). The tricky part comes from coding the concept map look-up for concept maps of less-refined concept in the case where someone provides a concept map template for a more-refined concept. This is nontrivial since it's entirely possible for, I.E., a more-refined concept to have more (or less, or reordered) arguments than a concept that it refines, but the less-refined concept still needs to be deducible from the template arguments for the more-refined concept's concept map template; otherwise, it would be impossible to match that template with the less-refined concept (that was a mouthful). This type of situation is what's referred to in that part of the standard that I linked. The trick I use in the end is to make curious use of template aliasing along with function template overloads to get the same type of deduction and pattern matching that is described in the standard. It's a little bit trickier than that because the library needs to keep track of the more refined concepts and concept maps in compile-time mutable type lists that are updated every time a new concept refinement or concept map is introduced in a translation unit. My proof-of-concept on this works, but it's taking a few days to implement in full. -- -Matt Calabrese

On Thu, Oct 4, 2012 at 8:16 PM, Matt Calabrese <rivorus@gmail.com> wrote:
On Thu, Oct 4, 2012 at 5:25 PM, Dave Abrahams <dave@boostpro.com> wrote:
I would not draw too many conclusions from the recent EWG proposals. It remains unclear to many of us that the "valid expressions" approach is technically or ergonomically feasible.
Yeah, this is sort of my conclusion. I really don't understand the move away from pseudo-signatures, the lack of mention of archetypes, lack of associated type deduction, etc. I think what I'm going to try to do is finish Boost.Generic following N2914 along side of Lorenzo's N3351 implementation (and preferably start sharing backend implementation of some things).
Yes, this would be ideal to have two libs that implement concepts as per N2914 adn N3351 so the std people can see impl of both ideas and decide for the best when/if it comes to adopting concepts (and hopefully also pre/post/inv) into the C++ standard. To this, the syntax of the concept macros (Generic-like, Concept-like, more or less extra parenthesis, etc) is essentially irrelevant as the main purpose is to implement the concept design of N2914 and N3351 irregardless of the syntax used by the lib to implement such a design. All of that said, I don't have a lot of time to work on implementing N3351 as my priorities are (1) get Boost.Contract into a release, (2) reduce Boost.Contract compilation times, and (3) implement N3351 concepts (only last priority). However, I'd like to have an idea on how to do (3) before I put it off to do (1) and (2) to see if there's any major road block that could require Boost.Contract design changes.
At that point, perhaps we'll have two reasonable implementations of the ideas presented in both and people will actually be able to determine which proposal they feel is more suitable for standardization. It also makes it easy to experiment with different library specifications as well. Right now, I get the sense that some people definitely want concepts in some form but don't necessarily have an understanding of all of the nuances of the different approaches (let alone the larger capabilities), making it difficult to make a sound judgment on the benefits and drawbacks of each. If people have a chance to actually use both implementations, especially developers of generic libraries, it will hopefully make the debate at least a little less theoretical than it currently is.
Thanks, --Lorenzo
participants (3)
-
Dave Abrahams
-
Lorenzo Caminiti
-
Matt Calabrese