Changeset 0b4b81c in mainline


Ignore:
Timestamp:
2018-07-05T21:41:18Z (6 years ago)
Author:
Dzejrou <dzejrou@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6648ab33
Parents:
6702d7e
git-author:
Jaroslav Jindrak <dzejrou@…> (2017-11-08 21:23:49)
git-committer:
Dzejrou <dzejrou@…> (2018-07-05 21:41:18)
Message:

cpp: added some more dummy locale implementations

Location:
uspace/lib/cpp
Files:
1 added
1 edited

Legend:

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

    r6702d7e r0b4b81c  
    3030#define LIBCPP_LOCALE
    3131
     32#include <cctype>
     33#include <cstdlib>
     34#include <iosfwd>
     35#include <string>
     36
    3237namespace std
    3338{
     39
     40    /**
     41     * Note: This is a very simplistic implementation of <locale>.
     42     *       We have a single locale that has all of its facets.
     43     *       This should behave correctly on the outside but will prevent
     44     *       us from using multiple locales so if that becomes necessary
     45     *       in the future, TODO: implement :)
     46     */
     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
    34787    class locale
    35788    {
    36         // TODO: implement
     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_{};
    37888    };
     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    }
     913
     914    /**
     915     * 22.3.3, convenience interfaces:
     916     */
     917
     918    /**
     919     * 22.3.3.1, character classification:
     920     */
     921
     922    template<class Char>
     923    bool isspace(Char c, const locale& loc)
     924    {
     925        return use_facet<ctype<Char>>(loc).is(ctype_base::space, c);
     926    }
     927
     928    template<class Char>
     929    bool isprint(Char c, const locale& loc)
     930    {
     931        return use_facet<ctype<Char>>(loc).is(ctype_base::print, c);
     932    }
     933
     934    template<class Char>
     935    bool iscntrl(Char c, const locale& loc)
     936    {
     937        return use_facet<ctype<Char>>(loc).is(ctype_base::cntrl, c);
     938    }
     939
     940    template<class Char>
     941    bool isupper(Char c, const locale& loc)
     942    {
     943        return use_facet<ctype<Char>>(loc).is(ctype_base::upper, c);
     944    }
     945
     946    template<class Char>
     947    bool islower(Char c, const locale& loc)
     948    {
     949        return use_facet<ctype<Char>>(loc).is(ctype_base::lower, c);
     950    }
     951
     952    template<class Char>
     953    bool isalpha(Char c, const locale& loc)
     954    {
     955        return use_facet<ctype<Char>>(loc).is(ctype_base::alpha, c);
     956    }
     957
     958    template<class Char>
     959    bool isdigit(Char c, const locale& loc)
     960    {
     961        return use_facet<ctype<Char>>(loc).is(ctype_base::digit, c);
     962    }
     963
     964    template<class Char>
     965    bool ispunct(Char c, const locale& loc)
     966    {
     967        return use_facet<ctype<Char>>(loc).is(ctype_base::punct, c);
     968    }
     969
     970    template<class Char>
     971    bool isxdigit(Char c, const locale& loc)
     972    {
     973        return use_facet<ctype<Char>>(loc).is(ctype_base::xdigit, c);
     974    }
     975
     976    template<class Char>
     977    bool isalnum(Char c, const locale& loc)
     978    {
     979        return use_facet<ctype<Char>>(loc).is(ctype_base::alnum, c);
     980    }
     981
     982    template<class Char>
     983    bool isgraph(Char c, const locale& loc)
     984    {
     985        return use_facet<ctype<Char>>(loc).is(ctype_base::graph, c);
     986    }
     987
     988    template<class Char>
     989    bool isblank(Char c, const locale& loc)
     990    {
     991        return use_facet<ctype<Char>>(loc).is(ctype_base::blank, c);
     992    }
     993
     994    /**
     995     * 22.3.3.2, conversions:
     996     */
     997
     998    /**
     999     * 22.3.3.2.1, character conversions:
     1000     */
     1001
     1002    template<class Char>
     1003    Char toupper(Char c, const locale& loc)
     1004    {
     1005        return use_facet<ctype<Char>>(loc).toupper(c);
     1006    }
     1007
     1008    template<class Char>
     1009    Char tolower(Char c, const locale& loc)
     1010    {
     1011        return use_facet<ctype<Char>>(loc).tolower(c);
     1012    }
     1013
     1014    /**
     1015     * 22.3.3.2.2, string conversions:
     1016     */
     1017
     1018    // TODO: implement
    381019}
    391020
Note: See TracChangeset for help on using the changeset viewer.