Boost logo

Boost :

Subject: Re: [boost] [review][assign] Formal review of Assign v2 ongoing
From: John Bytheway (jbytheway+boost_at_[hidden])
Date: 2011-06-22 19:28:47


On 21/06/11 21:47, Simonson, Lucanus J wrote:
> John Bytheway wrote:
>> On 20/06/11 18:36, Simonson, Lucanus J wrote: <snip>
>>> I very much like initializer list syntax, but the syntax for
>>> this library doesn't give me any warm feelings. Perhaps we need
>>> motivating examples and a little bit of rationale for *why* such
>>> a library should exist. Does it make doing something much easier
>>> in a templated context or is it just a quest to type less when
>>> using standard containers in code that looks like the examples?
>>> I ordinarily only initialize containers to literals when writing
>>> unit tests.
>>
>> I think unit tests are indeed an important use case for such a
>> library. That's where I use the existing Boost.Assign.
>
> In unit tests I tend to write ugly code like:
>
> std::vector<Point> pts;
> pts.push_back(Point(0,0));
> pts.push_back(Point(0,10));
> pts.push_back(Point(10,10));
> pts.push_back(Point(10,0));
> Polygon pgn(pts.begin(), pts.end());
> assert(boost::polygon::area(pgn) == 100);
>
> only because I'm lazy and I'm not really concerned about whether my
> unit test code is elegant. Unit tests is where I need such a library
> most, but care least.

If you'd like more specific evidence, here's a unit test from a program
of mine using Assign v1 where it saves a great deal of code over the
above approach:

    auto result = do_outcome_test(
      list_of("7 4 H:8")("2 D:9 H:J"),
      list_of("r")("")("")("")("t"),
      list_of
        ("21")("Sk")("20")("18")
        ("C9")("CQ")("CJ")("CN")
        ("12")("16")("19")("17")
        ("10")("14")("13")("15")
        (" 8")("CK")(" 9")("11")
        ("SJ")("St")("S8")("SN")
        ("HK")("H9")(" 5")("HQ")
        (" 6")("DN")(" 3")("DK")
        ("DQ")("DJ")("Dt")("SK")
        ("Ht")("H7")(" 1")("HN")
        ("C8")("S9")("C7")("Ct")
        ("D8")("S7")("D7")("SQ")
    );
    BOOST_CHECK(result.scores == list_of(0)(0)(0)(0));
    BOOST_CHECK_EQUAL(result.outcome.string(), "t4");

> I don't understand the motivation for having this library if using
> C++0x initializer lists is an option. What then is the point of
> C++0x only library features?

What features are you thinking of? I think it is primarily that the
library takes advantage of C++0x where possible to go better or faster,
rather than providing 0x-only features.

> Allowing a filter function to be
> applied on each element as it initializes the container seems
> somewhat of a stretch.

Well, here are a few possible reasons why it's reasonable to take
advantage of C++0x features to solve problems for which initializer
lists would be a better solution:

- gcc supported variadic templates and rvalue references before
initializer lists. clang doesn't support the latter yet. So, there are
compilers out there where these features can be used and initializer
lists cannot.

- Containers have to explicitly support initializer lists. There are
plenty out there that don't, and most probably never will.

- You can write code which works under both C++03 and 0x, but will
compile and/or run faster in 0x.

> We can't have
>
> template <typename T> boost::range<T> get_range(T*, std::size_t
> size);
>
> foo(get_range({"a", "b", "c"}, 3);
>
> or even
>
> template<typename T, int size> boost:range<T> get_range(T[size]);
>
> foo(get_range({"a", "b", "c"});
>
> as a simple range adaptor for C-style array so that we can use
> regular array initializer lists as a range, but have to go through an
> intermediate c-sytle array instead.
>
> I get this error:
> test.cpp:6: error: expected primary-expression before '{' token
> when I try, so I guess we can't pass C++98
> initializer lists directly into functions. Even if we could that
> would only get us half way since we still wouldn't have initializer
> lists for elements of the array.
>
> Oh well,
> Luke

Sorry, I don't really understand your point. Indeed this failing of
C++98 is one of the motivations for the Assign library.

Even in gcc 4.5 in 0x mode I can't do this:

void f(std::array<int, 3> const&)
{
}

f({0, 1, 2});

I'm not sure whether it is supposed to work by the standard. The
analogous thing with std::vector does work.

John


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