Changeset e8c4c59 in mainline


Ignore:
Timestamp:
2018-07-05T21:41:19Z (6 years ago)
Author:
Dzejrou <dzejrou@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
7c84fce
Parents:
fe39530
git-author:
Dzejrou <dzejrou@…> (2017-12-17 20:01:30)
git-committer:
Dzejrou <dzejrou@…> (2018-07-05 21:41:19)
Message:

cpp: added most of the integral conversions

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/cpp/include/internal/locale/num_get.hpp

    rfe39530 re8c4c59  
    3131
    3232#include <internal/locale.hpp>
     33#include <internal/locale/numpunct.hpp>
    3334#include <ios>
    3435#include <iterator>
     36#include <limits>
    3537
    3638namespace std
     
    4749            using iter_type = InputIterator;
    4850
    49             explicit num_get(size_t refs = 0);
     51            explicit num_get(size_t refs = 0)
     52            { /* DUMMY BODY */ }
    5053
    5154            iter_type get(iter_type in, iter_type end, ios_base& base,
     
    117120            static locale::id id;
    118121
    119             ~num_get();
     122            ~num_get()
     123            { /* DUMMY BODY */ }
    120124
    121125        protected:
     
    123127                             ios_base::iostate& err, bool& v) const
    124128            {
     129                if (in == end)
     130                {
     131                    err = ios_base::eofbit;
     132                    return in;
     133                }
     134
     135                if ((base.flags() & ios_base::boolalpha) == 0)
     136                {
     137                    int8_t tmp{};
     138                    in = get_integral_<int64_t>(in, end, base, err, tmp);
     139
     140                    if (tmp == 0)
     141                        v = false;
     142                    else if (tmp == 1)
     143                        v = true;
     144                    else
     145                    {
     146                        v = true;
     147                        err = ios_base::failbit;
     148                    }
     149                }
     150                else
     151                {
     152                    /**
     153                     * We track both truename() and falsename()
     154                     * at the same time, once either is matched
     155                     * or the input is too big without a match
     156                     * or the input ends the conversion ends
     157                     * and the result is deduced.
     158                     */
     159
     160                    auto loc = base.getloc();
     161                    const auto& nt = use_facet<numpunct<char_type>>(loc);
     162
     163                    auto true_target = nt.truename();
     164                    auto false_target = nt.falsename();
     165
     166                    if (true_target == "" || false_target == "")
     167                    {
     168                        v = (err == ios_base::failbit);
     169                        return in;
     170                    }
     171
     172                    auto true_str = true_target;
     173                    auto false_str = false_target;
     174
     175                    size_t i{};
     176                    while (true)
     177                    {
     178                        if (true_str.size() <= i && false_str.size() <= i)
     179                            break;
     180                        auto c = *in++;
     181
     182                        if (i < true_str.size())
     183                            true_str[i] = c;
     184                        if (i < false_str.size())
     185                            false_str[i] = c;
     186                        ++i;
     187
     188                        if (in == end || *in == '\n')
     189                        {
     190                            err = ios_base::eofbit;
     191                            break;
     192                        }
     193                    }
     194
     195                    if (i == true_str.size() && true_str == true_target)
     196                    {
     197                        v = true;
     198
     199                        if (++in == end)
     200                            err = ios_base::eofbit;
     201                        else
     202                            err = ios_base::goodbit;
     203                    }
     204                    else if (i == false_str.size() && false_str == false_target)
     205                    {
     206                        v = false;
     207
     208                        if (in == end)
     209                            err = (ios_base::failbit | ios_base::eofbit);
     210                        else
     211                            err = ios_base::failbit;
     212                    }
     213                    else
     214                        err = ios_base::failbit;
     215                }
     216
     217                return in;
     218            }
     219
     220            iter_type do_get(iter_type in, iter_type end, ios_base& base,
     221                             ios_base::iostate& err, long& v) const
     222            {
     223                return get_integral_<int64_t>(in, end, base, err, v);
     224            }
     225
     226            iter_type do_get(iter_type in, iter_type end, ios_base& base,
     227                             ios_base::iostate& err, long long& v) const
     228            {
     229                return get_integral_<int64_t>(in, end, base, err, v);
     230            }
     231
     232            iter_type do_get(iter_type in, iter_type end, ios_base& base,
     233                             ios_base::iostate& err, unsigned short& v) const
     234            {
     235                return get_integral_<uint64_t>(in, end, base, err, v);
     236            }
     237
     238            iter_type do_get(iter_type in, iter_type end, ios_base& base,
     239                             ios_base::iostate& err, unsigned int& v) const
     240            {
     241                return get_integral_<uint64_t>(in, end, base, err, v);
     242            }
     243
     244            iter_type do_get(iter_type in, iter_type end, ios_base& base,
     245                             ios_base::iostate& err, unsigned long& v) const
     246            {
     247                return get_integral_<uint64_t>(in, end, base, err, v);
     248            }
     249
     250            iter_type do_get(iter_type in, iter_type end, ios_base& base,
     251                             ios_base::iostate& err, unsigned long long& v) const
     252            {
     253                return get_integral_<uint64_t>(in, end, base, err, v);
     254            }
     255
     256            iter_type do_get(iter_type in, iter_type end, ios_base& base,
     257                             ios_base::iostate& err, float& v) const
     258            {
    125259                // TODO: implement
    126260            }
    127261
    128262            iter_type do_get(iter_type in, iter_type end, ios_base& base,
    129                              ios_base::iostate& err, long& v) const
     263                             ios_base::iostate& err, double& v) const
    130264            {
    131265                // TODO: implement
     
    133267
    134268            iter_type do_get(iter_type in, iter_type end, ios_base& base,
    135                              ios_base::iostate& err, long long& v) const
     269                             ios_base::iostate& err, long double& v) const
    136270            {
    137271                // TODO: implement
     
    139273
    140274            iter_type do_get(iter_type in, iter_type end, ios_base& base,
    141                              ios_base::iostate& err, unsigned short& v) const
     275                             ios_base::iostate& err, void*& v) const
    142276            {
    143277                // TODO: implement
    144278            }
    145279
    146             iter_type do_get(iter_type in, iter_type end, ios_base& base,
    147                              ios_base::iostate& err, unsigned int& v) const
    148             {
    149                 // TODO: implement
    150             }
    151 
    152             iter_type do_get(iter_type in, iter_type end, ios_base& base,
    153                              ios_base::iostate& err, unsigned long& v) const
    154             {
    155                 // TODO: implement
    156             }
    157 
    158             iter_type do_get(iter_type in, iter_type end, ios_base& base,
    159                              ios_base::iostate& err, unsigned long long& v) const
    160             {
    161                 // TODO: implement
    162             }
    163 
    164             iter_type do_get(iter_type in, iter_type end, ios_base& base,
    165                              ios_base::iostate& err, float& v) const
    166             {
    167                 // TODO: implement
    168             }
    169 
    170             iter_type do_get(iter_type in, iter_type end, ios_base& base,
    171                              ios_base::iostate& err, double& v) const
    172             {
    173                 // TODO: implement
    174             }
    175 
    176             iter_type do_get(iter_type in, iter_type end, ios_base& base,
    177                              ios_base::iostate& err, long double& v) const
    178             {
    179                 // TODO: implement
    180             }
    181 
    182             iter_type do_get(iter_type in, iter_type end, ios_base& base,
    183                              ios_base::iostate& err, void*& v) const
    184             {
    185                 // TODO: implement
     280        private:
     281            template<class BaseType, class T>
     282            iter_type get_integral_(iter_type in, iter_type end, ios_base& base,
     283                                    ios_base::iostate err, T& v) const
     284            {
     285                BaseType res{};
     286                unsigned int num_base{10};
     287
     288                auto basefield = (base.flags() & ios_base::basefield);
     289                if (basefield == ios_base::oct)
     290                    num_base = 8;
     291                else if (basefield == ios_base::hex)
     292                    num_base = 16;
     293
     294                auto size = fill_buffer_integral_(in, end, base);
     295                if (size > 0)
     296                {
     297                    if constexpr (is_signed<BaseType>::value)
     298                        str_int64_t(base.buffer_, nullptr, num_base, false, &res);
     299                    else
     300                        str_uint64_t(base.buffer_, nullptr, num_base, false, &res);
     301
     302                    if (res > static_cast<BaseType>(numeric_limits<T>::max()))
     303                    {
     304                        err |= ios_base::failbit;
     305                        v = numeric_limits<T>::max();
     306                    }
     307                    else if (res < static_cast<BaseType>(numeric_limits<T>::min()))
     308                    {
     309                        err |= ios_base::failbit;
     310                        v = numeric_limits<T>::min();
     311                    }
     312                    else
     313                        v = static_cast<T>(res);
     314                }
     315                else
     316                {
     317                    err |= ios_base::failbit;
     318                    v = 0;
     319                }
     320
     321                return in;
     322            }
     323
     324            size_t fill_buffer_integral_(iter_type& in, iter_type end, ios_base& base) const
     325            {
     326                if (in == end)
     327                    return 0;
     328
     329                auto loc = base.getloc();
     330                const auto& ct = use_facet<ctype<char_type>>(loc);
     331
     332                size_t i{};
     333                if (*in == '+' || *in == '-')
     334                    base.buffer_[i++] = *in++;
     335
     336                while (in != end && i < ios_base::buffer_size_ - 1)
     337                {
     338                    auto c = *in;
     339                    if (ct.is(ctype_base::digit, c))
     340                    {
     341                        ++in;
     342                        base.buffer_[i++] = c;
     343                    }
     344                    else
     345                        break;
     346                }
     347                base.buffer_[i] = '\0';
     348
     349                return i;
    186350            }
    187351    };
Note: See TracChangeset for help on using the changeset viewer.