Boost logo

Boost :

Subject: Re: [boost] [config/multiprecision/units/general] Do we have a policy for user-defined-literals?
From: John Maddock (john_at_[hidden])
Date: 2013-04-28 04:12:43


>If http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3402.pdf is the
>final version accepted for C++14, the standard will use, e.g.
>
>namespace std {
>namespace suffixes {
>namespace chrono {
>
>One of the advantages is that we can add some utilities. I helped Peter
>Sommerlad to port his reference implementation to Boost (See
>https://github.com/PeterSommerlad/UDLSuffixBoost/tree/master/boost/suffixes).
>There are some interesting utilities that make easier implementing
>suffixes. I guess it would like to name his library Boost.Suffixes.
>This doesn't means that we can not choose your option.

I hadn't seen that before, thanks for the heads up.

If we have UDL utilities in boost then I agree they should have their own
top-level namespace in Boost, whether it makes sense to group all literals
in there is another matter. My gut feeling is that users will find
boost::mylib::literals or boost::mylib::suffixes easier, but I can see how
it would make sense for the std to go your way.

BTW, I believe your implementation of parse_int is unnessarily complex,
looks like that whole file can be reduced to just:

template <unsigned base, unsigned long long val, char... Digits>
struct parse_int
{
    // The default specialization is also the termination condition:
    // it gets invoked only when sizeof...Digits == 0.
    static_assert(base<=16u,"only support up to hexadecimal");
    static constexpr unsigned long long value{ val };
};

template <unsigned base, unsigned long long val, char c, char... Digits>
struct parse_int<base, val, c, Digits...>
{
    static constexpr unsigned long long char_value = (c >= '0' && c <= '9')
            ? c - '0'
            : (c >= 'a' && c <= 'f')
            ? c - 'a'
            : (c >= 'A' && c <= 'F')
            ? c - 'A'
            : 400u;
    static_assert(char_value < base, "Encountered a digit out of range");
    static constexpr unsigned long long value{ parse_int<base, val * base +
char_value, Digits...>::value };
};

Typical usage is:

template <char...PACK>
constexpr unsigned long long operator "" _b()
{
   return parse_int<2, 0, PACK...>::value;
}

constexpr unsigned bt = 1001_b;

static_assert(bt == 9, "");

More than that though: I can't help but feel that base 8, 10 and 16 parsing
is much better (faster) handled by the compiler, so parse_int could be
reduced to base-2 parsing only which would simplify it still further.
What's the rationale for the chrono integer literals parsing the ints
themselves rather than using cooked literals?

Cheers, John.


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