Boost logo

Boost :

Subject: [boost] Boost.Generic, C++0x Concepts, and C++1y Concepts
From: Matt Calabrese (rivorus_at_[hidden])
Date: 2012-09-27 15:20:58


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.pdf
).
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.pdf).
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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk