Welcome to the inaugural article of This Week in Boost. Today, I’d like to talk about a couple of active development efforts. Let’s jump right in.
New Type Traits for Comparison Operators
Frédéric Bron requested a review of the new type
traits is_less_comparable and friends.
These traits allow the detection of any comparison operators.
For example,
BOOST_MPL_ASSERT((is_less_comparable<int>)); BOOST_MPL_ASSERT_NOT((is_less_comparable<std::complex<double> >)); BOOST_MPL_ASSERT_NOT((is_less_comparable<char*, int>));
They also check that the return type is convertible to bool, so
BOOST_MPL_ASSERT_NOT((is_less_comparable<proto::terminal<int>::type>));
This behavior turned out to be somewhat controversial.
In many contexts, it is exactly what we want. After all,
the
LessThanComparable concept requires it. On the
other hand, several people expressed concerns that
it is not generic enough and that the library should
not require anything beyond the bare existence of the
operators. The conclusion was to add another trait,
has_operator_less_than in addition to the current
is_less_comparable. This way users can
select the behavior that they want.
The mechanism used to implement these traits is not quite perfect. It can trigger an error if the operators return void. There is no known perfect solution for this problem in C++03, but, such aberrant operators are very rare. Usually comparison operators that don’t return bool belong to expression template frameworks. In practice, these traits work quite well.
Relational Database Mappings
Jean-Louis Leroy has been working on a new library which wraps access to relational databases. This library uses macros to define a schema for the database. Here’s an example from the documentation.
BOOST_RDB_BEGIN_TABLE(person) BOOST_RDB_COLUMN(id, integer) BOOST_RDB_COLUMN(name, varchar<20>) BOOST_RDB_COLUMN(first_name, varchar<30>) BOOST_RDB_COLUMN(age, integer) BOOST_RDB_END_TABLE(person)
Queries and are handled via a simple DSL:
person p; db.execute(insert_into(p)(p.id, p.first_name, p.name, p.age).values(1, "Homer", "Simpson", 37)); db.execute(select(p.id, p.first_name, p.name, p.age).from(p))
The cool thing about this is that the C++ compiler can catch type errors. For instance,
db.execute(insert_into(p)(p.id, p.first_name, p.name, p.age).values(2, "Marge", 34, "Simpson"));
The compiler is bitterly unhappy about this, and rightly so. The parameters are out of order. The main purpose of the library appears to be to provide this kind of static type-safety for database access. Expression templates allow it to achieve this goal cleanly.

With the 1.41.0 beta just around the corner (Thursday, IIRC), would it be possibe to give a quick overview as to what’s expected to be added to this great library collection?
Kaz Dragon(Quote)If you don’t mind reading quickbook source, you can check http://beta.boost.org/feed/history/boost_1_41_0.qbk
Steven Watanabe(Quote)Great idea for a series Steven. I’m looking forward to reading your weekly updates.
Michael Caisse(Quote)What exactly are you asking? The library can be downloaded from the Boost Vault if that’s what you mean.
Steven Watanabe(Quote)The database thingy starts to look like a real contender for the stuff we speak about at boost’Con 09 on the rdb library. Where does it ended up btw ?
Joel Falcou(Quote)That just moves the problem with
voidto an overloadedoperator,.
So did I implement that trick incorrectly, or is there really no way out of that problem?
Dave Abrahams(Quote)There might be a way out, but if there is, I couldn’t find it. I’ve tried using (non-portable) ADL hacks to generate an overload of
Steven Watanabe(Quote)operator,that is always more specialized than any user defined overload. It sort of worked on gcc and msvc. Unfortunately, there were still some ICEs that I couldn’t get rid of. I don’t remember the details exactly.Could you redefine a ‘standard’ operator,() inside of namespace detail/is_incr that hides the ‘bad’ user-defined one? ie then the one inside the namespace of is_incr be chosen first? Or is that too simple?
Tony
Tony(Quote)It would all be much easier if the language considered this to be valid:
int f() { return 1; } void f(int) { return 2; }
int main() { return f(f(4)); }
Tony
Tony(Quote)OK now I see how bad this is. ADL is even worse than I thought… Tony
Tony(Quote)I had the same problem and did two rounds of “operator,” like in this one: http://codepad.org/59U28jCs . It still fails for “op,(T const&, test)” but i thought it’s less likely such a op, exists.
litb(Quote)Yeah, that seems a little better. I’m not sure that it makes much difference in practice, since I’ve only seen an overloaded
Steven Watanabe(Quote)operator,in contrived examples anyway.Is there some reason that the comma operator trick can’t be used to avoid errors in case
Dave Abrahams(Quote)operator<returnsvoid?Neat! Thanks for taking up this weekly task. I really have a hard time tracking what all goes on with boost with my already hectic life.
The RDB modules sounds like it would be splendid with small tcp/udp clients… I’ve always wanted a good crossplatform, pro-generic DB lib for C++ . I wonder how it will pan out, however… since I know not all libs make it into boost for sometimes quite a while.
Dudy(Quote)