Changeset ccf7a7e in mainline
- Timestamp:
- 2018-07-05T21:41:19Z (7 years ago)
- 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)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/impl/locale.hpp
r7258487 rccf7a7e 30 30 #define LIBCPP_LOCALE 31 31 32 #include <cctype>33 32 #include <cstdlib> 33 #include <ios> 34 34 #include <iosfwd> 35 35 #include <string> 36 36 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 37 43 namespace std 38 44 { 39 40 45 /** 41 46 * Note: This is a very simplistic implementation of <locale>. … … 45 50 * in the future, TODO: implement :) 46 51 */ 47 48 namespace aux49 {50 class facet51 {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 id62 {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_base76 {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_base100 {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) const108 {109 return do_is(m, c);110 }111 112 const char_type* is(const char_type* low, const char_type* high,113 mask* vec) const114 {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) const120 {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) const126 {127 return do_scan_not(m, low, high);128 }129 130 char_type toupper(char_type c) const131 {132 return do_toupper(c);133 }134 135 const char_type* toupper(char_type* low, const char_type* high) const136 {137 return do_toupper(low, high);138 }139 140 char_type tolower(char_type c) const141 {142 return do_tolower(c);143 }144 145 const char_type* tolower(char_type* low, const char_type* high) const146 {147 return do_tolower(low, high);148 }149 150 char_type widen(char c) const151 {152 return do_widen(c);153 }154 155 const char_type* widen(const char* low, const char* high, char_type* to) const156 {157 return do_widen(low, high, to);158 }159 160 char narrow(char_type c, char def) const161 {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) const167 {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 the175 * ISO C++ Standard this function is protected (because176 * the instances are reference counted, but in our design177 * 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) const184 {185 // TODO: implement186 return false;187 }188 189 virtual const char_type* do_is(const char_type* low, const char_type high,190 mask m) const191 {192 // TODO: implement193 return high;194 }195 196 virtual const char_type* do_scan_is(mask m, const char_type* low,197 const char_type* high) const198 {199 // TODO: implement200 return high;201 }202 203 virtual const char_type* do_scan_not(mask m, const char_type* low,204 const char_type* high) const205 {206 // TODO: implement207 return low;208 }209 210 virtual char_type do_toupper(char_type c) const211 {212 // TODO: implement213 return c;214 }215 216 virtual const char_type* do_toupper(char_type* low, const char_type* high) const217 {218 // TODO: implement219 return high;220 }221 222 virtual char_type do_tolower(char_type c) const223 {224 // TODO: implement225 return c;226 }227 228 virtual const char_type* do_tolower(char_type* low, const char_type* high) const229 {230 // TODO: implement231 return high;232 }233 234 virtual char_type do_widen(char c) const235 {236 // TODO: implement237 return c;238 }239 240 virtual const char_type* do_widen(const char* low, const char* high,241 char_type* dest) const242 {243 // TODO: implement244 return high;245 }246 247 virtual char do_narrow(char_type c, char def) const248 {249 // TODO: implement250 return c;251 }252 253 virtual const char_type* do_narrow(const char_type* low, const char_type* high,254 char def, char* dest) const255 {256 // TODO: implement257 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_base291 {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) const299 {300 return do_is(m, c);301 }302 303 const char_type* is(const char_type* low, const char_type* high,304 mask* vec) const305 {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) const311 {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) const317 {318 return do_scan_not(m, low, high);319 }320 321 char_type toupper(char_type c) const322 {323 return do_toupper(c);324 }325 326 const char_type* toupper(char_type* low, const char_type* high) const327 {328 return do_toupper(low, high);329 }330 331 char_type tolower(char_type c) const332 {333 return do_tolower(c);334 }335 336 const char_type* tolower(char_type* low, const char_type* high) const337 {338 return do_tolower(low, high);339 }340 341 char_type widen(char c) const342 {343 return do_widen(c);344 }345 346 const char_type* widen(const char* low, const char* high, char_type* to) const347 {348 return do_widen(low, high, to);349 }350 351 char narrow(char_type c, char def) const352 {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) const358 {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 noexcept366 {367 return classic_table();368 }369 370 static const mask* classic_table() noexcept371 {372 return classic_table_;373 }374 375 ~ctype() = default;376 377 protected:378 virtual bool do_is(mask m, char_type c) const379 {380 // TODO: implement, this is a dummy381 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) const396 {397 // TODO: implement398 return high;399 }400 401 virtual const char_type* do_scan_is(mask m, const char_type* low,402 const char_type* high) const403 {404 // TODO: implement405 return high;406 }407 408 virtual const char_type* do_scan_not(mask m, const char_type* low,409 const char_type* high) const410 {411 // TODO: implement412 return high;413 }414 415 virtual char_type do_toupper(char_type c) const416 {417 return std::toupper(c);418 }419 420 virtual const char_type* do_toupper(char_type* low, const char_type* high) const421 {422 while (low != high)423 *low = std::toupper(*low);424 425 return high;426 }427 428 virtual char_type do_tolower(char_type c) const429 {430 return std::tolower(c);431 }432 433 virtual const char_type* do_tolower(char_type* low, const char_type* high) const434 {435 while (low != high)436 *low = std::tolower(*low);437 438 return high;439 }440 441 virtual char_type do_widen(char c) const442 {443 return c;444 }445 446 virtual const char_type* do_widen(const char* low, const char* high,447 char_type* dest) const448 {449 while (low != high)450 *dest++ = *low++;451 452 return high;453 }454 455 virtual char do_narrow(char_type c, char def) const456 {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) const462 {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_base475 {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) const483 {484 return do_is(m, c);485 }486 487 const char_type* is(const char_type* low, const char_type* high,488 mask* vec) const489 {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) const495 {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) const501 {502 return do_scan_not(m, low, high);503 }504 505 char_type toupper(char_type c) const506 {507 return do_toupper(c);508 }509 510 const char_type* toupper(char_type* low, const char_type* high) const511 {512 return do_toupper(low, high);513 }514 515 char_type tolower(char_type c) const516 {517 return do_tolower(c);518 }519 520 const char_type* tolower(char_type* low, const char_type* high) const521 {522 return do_tolower(low, high);523 }524 525 char_type widen(char c) const526 {527 return do_widen(c);528 }529 530 const char_type* widen(const char* low, const char* high, char_type* to) const531 {532 return do_widen(low, high, to);533 }534 535 char narrow(char_type c, char def) const536 {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) const542 {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 noexcept550 {551 return classic_table();552 }553 554 static const mask* classic_table() noexcept555 {556 return classic_table_;557 }558 559 ~ctype() = default;560 561 protected:562 virtual bool do_is(mask m, char_type c) const563 {564 // TODO: implement565 return false;566 }567 568 virtual const char_type* do_is(const char_type* low, const char_type* high,569 mask* m) const570 {571 // TODO: implement572 return high;573 }574 575 virtual const char_type* do_scan_is(mask m, const char_type* low,576 const char_type* high) const577 {578 // TODO: implement579 return high;580 }581 582 virtual const char_type* do_scan_not(mask m, const char_type* low,583 const char_type* high) const584 {585 // TODO: implement586 return high;587 }588 589 virtual char_type do_toupper(char_type c) const590 {591 // TODO: implement592 return c;593 }594 595 virtual const char_type* do_toupper(char_type* low, const char_type* high) const596 {597 // TODO: implement598 return high;599 }600 601 virtual char_type do_tolower(char_type c) const602 {603 // TODO: implement604 return c;605 }606 607 virtual const char_type* do_tolower(char_type* low, const char_type* high) const608 {609 // TODO: implement610 return high;611 }612 613 virtual char_type do_widen(char c) const614 {615 // TODO: implement616 return c;617 }618 619 virtual const char_type* do_widen(const char* low, const char* high,620 char_type* dest) const621 {622 // TODO: implement623 return dest;624 }625 626 virtual char do_narrow(char_type c, char def) const627 {628 // TODO: implement629 return c;630 }631 632 virtual const char_type* do_narrow(const char_type* low, const char_type* high,633 char def, char* dest) const634 {635 // TODO: implement636 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_base648 {649 public:650 enum result651 {652 ok, partial, error, noconv653 };654 };655 656 template<class Intern, class Extern, class State>657 class codecvt: public codecvt_base658 {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) const670 {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) const676 {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) const683 {684 return do_in(state, from, from_end, from_next, to, to_end, to_next);685 }686 687 int encoding() const noexcept688 {689 return do_encoding();690 }691 692 bool always_noconv() const noexcept693 {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) const699 {700 return do_length(state, from, end, max);701 }702 703 int max_length() const noexcept704 {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) const716 {717 // TODO: implement718 return error;719 }720 721 virtual result do_unshift(state_type& state, extern_type* to, extern_type* to_end,722 extern_type*& to_next) const723 {724 // TODO: implement725 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) const731 {732 // TODO: implement733 return error;734 }735 736 virtual int do_encoding() const noexcept737 {738 // TODO: implement739 return 0;740 }741 742 virtual bool do_always_noconv() const noexcept743 {744 // TODO: implement745 return false;746 }747 748 virtual int do_length(state_type& state, const extern_type* from, const extern_type* end,749 size_t max) const750 {751 // TODO: implement752 return 0;753 }754 755 virtual int do_max_length() const noexcept756 {757 // TODO: implement758 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 locale788 {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) const830 {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) const842 {843 // TODO: define outside locale844 /* 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 main880 * 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 }913 52 914 53 /**
Note:
See TracChangeset
for help on using the changeset viewer.