This Week in Boost

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.

Posted Monday, October 12th, 2009 under Boost.

15 Responses to “This Week in Boost”

  1. Kaz Dragon says:

    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?

      (Quote)
  2. Michael Caisse says:

    Great idea for a series Steven. I’m looking forward to reading your weekly updates.

      (Quote)
  3. Steven Watanabe says:
    Joel Falcou: 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 ?

    What exactly are you asking? The library can be downloaded from the Boost Vault if that’s what you mean.

      (Quote)
  4. Joel Falcou says:

    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 ?

      (Quote)
  5. Steven Watanabe says:
    Dave Abrahams: Is there some reason that the comma operator trick can’t be used to avoid errors in case operator< returns void?

    That just moves the problem with void to an overloaded operator,.

    \#include <boost/mpl/assert.hpp>
    \#include <boost/detail/is_incrementable.hpp>
     
    struct test {
        test& operator++() { return(*this); }
    };
     
    template<class T>
    void operator,(const test&, const T&) {}
     
    int main() {
        BOOST_MPL_ASSERT((boost::detail::is_incrementable<test>));
    }
      (Quote)
    • :( So did I implement that trick incorrectly, or is there really no way out of that problem?

        (Quote)
      • Steven Watanabe says:

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

          (Quote)
        • Tony says:

          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

            (Quote)
    • litb says:

      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.

        (Quote)
      • Steven Watanabe says:

        Yeah, that seems a little better. I’m not sure that it makes much difference in practice, since I’ve only seen an overloaded operator, in contrived examples anyway.

          (Quote)
  6. Is there some reason that the comma operator trick can’t be used to avoid errors in case operator< returns void?

      (Quote)
  7. Dudy says:

    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.

      (Quote)

Leave a Comment (post replies using links below individual comments)

Spam Protection by WP-SpamFree

Subscribe without commenting