Changeset ccf7a7e 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:
42ed4855
Parents:
7258487
git-author:
Dzejrou <dzejrou@…> (2017-12-04 15:55:00)
git-committer:
Dzejrou <dzejrou@…> (2018-07-05 21:41:19)
Message:

cpp: moved most of <locale> out because of dependencies inside the stdlib

File:
1 edited

Legend:

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

    r7258487 rccf7a7e  
    3030#define LIBCPP_LOCALE
    3131
    32 #include <cctype>
    3332#include <cstdlib>
     33#include <ios>
    3434#include <iosfwd>
    3535#include <string>
    3636
     37#include <internal/locale.hpp>
     38#include <internal/locale/ctype.hpp>
     39#include <internal/locale/num_get.hpp>
     40#include <internal/locale/num_put.hpp>
     41#include <internal/locale/numpunct.hpp>
     42
    3743namespace std
    3844{
    39 
    4045    /**
    4146     * Note: This is a very simplistic implementation of <locale>.
     
    4550     *       in the future, TODO: implement :)
    4651     */
    47 
    48     namespace aux
    49     {
    50         class facet
    51         {
    52             protected:
    53                 explicit facet(size_t refs = 0);
    54 
    55                 virtual ~facet();
    56 
    57                 facet(const facet&) = delete;
    58                 void operator=(const facet&) = delete;
    59         };
    60 
    61         class id
    62         {
    63             public:
    64                 id() = default;
    65 
    66                 id(const id&) = delete;
    67                 void operator=(const id&) = delete;
    68         };
    69     }
    70 
    71     /**
    72      * 22.4.1, the type category:
    73      */
    74 
    75     class ctype_base
    76     {
    77         public:
    78             using mask = uint16_t;
    79 
    80             static constexpr mask space  = 0b00'0000'0001;
    81             static constexpr mask print  = 0b00'0000'0010;
    82             static constexpr mask cntrl  = 0b00'0000'0100;
    83             static constexpr mask upper  = 0b00'0000'1000;
    84             static constexpr mask lower  = 0b00'0001'0000;
    85             static constexpr mask alpha  = 0b00'0010'0000;
    86             static constexpr mask digit  = 0b00'0100'0000;
    87             static constexpr mask punct  = 0b00'1000'0000;
    88             static constexpr mask xdigit = 0b01'0000'0000;
    89             static constexpr mask blank  = 0b10'0000'0000;
    90             static constexpr mask alnum  = alpha | digit;
    91             static constexpr mask graph  = alnum | punct;
    92     };
    93 
    94     /**
    95      * 22.4.1.1, class template ctype:
    96      */
    97 
    98     template<class Char>
    99     class ctype: public aux::facet, public ctype_base
    100     {
    101         public:
    102             using char_type = Char;
    103 
    104             explicit ctype(size_t)
    105             { /* DUMMY BODY */ }
    106 
    107             bool is(mask m, char_type c) const
    108             {
    109                 return do_is(m, c);
    110             }
    111 
    112             const char_type* is(const char_type* low, const char_type* high,
    113                                 mask* vec) const
    114             {
    115                 return do_is(low, high, vec);
    116             }
    117 
    118             const char_type* scan_is(mask m, const char_type* low,
    119                                      const char_type* high) const
    120             {
    121                 return do_scan_is(m, low, high);
    122             }
    123 
    124             const char_type* scan_not(mask m, const char_type* low,
    125                                       const char_type* high) const
    126             {
    127                 return do_scan_not(m, low, high);
    128             }
    129 
    130             char_type toupper(char_type c) const
    131             {
    132                 return do_toupper(c);
    133             }
    134 
    135             const char_type* toupper(char_type* low, const char_type* high) const
    136             {
    137                 return do_toupper(low, high);
    138             }
    139 
    140             char_type tolower(char_type c) const
    141             {
    142                 return do_tolower(c);
    143             }
    144 
    145             const char_type* tolower(char_type* low, const char_type* high) const
    146             {
    147                 return do_tolower(low, high);
    148             }
    149 
    150             char_type widen(char c) const
    151             {
    152                 return do_widen(c);
    153             }
    154 
    155             const char_type* widen(const char* low, const char* high, char_type* to) const
    156             {
    157                 return do_widen(low, high, to);
    158             }
    159 
    160             char narrow(char_type c, char def) const
    161             {
    162                 return do_narrow(c, def);
    163             }
    164 
    165             const char_type* narrow(const char_type* low, const char_type* high,
    166                                     char def, char* to) const
    167             {
    168                 return do_narrow(low, high, def, to);
    169             }
    170 
    171             static aux::id id;
    172 
    173             /**
    174              * Note: This is a deviation from the standard, because in the
    175              *       ISO C++ Standard this function is protected (because
    176              *       the instances are reference counted, but in our design
    177              *       they are not and as such we did this change).
    178              *       (This applies to all constructors of all facets.)
    179              */
    180             ~ctype() = default;
    181 
    182         protected:
    183             virtual bool do_is(mask m, char_type c) const
    184             {
    185                 // TODO: implement
    186                 return false;
    187             }
    188 
    189             virtual const char_type* do_is(const char_type* low, const char_type high,
    190                                            mask m) const
    191             {
    192                 // TODO: implement
    193                 return high;
    194             }
    195 
    196             virtual const char_type* do_scan_is(mask m, const char_type* low,
    197                                                 const char_type* high) const
    198             {
    199                 // TODO: implement
    200                 return high;
    201             }
    202 
    203             virtual const char_type* do_scan_not(mask m, const char_type* low,
    204                                                  const char_type* high) const
    205             {
    206                 // TODO: implement
    207                 return low;
    208             }
    209 
    210             virtual char_type do_toupper(char_type c) const
    211             {
    212                 // TODO: implement
    213                 return c;
    214             }
    215 
    216             virtual const char_type* do_toupper(char_type* low, const char_type* high) const
    217             {
    218                 // TODO: implement
    219                 return high;
    220             }
    221 
    222             virtual char_type do_tolower(char_type c) const
    223             {
    224                 // TODO: implement
    225                 return c;
    226             }
    227 
    228             virtual const char_type* do_tolower(char_type* low, const char_type* high) const
    229             {
    230                 // TODO: implement
    231                 return high;
    232             }
    233 
    234             virtual char_type do_widen(char c) const
    235             {
    236                 // TODO: implement
    237                 return c;
    238             }
    239 
    240             virtual const char_type* do_widen(const char* low, const char* high,
    241                                               char_type* dest) const
    242             {
    243                 // TODO: implement
    244                 return high;
    245             }
    246 
    247             virtual char do_narrow(char_type c, char def) const
    248             {
    249                 // TODO: implement
    250                 return c;
    251             }
    252 
    253             virtual const char_type* do_narrow(const char_type* low, const char_type* high,
    254                                                char def, char* dest) const
    255             {
    256                 // TODO: implement
    257                 return high;
    258             }
    259     };
    260 
    261     template<class Char>
    262     aux::id ctype<Char>::id{};
    263 
    264     /**
    265      * 22.4.1.2, class template ctype_byname:
    266      * Note: Dummy, TODO: implement.
    267      */
    268 
    269     template<class Char>
    270     class ctype_byname: public ctype<Char>
    271     {
    272         public:
    273             using mask = typename ctype<Char>::mask;
    274 
    275             explicit ctype_byname(const char* name, size_t = 0)
    276             { /* DUMMY BODY */ }
    277 
    278             explicit ctype_byname(const string& name, size_t = 0)
    279             { /* DUMMY BODY */ }
    280 
    281         protected:
    282             ~ctype_byname() = default;
    283     };
    284 
    285     /**
    286      * 22.4.1.3, ctype specialziations:
    287      */
    288 
    289     template<>
    290     class ctype<char>: public aux::facet, public ctype_base
    291     {
    292         public:
    293             using char_type = char;
    294 
    295             explicit ctype(const mask* tab = nullptr, bool del = false, size_t = 0)
    296             { /* DUMMY BODY */ }
    297 
    298             bool is(mask m, char_type c) const
    299             {
    300                 return do_is(m, c);
    301             }
    302 
    303             const char_type* is(const char_type* low, const char_type* high,
    304                                 mask* vec) const
    305             {
    306                 return do_is(low, high, vec);
    307             }
    308 
    309             const char_type* scan_is(mask m, const char_type* low,
    310                                      const char_type* high) const
    311             {
    312                 return do_scan_is(m, low, high);
    313             }
    314 
    315             const char_type* scan_not(mask m, const char_type* low,
    316                                       const char_type* high) const
    317             {
    318                 return do_scan_not(m, low, high);
    319             }
    320 
    321             char_type toupper(char_type c) const
    322             {
    323                 return do_toupper(c);
    324             }
    325 
    326             const char_type* toupper(char_type* low, const char_type* high) const
    327             {
    328                 return do_toupper(low, high);
    329             }
    330 
    331             char_type tolower(char_type c) const
    332             {
    333                 return do_tolower(c);
    334             }
    335 
    336             const char_type* tolower(char_type* low, const char_type* high) const
    337             {
    338                 return do_tolower(low, high);
    339             }
    340 
    341             char_type widen(char c) const
    342             {
    343                 return do_widen(c);
    344             }
    345 
    346             const char_type* widen(const char* low, const char* high, char_type* to) const
    347             {
    348                 return do_widen(low, high, to);
    349             }
    350 
    351             char narrow(char_type c, char def) const
    352             {
    353                 return do_narrow(c, def);
    354             }
    355 
    356             const char_type* narrow(const char_type* low, const char_type* high,
    357                                     char def, char* to) const
    358             {
    359                 return do_narrow(low, high, def, to);
    360             }
    361 
    362             static aux::id id;
    363             static const size_t table_size{0};
    364 
    365             const mask* table() const noexcept
    366             {
    367                 return classic_table();
    368             }
    369 
    370             static const mask* classic_table() noexcept
    371             {
    372                 return classic_table_;
    373             }
    374 
    375             ~ctype() = default;
    376 
    377         protected:
    378             virtual bool do_is(mask m, char_type c) const
    379             {
    380                 // TODO: implement, this is a dummy
    381                 if ((m & space) != 0 && std::isspace(c))
    382                     return true;
    383                 else if ((m & alpha) != 0 && std::isalpha(c))
    384                     return true;
    385                 else if ((m & upper) != 0 && std::isupper(c))
    386                     return true;
    387                 else if ((m & lower) != 0 && std::islower(c))
    388                     return true;
    389                 else if ((m & digit) != 0 && std::isdigit(c))
    390                     return true;
    391                 return false;
    392             }
    393 
    394             virtual const char_type* do_is(const char_type* low, const char_type* high,
    395                                            mask* m) const
    396             {
    397                 // TODO: implement
    398                 return high;
    399             }
    400 
    401             virtual const char_type* do_scan_is(mask m, const char_type* low,
    402                                                 const char_type* high) const
    403             {
    404                 // TODO: implement
    405                 return high;
    406             }
    407 
    408             virtual const char_type* do_scan_not(mask m, const char_type* low,
    409                                                  const char_type* high) const
    410             {
    411                 // TODO: implement
    412                 return high;
    413             }
    414 
    415             virtual char_type do_toupper(char_type c) const
    416             {
    417                 return std::toupper(c);
    418             }
    419 
    420             virtual const char_type* do_toupper(char_type* low, const char_type* high) const
    421             {
    422                 while (low != high)
    423                     *low = std::toupper(*low);
    424 
    425                 return high;
    426             }
    427 
    428             virtual char_type do_tolower(char_type c) const
    429             {
    430                 return std::tolower(c);
    431             }
    432 
    433             virtual const char_type* do_tolower(char_type* low, const char_type* high) const
    434             {
    435                 while (low != high)
    436                     *low = std::tolower(*low);
    437 
    438                 return high;
    439             }
    440 
    441             virtual char_type do_widen(char c) const
    442             {
    443                 return c;
    444             }
    445 
    446             virtual const char_type* do_widen(const char* low, const char* high,
    447                                               char_type* dest) const
    448             {
    449                 while (low != high)
    450                     *dest++ = *low++;
    451 
    452                 return high;
    453             }
    454 
    455             virtual char do_narrow(char_type c, char def) const
    456             {
    457                 return c;
    458             }
    459 
    460             virtual const char_type* do_narrow(const char_type* low, const char_type* high,
    461                                                char def, char* dest) const
    462             {
    463                 while (low != high)
    464                     *dest++ = *low++;
    465 
    466                 return high;
    467             }
    468 
    469         private:
    470             static constexpr mask* classic_table_{nullptr};
    471     };
    472 
    473     template<>
    474     class ctype<wchar_t>: public aux::facet, public ctype_base
    475     {
    476         public:
    477             using char_type = wchar_t;
    478 
    479             explicit ctype(const mask* tab = nullptr, bool del = false, size_t = 0)
    480             { /* DUMMY BODY */ }
    481 
    482             bool is(mask m, char_type c) const
    483             {
    484                 return do_is(m, c);
    485             }
    486 
    487             const char_type* is(const char_type* low, const char_type* high,
    488                                 mask* vec) const
    489             {
    490                 return do_is(low, high, vec);
    491             }
    492 
    493             const char_type* scan_is(mask m, const char_type* low,
    494                                      const char_type* high) const
    495             {
    496                 return do_scan_is(m, low, high);
    497             }
    498 
    499             const char_type* scan_not(mask m, const char_type* low,
    500                                       const char_type* high) const
    501             {
    502                 return do_scan_not(m, low, high);
    503             }
    504 
    505             char_type toupper(char_type c) const
    506             {
    507                 return do_toupper(c);
    508             }
    509 
    510             const char_type* toupper(char_type* low, const char_type* high) const
    511             {
    512                 return do_toupper(low, high);
    513             }
    514 
    515             char_type tolower(char_type c) const
    516             {
    517                 return do_tolower(c);
    518             }
    519 
    520             const char_type* tolower(char_type* low, const char_type* high) const
    521             {
    522                 return do_tolower(low, high);
    523             }
    524 
    525             char_type widen(char c) const
    526             {
    527                 return do_widen(c);
    528             }
    529 
    530             const char_type* widen(const char* low, const char* high, char_type* to) const
    531             {
    532                 return do_widen(low, high, to);
    533             }
    534 
    535             char narrow(char_type c, char def) const
    536             {
    537                 return do_narrow(c, def);
    538             }
    539 
    540             const char_type* narrow(const char_type* low, const char_type* high,
    541                                     char def, char* to) const
    542             {
    543                 return do_narrow(low, high, def, to);
    544             }
    545 
    546             static aux::id id;
    547             static const size_t table_size{0};
    548 
    549             const mask* table() const noexcept
    550             {
    551                 return classic_table();
    552             }
    553 
    554             static const mask* classic_table() noexcept
    555             {
    556                 return classic_table_;
    557             }
    558 
    559             ~ctype() = default;
    560 
    561         protected:
    562             virtual bool do_is(mask m, char_type c) const
    563             {
    564                 // TODO: implement
    565                 return false;
    566             }
    567 
    568             virtual const char_type* do_is(const char_type* low, const char_type* high,
    569                                            mask* m) const
    570             {
    571                 // TODO: implement
    572                 return high;
    573             }
    574 
    575             virtual const char_type* do_scan_is(mask m, const char_type* low,
    576                                                 const char_type* high) const
    577             {
    578                 // TODO: implement
    579                 return high;
    580             }
    581 
    582             virtual const char_type* do_scan_not(mask m, const char_type* low,
    583                                                  const char_type* high) const
    584             {
    585                 // TODO: implement
    586                 return high;
    587             }
    588 
    589             virtual char_type do_toupper(char_type c) const
    590             {
    591                 // TODO: implement
    592                 return c;
    593             }
    594 
    595             virtual const char_type* do_toupper(char_type* low, const char_type* high) const
    596             {
    597                 // TODO: implement
    598                 return high;
    599             }
    600 
    601             virtual char_type do_tolower(char_type c) const
    602             {
    603                 // TODO: implement
    604                 return c;
    605             }
    606 
    607             virtual const char_type* do_tolower(char_type* low, const char_type* high) const
    608             {
    609                 // TODO: implement
    610                 return high;
    611             }
    612 
    613             virtual char_type do_widen(char c) const
    614             {
    615                 // TODO: implement
    616                 return c;
    617             }
    618 
    619             virtual const char_type* do_widen(const char* low, const char* high,
    620                                               char_type* dest) const
    621             {
    622                 // TODO: implement
    623                 return dest;
    624             }
    625 
    626             virtual char do_narrow(char_type c, char def) const
    627             {
    628                 // TODO: implement
    629                 return c;
    630             }
    631 
    632             virtual const char_type* do_narrow(const char_type* low, const char_type* high,
    633                                                char def, char* dest) const
    634             {
    635                 // TODO: implement
    636                 return high;
    637             }
    638 
    639         private:
    640             static constexpr mask* classic_table_{nullptr};
    641     };
    642 
    643     /**
    644      * 22.4.1.4, class template codecvt:
    645      */
    646 
    647     class codecvt_base
    648     {
    649         public:
    650             enum result
    651             {
    652                 ok, partial, error, noconv
    653             };
    654     };
    655 
    656     template<class Intern, class Extern, class State>
    657     class codecvt: public codecvt_base
    658     {
    659         public:
    660             using intern_type = Intern;
    661             using extern_type = Extern;
    662             using state_type  = State;
    663 
    664             explicit codecvt(size_t = 0)
    665             { /* DUMMY BODY */ }
    666 
    667             result out(state_type& state, const intern_type* from, const intern_type* from_end,
    668                        const intern_type*& from_next, extern_type* to, extern_type* to_end,
    669                        extern_type*& to_next) const
    670             {
    671                 return do_out(state, from, from_end, from_next, to, to_end, to_next);
    672             }
    673 
    674             result unshift(state_type& state, extern_type* to, extern_type* to_end,
    675                            extern_type*& to_next) const
    676             {
    677                 return do_unshift(state, to, to_end, to_next);
    678             }
    679 
    680             result in(state_type& state, const extern_type* from, const extern_type* from_end,
    681                       const extern_type*& from_next, intern_type* to, intern_type* to_end,
    682                       intern_type*& to_next) const
    683             {
    684                 return do_in(state, from, from_end, from_next, to, to_end, to_next);
    685             }
    686 
    687             int encoding() const noexcept
    688             {
    689                 return do_encoding();
    690             }
    691 
    692             bool always_noconv() const noexcept
    693             {
    694                 return do_always_noconv();
    695             }
    696 
    697             int length(state_type& state, const extern_type* from, const extern_type* end,
    698                        size_t max) const
    699             {
    700                 return do_length(state, from, end, max);
    701             }
    702 
    703             int max_length() const noexcept
    704             {
    705                 return do_max_length();
    706             }
    707 
    708             static aux::id id;
    709 
    710             ~codecvt() = default;
    711 
    712         protected:
    713             virtual result do_out(state_type& state, const intern_type* from, const intern_type* from_end,
    714                                   const intern_type*& from_next, extern_type* to, extern_type* to_end,
    715                                   extern_type*& to_next) const
    716             {
    717                 // TODO: implement
    718                 return error;
    719             }
    720 
    721             virtual result do_unshift(state_type& state, extern_type* to, extern_type* to_end,
    722                                       extern_type*& to_next) const
    723             {
    724                 // TODO: implement
    725                 return error;
    726             }
    727 
    728             virtual result do_in(state_type& state, const extern_type* from, const extern_type* from_end,
    729                                  const extern_type*& from_next, intern_type* to, intern_type* to_end,
    730                                  intern_type*& to_next) const
    731             {
    732                 // TODO: implement
    733                 return error;
    734             }
    735 
    736             virtual int do_encoding() const noexcept
    737             {
    738                 // TODO: implement
    739                 return 0;
    740             }
    741 
    742             virtual bool do_always_noconv() const noexcept
    743             {
    744                 // TODO: implement
    745                 return false;
    746             }
    747 
    748             virtual int do_length(state_type& state, const extern_type* from, const extern_type* end,
    749                                   size_t max) const
    750             {
    751                 // TODO: implement
    752                 return 0;
    753             }
    754 
    755             virtual int do_max_length() const noexcept
    756             {
    757                 // TODO: implement
    758                 return 0;
    759             }
    760     };
    761 
    762     template<class Intern, class Extern, class State>
    763     aux::id codecvt<Intern, Extern, State>::id{};
    764 
    765     /**
    766      * 22.4.1.5, class template codecvt_byname:
    767      * Note: Dummy, TODO: implement.
    768      */
    769 
    770     template<class Intern, class Extern, class State>
    771     class codecvt_byname: public codecvt<Intern, Extern, State>
    772     {
    773         public:
    774             explicit codecvt_byname(const char*, size_t = 0)
    775             { /* DUMMY BODY */ }
    776 
    777             explicit codecvt_byname(const string&, size_t = 0)
    778             { /* DUMMY BODY */ }
    779 
    780             ~codecvt_byname() = default;
    781     };
    782 
    783     /**
    784      * 22.3.1, class locale:
    785      */
    786 
    787     class locale
    788     {
    789         public:
    790             using facet = aux::facet;
    791             using id    = aux::id;
    792 
    793             using category = int;
    794 
    795             static const category none     = 0b000'0001;
    796             static const category collate  = 0b000'0010;
    797             static const category ctype    = 0b000'0100;
    798             static const category monetary = 0b000'1000;
    799             static const category numeric  = 0b001'0000;
    800             static const category time     = 0b010'0000;
    801             static const category messages = 0b100'0000;
    802             static const category all      = collate | ctype | monetary |
    803                                              numeric | time | messages;
    804 
    805             locale() noexcept;
    806 
    807             locale(const locale& other) noexcept;
    808 
    809             explicit locale(const char* name);
    810 
    811             explicit locale(const string& name);
    812 
    813             locale(const locale& other, const char* name, category);
    814 
    815             locale(const locale& other, const string& name, category);
    816 
    817             template<class Facet>
    818             locale(const locale& other, Facet* f)
    819                 : name_{other.name_}
    820             { /* DUMMY BODY */ }
    821 
    822             locale(const locale& other, const locale& one, category);
    823 
    824             ~locale() = default;
    825 
    826             const locale& operator=(const locale& other) noexcept;
    827 
    828             template<class Facet>
    829             locale combine(const locale& other) const
    830             {
    831                 return other;
    832             }
    833 
    834             string name() const;
    835 
    836             bool operator==(const locale& other) const;
    837             bool operator!=(const locale& other) const;
    838 
    839             template<class Char, class Traits, class Allocator>
    840             bool operator()(const basic_string<Char, Traits, Allocator>& s1,
    841                             const basic_string<Char, Traits, Allocator>& s2) const
    842             {
    843                 // TODO: define outside locale
    844                 /* return use_facet<collate<Char>>(*this).compare( */
    845                 /*     s1.begin(), s1.end(), s2.begin(), s2.end() */
    846                 /* ) < 0; */
    847                 return false;
    848             }
    849 
    850             static locale global(const locale&)
    851             {
    852                 return *the_locale_;
    853             }
    854 
    855             static const locale& classic()
    856             {
    857                 return *the_locale_;
    858             }
    859 
    860         private:
    861             string name_;
    862 
    863             // TODO: implement the_locale_
    864             static constexpr locale* the_locale_{nullptr};
    865 
    866             template<class Facet>
    867             friend bool has_facet(const locale&);
    868 
    869             template<class Facet>
    870             bool has_()
    871             { // Our single locale atm has all facets.
    872                 return true;
    873             }
    874 
    875             template<class Facet>
    876             friend const Facet& use_facet(const locale&);
    877 
    878             /**
    879              * Note: We store all of the facets in the main
    880              *       locale.
    881              */
    882 
    883             template<class Facet>
    884             const Facet& get_();
    885 
    886             std::ctype<char> ctype_char_{};
    887             std::ctype<wchar_t> ctype_wchar_{};
    888     };
    889 
    890     template<>
    891     const ctype<char>& locale::get_<ctype<char>>()
    892     {
    893         return ctype_char_;
    894     }
    895 
    896     template<>
    897     const ctype<wchar_t>& locale::get_<ctype<wchar_t>>()
    898     {
    899         return ctype_wchar_;
    900     }
    901 
    902     template<class Facet>
    903     const Facet& use_facet(const locale& loc)
    904     {
    905         return loc.get_<Facet>();
    906     }
    907 
    908     template<class Facet>
    909     bool has_facet(const locale& loc)
    910     {
    911         return loc.has_<Facet>();
    912     }
    91352
    91453    /**
Note: See TracChangeset for help on using the changeset viewer.