Ustring format_radix(T t, int base, int prec) {
     // Argument will never be negative
     Ustring s;
     auto b = static_cast<T>(base);
     prec = std::max(prec, 1);
     while (t > 0 || int(s.size()) < prec) {
         auto d = t % b;
         s += char(d + (d <= 9 ? '0' : 'a' - 10));
         t /= b;
     }
     std::reverse(s.begin(), s.end());
     return s;
 }
void
Entry::calculate_title( const Ustring& text )
{
    if( text.size() < 1 )
    {
        m_name = _( STRING::EMPTY_ENTRY_TITLE );
        return;
    }
    unsigned int l_pos = text.find( '\n', 0 );
    if( l_pos == std::string::npos )
        m_name = text;
    else
        m_name = text.substr( 0, l_pos );
}
 std::function<bool(char32_t)> gc_predicate(const Ustring& cat, bool sense) {
     auto table = make_category_table(cat.data(), cat.size());
     return make_category_function(table, sense);
 }
Result
Date::parse_string( Date::date_t* date, const Ustring& str_date )
{
    char c_cur;
    unsigned int num[ 4 ] = { 0, 0, 0, 0 };  // fourth int is for trailing spaces
    int i( 0 );

    for( unsigned j = 0; j < str_date.size(); j++ )
    {
        c_cur = str_date[ j ];
        switch( c_cur )
        {
            case '0': case '1': case '2': case '3': case '4':
            case '5': case '6': case '7': case '8': case '9':
                if( i > 2 )
                    return INVALID;
                num[ i ] *= 10;
                num[ i ] += ( c_cur - '0' );
                break;
            case ' ':
                if( num[ i ] > 0 )
                    i++;
                break;
            case '.':
            case '-':
            case '/':
                if( num[ i ] == 0 || i == 2 )
                    return INVALID;
                else
                    i++;
                break;
            default:
                return INVALID;
        }
    }

    if( num[ 2 ] ) // temporal
    {
        unsigned int year( 0 );
        unsigned int month( 0 );
        unsigned int day( 0 );

        if( num[ 0 ] > 31 && num[ 1 ] <= 12 && num[ 2 ] <= 31 ) // YMD
        {
            year = num[ 0 ];
            month = num[ 1 ];
            day = num[ 2 ];
        }
        else
        {
            if( num[ 0 ] <= 12 && num[ 1 ] <= 12 ) // both DMY and MDY possible
            {
                if( s_date_format_order[ 0 ] == 'M' )
                {
                    month = num[ 0 ];
                    day = num[ 1 ];
                }
                else
                {
                    day = num[ 0 ];
                    month = num[ 1 ];
                }
            }
            else if( num[ 0 ] <= 31 && num[ 1 ] <= 12 ) // DMY
            {
                month = num[ 1 ];
                day = num[ 0 ];
            }
            else if( num[ 0 ] <= 12 && num[ 1 ] <= 31 ) // MDY
            {
                month = num[ 1 ];
                day = num[ 0 ];
            }
            else
                return INVALID;

            year = num[ 2 ];

            if( year < 100 )
                year += ( year < 30 ? 2000 : 1900 );
        }

        if( year < YEAR_MIN || year > YEAR_MAX )
            return OUT_OF_RANGE;

        Date date_tmp( year, month, day );
        if( ! date_tmp.is_valid() ) // checks days in month
            return INVALID;

        if( date )  // pass NULL when just used for checking
            *date = date_tmp.m_date;

    }
    else if( num[ 1 ] )   // ordinal
    {
        if( num[ 0 ] > CHAPTER_MAX || num[ 1 ] > ORDER_MAX )
            return OUT_OF_RANGE;

        if( date )  // pass NULL when just used for checking
            *date = make_date( num[ 0 ], num[ 1 ] );
    }
    else
        return INVALID;

    return OK;
}