Boost logo

Boost :

From: Aleksey Gurtovoy (alexy_at_[hidden])
Date: 2001-11-26 22:09:38

> Assuming the comment refers to the names type_is and value_is , the
> intent, of course, is let_type_be<...> and let_value_be<...> , but
> those are just too awkward to type, methinks. Or maybe not, on second
> thought. Hmm.

It is! For instance, consider stuffing a type_list by a dozen of integer
values (boost::mpl has value_list for that, but let's ignore it for the sake
of the example); with the names you propose, it will be something like this:

    typedef type_list<
        let_value_be<int,1>, let_value_be<int,7>, let_value_be<int,5>,
        let_value_be<int,2>, let_value_be<int,4>, let_value_be<int,8>,
        let_value_be<int,9>, let_value_be<int,2>, let_value_be<int,0>,
        let_value_be<int,3>, let_value_be<int,9>, let_value_be<int,1>
> values;

IMO, there is too much visual clutter here, especially if you consider how
little information the above declaration carries. Or, for example, here is a
compile-time 'for' loop:

    for_loop< let_value_be<int,1>, less_than< mpl::_1, let_value_be<int,1>
>, next<mpl::_1>
        , /* first statement */
        , /* function */

Personally, I find the above much less readable than current

    for_loop< int_t<1>, less_than< mpl::_1, int_t<1> >, next<mpl::_1>
        , /* first statement */
        , /* function */

> For my purposes, I would like the value wrapper (whatever name boost
> ultimately gives it) to handle all the integral types for which the
> language permits non-type template arguments. I have use for unsigned
> and signed ints of various sizes, as well as for bools, of course, and
> would strongly prefer that a single value wrapper handle them
> all.

In principle, I agree. I guess the only reason boost::mpl doesn't have it is
because I never needed more than two of such wrappers - one for int (int_t)
and another one for bool (bool_t). But, as I noted above, the genericity of
a single value wrapper is also its weak side - the template is much more
cumbersome to use, especially in contexts where one ideally would like to
write just an integer constant - 1, 10 or whatever - if the language has
allowed it. Just as an example of how inconvenient this might be - at some
point boost::mpl::int_t<> was called int_value<>, and I changed the name
_mainly_ because even the 9/1 characters ratio (9 "ballast"/ 1-2 informative
ones) was too much.

> The alternative seems to be lots of value wrappers, one per type,
> and I'm not fond of such proliferation.

Me too. But do you always care what underlying type - short, int or long -
is used to keep your loop counter, if all you want to do is to iterate from
0 to 10? I don't, and in such cases I don't want to write any of those
let_value_be<short,10>, let_value_be<int,10>, or let_value_be<long,0>
instead of simple int_t<10>. Yes, a library should provide a generic wrapper
along the lines you suggest, but a shorter notation for everyday usage is
also required.

> In this context, I find it useful for the value wrapper to encompass
> the type wrapper (by inheritance or by aggregation, it doesn't matter
> to me) so that, if need be, I can inquire as to the wrapped value's
> type. This, however, appears to conflict with other implementations.
> Some seem not to address this at all, while others seem to prefer that
> the wrapper's reported type (::type) be that of the wrapper itself.

Yes, the latter is what boost::mpl does. It's important to be able to treat
those int_t<>, bool_t<>, etc. "objects" as compile-time nullary functions,
which means supporting the "type" interface in the way you've described
(int_t<N>::type == int_t<N>). As for wrapped value's type - I think it
should be exposed under exactly that name: "value_type" :).

Hmm, I think I will add this to mpl, and re-define 'int_t<>' in terms of it

    template<typename T, T N>
    struct integral_t
        BOOST_STATIC_CONSTANT(T, value = N);
        typedef T value_type;
        typedef integral_t<N> type;

        // increment/decrement support
        typedef integral_t<N + 1> next;
        typedef integral_t<N - 1> prior;

        // default ctor, conversion operator, etc..

> Thus, there are a few issues beyond naming (as important as that is)
> that ought be discussed, in my opinion, at least briefly.

Yes, and thanks for raising them!


Boost list run by bdawes at, gregod at, cpdaniel at, john at