locale.cpp 187 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123
  1. //===------------------------- locale.cpp ---------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is dual licensed under the MIT and the University of Illinois Open
  6. // Source Licenses. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "__config"
  10. #if !defined(_LIBCPP_SGX_CONFIG)
  11. // On Solaris, we need to define something to make the C99 parts of localeconv
  12. // visible.
  13. #ifdef __sun__
  14. #define _LCONV_C99
  15. #endif
  16. #include "string"
  17. #include "locale"
  18. #include "codecvt"
  19. #include "vector"
  20. #include "algorithm"
  21. #include "typeinfo"
  22. #ifndef _LIBCPP_NO_EXCEPTIONS
  23. # include "type_traits"
  24. #endif
  25. #include "clocale"
  26. #include "cstring"
  27. #include "cwctype"
  28. #include "__sso_allocator"
  29. #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
  30. #include "support/win32/locale_win32.h"
  31. #elif !defined(__ANDROID__)
  32. #include <langinfo.h>
  33. #endif
  34. #include <stdlib.h>
  35. #include <stdio.h>
  36. // On Linux, wint_t and wchar_t have different signed-ness, and this causes
  37. // lots of noise in the build log, but no bugs that I know of.
  38. #if defined(__clang__)
  39. #pragma clang diagnostic ignored "-Wsign-conversion"
  40. #endif
  41. _LIBCPP_BEGIN_NAMESPACE_STD
  42. #ifdef __cloc_defined
  43. locale_t __cloc() {
  44. // In theory this could create a race condition. In practice
  45. // the race condition is non-fatal since it will just create
  46. // a little resource leak. Better approach would be appreciated.
  47. static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
  48. return result;
  49. }
  50. #endif // __cloc_defined
  51. namespace {
  52. struct release
  53. {
  54. void operator()(locale::facet* p) {p->__release_shared();}
  55. };
  56. template <class T, class A0>
  57. inline
  58. T&
  59. make(A0 a0)
  60. {
  61. static typename aligned_storage<sizeof(T)>::type buf;
  62. ::new (&buf) T(a0);
  63. return *reinterpret_cast<T*>(&buf);
  64. }
  65. template <class T, class A0, class A1>
  66. inline
  67. T&
  68. make(A0 a0, A1 a1)
  69. {
  70. static typename aligned_storage<sizeof(T)>::type buf;
  71. ::new (&buf) T(a0, a1);
  72. return *reinterpret_cast<T*>(&buf);
  73. }
  74. template <class T, class A0, class A1, class A2>
  75. inline
  76. T&
  77. make(A0 a0, A1 a1, A2 a2)
  78. {
  79. static typename aligned_storage<sizeof(T)>::type buf;
  80. ::new (&buf) T(a0, a1, a2);
  81. return *reinterpret_cast<T*>(&buf);
  82. }
  83. template <typename T, size_t N>
  84. inline
  85. _LIBCPP_CONSTEXPR
  86. size_t
  87. countof(const T (&)[N])
  88. {
  89. return N;
  90. }
  91. template <typename T>
  92. inline
  93. _LIBCPP_CONSTEXPR
  94. size_t
  95. countof(const T * const begin, const T * const end)
  96. {
  97. return static_cast<size_t>(end - begin);
  98. }
  99. }
  100. #if defined(_AIX)
  101. // Set priority to INT_MIN + 256 + 150
  102. # pragma priority ( -2147483242 )
  103. #endif
  104. const locale::category locale::none;
  105. const locale::category locale::collate;
  106. const locale::category locale::ctype;
  107. const locale::category locale::monetary;
  108. const locale::category locale::numeric;
  109. const locale::category locale::time;
  110. const locale::category locale::messages;
  111. const locale::category locale::all;
  112. class _LIBCPP_HIDDEN locale::__imp
  113. : public facet
  114. {
  115. enum {N = 28};
  116. #if defined(_LIBCPP_MSVC)
  117. // FIXME: MSVC doesn't support aligned parameters by value.
  118. // I can't get the __sso_allocator to work here
  119. // for MSVC I think for this reason.
  120. vector<facet*> facets_;
  121. #else
  122. vector<facet*, __sso_allocator<facet*, N> > facets_;
  123. #endif
  124. string name_;
  125. public:
  126. explicit __imp(size_t refs = 0);
  127. explicit __imp(const string& name, size_t refs = 0);
  128. __imp(const __imp&);
  129. __imp(const __imp&, const string&, locale::category c);
  130. __imp(const __imp& other, const __imp& one, locale::category c);
  131. __imp(const __imp&, facet* f, long id);
  132. ~__imp();
  133. const string& name() const {return name_;}
  134. bool has_facet(long id) const
  135. {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
  136. const locale::facet* use_facet(long id) const;
  137. static const locale& make_classic();
  138. static locale& make_global();
  139. private:
  140. void install(facet* f, long id);
  141. template <class F> void install(F* f) {install(f, f->id.__get());}
  142. template <class F> void install_from(const __imp& other);
  143. };
  144. locale::__imp::__imp(size_t refs)
  145. : facet(refs),
  146. facets_(N),
  147. name_("C")
  148. {
  149. facets_.clear();
  150. install(&make<_VSTD::collate<char> >(1u));
  151. install(&make<_VSTD::collate<wchar_t> >(1u));
  152. install(&make<_VSTD::ctype<char> >(nullptr, false, 1u));
  153. install(&make<_VSTD::ctype<wchar_t> >(1u));
  154. install(&make<codecvt<char, char, mbstate_t> >(1u));
  155. install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
  156. install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
  157. install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
  158. install(&make<numpunct<char> >(1u));
  159. install(&make<numpunct<wchar_t> >(1u));
  160. install(&make<num_get<char> >(1u));
  161. install(&make<num_get<wchar_t> >(1u));
  162. install(&make<num_put<char> >(1u));
  163. install(&make<num_put<wchar_t> >(1u));
  164. install(&make<moneypunct<char, false> >(1u));
  165. install(&make<moneypunct<char, true> >(1u));
  166. install(&make<moneypunct<wchar_t, false> >(1u));
  167. install(&make<moneypunct<wchar_t, true> >(1u));
  168. install(&make<money_get<char> >(1u));
  169. install(&make<money_get<wchar_t> >(1u));
  170. install(&make<money_put<char> >(1u));
  171. install(&make<money_put<wchar_t> >(1u));
  172. install(&make<time_get<char> >(1u));
  173. install(&make<time_get<wchar_t> >(1u));
  174. install(&make<time_put<char> >(1u));
  175. install(&make<time_put<wchar_t> >(1u));
  176. install(&make<_VSTD::messages<char> >(1u));
  177. install(&make<_VSTD::messages<wchar_t> >(1u));
  178. }
  179. locale::__imp::__imp(const string& name, size_t refs)
  180. : facet(refs),
  181. facets_(N),
  182. name_(name)
  183. {
  184. #ifndef _LIBCPP_NO_EXCEPTIONS
  185. try
  186. {
  187. #endif // _LIBCPP_NO_EXCEPTIONS
  188. facets_ = locale::classic().__locale_->facets_;
  189. for (unsigned i = 0; i < facets_.size(); ++i)
  190. if (facets_[i])
  191. facets_[i]->__add_shared();
  192. install(new collate_byname<char>(name_));
  193. install(new collate_byname<wchar_t>(name_));
  194. install(new ctype_byname<char>(name_));
  195. install(new ctype_byname<wchar_t>(name_));
  196. install(new codecvt_byname<char, char, mbstate_t>(name_));
  197. install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
  198. install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
  199. install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
  200. install(new numpunct_byname<char>(name_));
  201. install(new numpunct_byname<wchar_t>(name_));
  202. install(new moneypunct_byname<char, false>(name_));
  203. install(new moneypunct_byname<char, true>(name_));
  204. install(new moneypunct_byname<wchar_t, false>(name_));
  205. install(new moneypunct_byname<wchar_t, true>(name_));
  206. install(new time_get_byname<char>(name_));
  207. install(new time_get_byname<wchar_t>(name_));
  208. install(new time_put_byname<char>(name_));
  209. install(new time_put_byname<wchar_t>(name_));
  210. install(new messages_byname<char>(name_));
  211. install(new messages_byname<wchar_t>(name_));
  212. #ifndef _LIBCPP_NO_EXCEPTIONS
  213. }
  214. catch (...)
  215. {
  216. for (unsigned i = 0; i < facets_.size(); ++i)
  217. if (facets_[i])
  218. facets_[i]->__release_shared();
  219. throw;
  220. }
  221. #endif // _LIBCPP_NO_EXCEPTIONS
  222. }
  223. // NOTE avoid the `base class should be explicitly initialized in the
  224. // copy constructor` warning emitted by GCC
  225. #if defined(__clang__) || _GNUC_VER >= 406
  226. #pragma GCC diagnostic push
  227. #pragma GCC diagnostic ignored "-Wextra"
  228. #endif
  229. locale::__imp::__imp(const __imp& other)
  230. : facets_(max<size_t>(N, other.facets_.size())),
  231. name_(other.name_)
  232. {
  233. facets_ = other.facets_;
  234. for (unsigned i = 0; i < facets_.size(); ++i)
  235. if (facets_[i])
  236. facets_[i]->__add_shared();
  237. }
  238. #if defined(__clang__) || _GNUC_VER >= 406
  239. #pragma GCC diagnostic pop
  240. #endif
  241. locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
  242. : facets_(N),
  243. name_("*")
  244. {
  245. facets_ = other.facets_;
  246. for (unsigned i = 0; i < facets_.size(); ++i)
  247. if (facets_[i])
  248. facets_[i]->__add_shared();
  249. #ifndef _LIBCPP_NO_EXCEPTIONS
  250. try
  251. {
  252. #endif // _LIBCPP_NO_EXCEPTIONS
  253. if (c & locale::collate)
  254. {
  255. install(new collate_byname<char>(name));
  256. install(new collate_byname<wchar_t>(name));
  257. }
  258. if (c & locale::ctype)
  259. {
  260. install(new ctype_byname<char>(name));
  261. install(new ctype_byname<wchar_t>(name));
  262. install(new codecvt_byname<char, char, mbstate_t>(name));
  263. install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
  264. install(new codecvt_byname<char16_t, char, mbstate_t>(name));
  265. install(new codecvt_byname<char32_t, char, mbstate_t>(name));
  266. }
  267. if (c & locale::monetary)
  268. {
  269. install(new moneypunct_byname<char, false>(name));
  270. install(new moneypunct_byname<char, true>(name));
  271. install(new moneypunct_byname<wchar_t, false>(name));
  272. install(new moneypunct_byname<wchar_t, true>(name));
  273. }
  274. if (c & locale::numeric)
  275. {
  276. install(new numpunct_byname<char>(name));
  277. install(new numpunct_byname<wchar_t>(name));
  278. }
  279. if (c & locale::time)
  280. {
  281. install(new time_get_byname<char>(name));
  282. install(new time_get_byname<wchar_t>(name));
  283. install(new time_put_byname<char>(name));
  284. install(new time_put_byname<wchar_t>(name));
  285. }
  286. if (c & locale::messages)
  287. {
  288. install(new messages_byname<char>(name));
  289. install(new messages_byname<wchar_t>(name));
  290. }
  291. #ifndef _LIBCPP_NO_EXCEPTIONS
  292. }
  293. catch (...)
  294. {
  295. for (unsigned i = 0; i < facets_.size(); ++i)
  296. if (facets_[i])
  297. facets_[i]->__release_shared();
  298. throw;
  299. }
  300. #endif // _LIBCPP_NO_EXCEPTIONS
  301. }
  302. template<class F>
  303. inline
  304. void
  305. locale::__imp::install_from(const locale::__imp& one)
  306. {
  307. long id = F::id.__get();
  308. install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
  309. }
  310. locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
  311. : facets_(N),
  312. name_("*")
  313. {
  314. facets_ = other.facets_;
  315. for (unsigned i = 0; i < facets_.size(); ++i)
  316. if (facets_[i])
  317. facets_[i]->__add_shared();
  318. #ifndef _LIBCPP_NO_EXCEPTIONS
  319. try
  320. {
  321. #endif // _LIBCPP_NO_EXCEPTIONS
  322. if (c & locale::collate)
  323. {
  324. install_from<_VSTD::collate<char> >(one);
  325. install_from<_VSTD::collate<wchar_t> >(one);
  326. }
  327. if (c & locale::ctype)
  328. {
  329. install_from<_VSTD::ctype<char> >(one);
  330. install_from<_VSTD::ctype<wchar_t> >(one);
  331. install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
  332. install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
  333. install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
  334. install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
  335. }
  336. if (c & locale::monetary)
  337. {
  338. install_from<moneypunct<char, false> >(one);
  339. install_from<moneypunct<char, true> >(one);
  340. install_from<moneypunct<wchar_t, false> >(one);
  341. install_from<moneypunct<wchar_t, true> >(one);
  342. install_from<money_get<char> >(one);
  343. install_from<money_get<wchar_t> >(one);
  344. install_from<money_put<char> >(one);
  345. install_from<money_put<wchar_t> >(one);
  346. }
  347. if (c & locale::numeric)
  348. {
  349. install_from<numpunct<char> >(one);
  350. install_from<numpunct<wchar_t> >(one);
  351. install_from<num_get<char> >(one);
  352. install_from<num_get<wchar_t> >(one);
  353. install_from<num_put<char> >(one);
  354. install_from<num_put<wchar_t> >(one);
  355. }
  356. if (c & locale::time)
  357. {
  358. install_from<time_get<char> >(one);
  359. install_from<time_get<wchar_t> >(one);
  360. install_from<time_put<char> >(one);
  361. install_from<time_put<wchar_t> >(one);
  362. }
  363. if (c & locale::messages)
  364. {
  365. install_from<_VSTD::messages<char> >(one);
  366. install_from<_VSTD::messages<wchar_t> >(one);
  367. }
  368. #ifndef _LIBCPP_NO_EXCEPTIONS
  369. }
  370. catch (...)
  371. {
  372. for (unsigned i = 0; i < facets_.size(); ++i)
  373. if (facets_[i])
  374. facets_[i]->__release_shared();
  375. throw;
  376. }
  377. #endif // _LIBCPP_NO_EXCEPTIONS
  378. }
  379. locale::__imp::__imp(const __imp& other, facet* f, long id)
  380. : facets_(max<size_t>(N, other.facets_.size()+1)),
  381. name_("*")
  382. {
  383. f->__add_shared();
  384. unique_ptr<facet, release> hold(f);
  385. facets_ = other.facets_;
  386. for (unsigned i = 0; i < other.facets_.size(); ++i)
  387. if (facets_[i])
  388. facets_[i]->__add_shared();
  389. install(hold.get(), id);
  390. }
  391. locale::__imp::~__imp()
  392. {
  393. for (unsigned i = 0; i < facets_.size(); ++i)
  394. if (facets_[i])
  395. facets_[i]->__release_shared();
  396. }
  397. void
  398. locale::__imp::install(facet* f, long id)
  399. {
  400. f->__add_shared();
  401. unique_ptr<facet, release> hold(f);
  402. if (static_cast<size_t>(id) >= facets_.size())
  403. facets_.resize(static_cast<size_t>(id+1));
  404. if (facets_[static_cast<size_t>(id)])
  405. facets_[static_cast<size_t>(id)]->__release_shared();
  406. facets_[static_cast<size_t>(id)] = hold.release();
  407. }
  408. const locale::facet*
  409. locale::__imp::use_facet(long id) const
  410. {
  411. #ifndef _LIBCPP_NO_EXCEPTIONS
  412. if (!has_facet(id))
  413. throw bad_cast();
  414. #endif // _LIBCPP_NO_EXCEPTIONS
  415. return facets_[static_cast<size_t>(id)];
  416. }
  417. // locale
  418. const locale&
  419. locale::__imp::make_classic()
  420. {
  421. // only one thread can get in here and it only gets in once
  422. static aligned_storage<sizeof(locale)>::type buf;
  423. locale* c = reinterpret_cast<locale*>(&buf);
  424. c->__locale_ = &make<__imp>(1u);
  425. return *c;
  426. }
  427. const locale&
  428. locale::classic()
  429. {
  430. static const locale& c = __imp::make_classic();
  431. return c;
  432. }
  433. locale&
  434. locale::__imp::make_global()
  435. {
  436. // only one thread can get in here and it only gets in once
  437. static aligned_storage<sizeof(locale)>::type buf;
  438. ::new (&buf) locale(locale::classic());
  439. return *reinterpret_cast<locale*>(&buf);
  440. }
  441. locale&
  442. locale::__global()
  443. {
  444. static locale& g = __imp::make_global();
  445. return g;
  446. }
  447. locale::locale() _NOEXCEPT
  448. : __locale_(__global().__locale_)
  449. {
  450. __locale_->__add_shared();
  451. }
  452. locale::locale(const locale& l) _NOEXCEPT
  453. : __locale_(l.__locale_)
  454. {
  455. __locale_->__add_shared();
  456. }
  457. locale::~locale()
  458. {
  459. __locale_->__release_shared();
  460. }
  461. const locale&
  462. locale::operator=(const locale& other) _NOEXCEPT
  463. {
  464. other.__locale_->__add_shared();
  465. __locale_->__release_shared();
  466. __locale_ = other.__locale_;
  467. return *this;
  468. }
  469. locale::locale(const char* name)
  470. #ifndef _LIBCPP_NO_EXCEPTIONS
  471. : __locale_(name ? new __imp(name)
  472. : throw runtime_error("locale constructed with null"))
  473. #else // _LIBCPP_NO_EXCEPTIONS
  474. : __locale_(new __imp(name))
  475. #endif
  476. {
  477. __locale_->__add_shared();
  478. }
  479. locale::locale(const string& name)
  480. : __locale_(new __imp(name))
  481. {
  482. __locale_->__add_shared();
  483. }
  484. locale::locale(const locale& other, const char* name, category c)
  485. #ifndef _LIBCPP_NO_EXCEPTIONS
  486. : __locale_(name ? new __imp(*other.__locale_, name, c)
  487. : throw runtime_error("locale constructed with null"))
  488. #else // _LIBCPP_NO_EXCEPTIONS
  489. : __locale_(new __imp(*other.__locale_, name, c))
  490. #endif
  491. {
  492. __locale_->__add_shared();
  493. }
  494. locale::locale(const locale& other, const string& name, category c)
  495. : __locale_(new __imp(*other.__locale_, name, c))
  496. {
  497. __locale_->__add_shared();
  498. }
  499. locale::locale(const locale& other, const locale& one, category c)
  500. : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
  501. {
  502. __locale_->__add_shared();
  503. }
  504. string
  505. locale::name() const
  506. {
  507. return __locale_->name();
  508. }
  509. void
  510. locale::__install_ctor(const locale& other, facet* f, long id)
  511. {
  512. if (f)
  513. __locale_ = new __imp(*other.__locale_, f, id);
  514. else
  515. __locale_ = other.__locale_;
  516. __locale_->__add_shared();
  517. }
  518. locale
  519. locale::global(const locale& loc)
  520. {
  521. locale& g = __global();
  522. locale r = g;
  523. g = loc;
  524. #ifndef __CloudABI__
  525. if (g.name() != "*")
  526. setlocale(LC_ALL, g.name().c_str());
  527. #endif
  528. return r;
  529. }
  530. bool
  531. locale::has_facet(id& x) const
  532. {
  533. return __locale_->has_facet(x.__get());
  534. }
  535. const locale::facet*
  536. locale::use_facet(id& x) const
  537. {
  538. return __locale_->use_facet(x.__get());
  539. }
  540. bool
  541. locale::operator==(const locale& y) const
  542. {
  543. return (__locale_ == y.__locale_)
  544. || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
  545. }
  546. // locale::facet
  547. locale::facet::~facet()
  548. {
  549. }
  550. void
  551. locale::facet::__on_zero_shared() _NOEXCEPT
  552. {
  553. delete this;
  554. }
  555. // locale::id
  556. int32_t locale::id::__next_id = 0;
  557. namespace
  558. {
  559. class __fake_bind
  560. {
  561. locale::id* id_;
  562. void (locale::id::* pmf_)();
  563. public:
  564. __fake_bind(void (locale::id::* pmf)(), locale::id* id)
  565. : id_(id), pmf_(pmf) {}
  566. void operator()() const
  567. {
  568. (id_->*pmf_)();
  569. }
  570. };
  571. }
  572. long
  573. locale::id::__get()
  574. {
  575. call_once(__flag_, __fake_bind(&locale::id::__init, this));
  576. return __id_ - 1;
  577. }
  578. void
  579. locale::id::__init()
  580. {
  581. __id_ = __sync_add_and_fetch(&__next_id, 1);
  582. }
  583. // template <> class collate_byname<char>
  584. collate_byname<char>::collate_byname(const char* n, size_t refs)
  585. : collate<char>(refs),
  586. __l(newlocale(LC_ALL_MASK, n, 0))
  587. {
  588. #ifndef _LIBCPP_NO_EXCEPTIONS
  589. if (__l == 0)
  590. throw runtime_error("collate_byname<char>::collate_byname"
  591. " failed to construct for " + string(n));
  592. #endif // _LIBCPP_NO_EXCEPTIONS
  593. }
  594. collate_byname<char>::collate_byname(const string& name, size_t refs)
  595. : collate<char>(refs),
  596. __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
  597. {
  598. #ifndef _LIBCPP_NO_EXCEPTIONS
  599. if (__l == 0)
  600. throw runtime_error("collate_byname<char>::collate_byname"
  601. " failed to construct for " + name);
  602. #endif // _LIBCPP_NO_EXCEPTIONS
  603. }
  604. collate_byname<char>::~collate_byname()
  605. {
  606. freelocale(__l);
  607. }
  608. int
  609. collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
  610. const char_type* __lo2, const char_type* __hi2) const
  611. {
  612. string_type lhs(__lo1, __hi1);
  613. string_type rhs(__lo2, __hi2);
  614. int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l);
  615. if (r < 0)
  616. return -1;
  617. if (r > 0)
  618. return 1;
  619. return r;
  620. }
  621. collate_byname<char>::string_type
  622. collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
  623. {
  624. const string_type in(lo, hi);
  625. string_type out(strxfrm_l(0, in.c_str(), 0, __l), char());
  626. strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l);
  627. return out;
  628. }
  629. // template <> class collate_byname<wchar_t>
  630. collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
  631. : collate<wchar_t>(refs),
  632. __l(newlocale(LC_ALL_MASK, n, 0))
  633. {
  634. #ifndef _LIBCPP_NO_EXCEPTIONS
  635. if (__l == 0)
  636. throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
  637. " failed to construct for " + string(n));
  638. #endif // _LIBCPP_NO_EXCEPTIONS
  639. }
  640. collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
  641. : collate<wchar_t>(refs),
  642. __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
  643. {
  644. #ifndef _LIBCPP_NO_EXCEPTIONS
  645. if (__l == 0)
  646. throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
  647. " failed to construct for " + name);
  648. #endif // _LIBCPP_NO_EXCEPTIONS
  649. }
  650. collate_byname<wchar_t>::~collate_byname()
  651. {
  652. freelocale(__l);
  653. }
  654. int
  655. collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
  656. const char_type* __lo2, const char_type* __hi2) const
  657. {
  658. string_type lhs(__lo1, __hi1);
  659. string_type rhs(__lo2, __hi2);
  660. int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l);
  661. if (r < 0)
  662. return -1;
  663. if (r > 0)
  664. return 1;
  665. return r;
  666. }
  667. collate_byname<wchar_t>::string_type
  668. collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
  669. {
  670. const string_type in(lo, hi);
  671. string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t());
  672. wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l);
  673. return out;
  674. }
  675. // template <> class ctype<wchar_t>;
  676. const ctype_base::mask ctype_base::space;
  677. const ctype_base::mask ctype_base::print;
  678. const ctype_base::mask ctype_base::cntrl;
  679. const ctype_base::mask ctype_base::upper;
  680. const ctype_base::mask ctype_base::lower;
  681. const ctype_base::mask ctype_base::alpha;
  682. const ctype_base::mask ctype_base::digit;
  683. const ctype_base::mask ctype_base::punct;
  684. const ctype_base::mask ctype_base::xdigit;
  685. const ctype_base::mask ctype_base::blank;
  686. const ctype_base::mask ctype_base::alnum;
  687. const ctype_base::mask ctype_base::graph;
  688. locale::id ctype<wchar_t>::id;
  689. ctype<wchar_t>::~ctype()
  690. {
  691. }
  692. bool
  693. ctype<wchar_t>::do_is(mask m, char_type c) const
  694. {
  695. return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
  696. }
  697. const wchar_t*
  698. ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
  699. {
  700. for (; low != high; ++low, ++vec)
  701. *vec = static_cast<mask>(isascii(*low) ?
  702. ctype<char>::classic_table()[*low] : 0);
  703. return low;
  704. }
  705. const wchar_t*
  706. ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
  707. {
  708. for (; low != high; ++low)
  709. if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
  710. break;
  711. return low;
  712. }
  713. const wchar_t*
  714. ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
  715. {
  716. for (; low != high; ++low)
  717. if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
  718. break;
  719. return low;
  720. }
  721. wchar_t
  722. ctype<wchar_t>::do_toupper(char_type c) const
  723. {
  724. #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
  725. return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
  726. #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
  727. defined(__NetBSD__)
  728. return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
  729. #else
  730. return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;
  731. #endif
  732. }
  733. const wchar_t*
  734. ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
  735. {
  736. for (; low != high; ++low)
  737. #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
  738. *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
  739. #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
  740. defined(__NetBSD__)
  741. *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
  742. : *low;
  743. #else
  744. *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low;
  745. #endif
  746. return low;
  747. }
  748. wchar_t
  749. ctype<wchar_t>::do_tolower(char_type c) const
  750. {
  751. #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
  752. return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
  753. #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
  754. defined(__NetBSD__)
  755. return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
  756. #else
  757. return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;
  758. #endif
  759. }
  760. const wchar_t*
  761. ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
  762. {
  763. for (; low != high; ++low)
  764. #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
  765. *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
  766. #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
  767. defined(__NetBSD__)
  768. *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
  769. : *low;
  770. #else
  771. *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low;
  772. #endif
  773. return low;
  774. }
  775. wchar_t
  776. ctype<wchar_t>::do_widen(char c) const
  777. {
  778. return c;
  779. }
  780. const char*
  781. ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
  782. {
  783. for (; low != high; ++low, ++dest)
  784. *dest = *low;
  785. return low;
  786. }
  787. char
  788. ctype<wchar_t>::do_narrow(char_type c, char dfault) const
  789. {
  790. if (isascii(c))
  791. return static_cast<char>(c);
  792. return dfault;
  793. }
  794. const wchar_t*
  795. ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
  796. {
  797. for (; low != high; ++low, ++dest)
  798. if (isascii(*low))
  799. *dest = static_cast<char>(*low);
  800. else
  801. *dest = dfault;
  802. return low;
  803. }
  804. // template <> class ctype<char>;
  805. locale::id ctype<char>::id;
  806. ctype<char>::ctype(const mask* tab, bool del, size_t refs)
  807. : locale::facet(refs),
  808. __tab_(tab),
  809. __del_(del)
  810. {
  811. if (__tab_ == 0)
  812. __tab_ = classic_table();
  813. }
  814. ctype<char>::~ctype()
  815. {
  816. if (__tab_ && __del_)
  817. delete [] __tab_;
  818. }
  819. char
  820. ctype<char>::do_toupper(char_type c) const
  821. {
  822. #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
  823. return isascii(c) ?
  824. static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
  825. #elif defined(__NetBSD__)
  826. return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
  827. #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
  828. return isascii(c) ?
  829. static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
  830. #else
  831. return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;
  832. #endif
  833. }
  834. const char*
  835. ctype<char>::do_toupper(char_type* low, const char_type* high) const
  836. {
  837. for (; low != high; ++low)
  838. #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
  839. *low = isascii(*low) ?
  840. static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
  841. #elif defined(__NetBSD__)
  842. *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
  843. #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
  844. *low = isascii(*low) ?
  845. static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
  846. #else
  847. *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low;
  848. #endif
  849. return low;
  850. }
  851. char
  852. ctype<char>::do_tolower(char_type c) const
  853. {
  854. #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
  855. return isascii(c) ?
  856. static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
  857. #elif defined(__NetBSD__)
  858. return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
  859. #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
  860. return isascii(c) ?
  861. static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
  862. #else
  863. return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c;
  864. #endif
  865. }
  866. const char*
  867. ctype<char>::do_tolower(char_type* low, const char_type* high) const
  868. {
  869. for (; low != high; ++low)
  870. #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
  871. *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
  872. #elif defined(__NetBSD__)
  873. *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
  874. #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
  875. *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
  876. #else
  877. *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low;
  878. #endif
  879. return low;
  880. }
  881. char
  882. ctype<char>::do_widen(char c) const
  883. {
  884. return c;
  885. }
  886. const char*
  887. ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
  888. {
  889. for (; low != high; ++low, ++dest)
  890. *dest = *low;
  891. return low;
  892. }
  893. char
  894. ctype<char>::do_narrow(char_type c, char dfault) const
  895. {
  896. if (isascii(c))
  897. return static_cast<char>(c);
  898. return dfault;
  899. }
  900. const char*
  901. ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
  902. {
  903. for (; low != high; ++low, ++dest)
  904. if (isascii(*low))
  905. *dest = *low;
  906. else
  907. *dest = dfault;
  908. return low;
  909. }
  910. #if defined(__EMSCRIPTEN__)
  911. extern "C" const unsigned short ** __ctype_b_loc();
  912. extern "C" const int ** __ctype_tolower_loc();
  913. extern "C" const int ** __ctype_toupper_loc();
  914. #endif
  915. #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
  916. const ctype<char>::mask*
  917. ctype<char>::classic_table() _NOEXCEPT
  918. {
  919. static _LIBCPP_CONSTEXPR const ctype<char>::mask builtin_table[table_size] = {
  920. cntrl, cntrl,
  921. cntrl, cntrl,
  922. cntrl, cntrl,
  923. cntrl, cntrl,
  924. cntrl, cntrl | space | blank,
  925. cntrl | space, cntrl | space,
  926. cntrl | space, cntrl | space,
  927. cntrl, cntrl,
  928. cntrl, cntrl,
  929. cntrl, cntrl,
  930. cntrl, cntrl,
  931. cntrl, cntrl,
  932. cntrl, cntrl,
  933. cntrl, cntrl,
  934. cntrl, cntrl,
  935. cntrl, cntrl,
  936. space | blank | print, punct | print,
  937. punct | print, punct | print,
  938. punct | print, punct | print,
  939. punct | print, punct | print,
  940. punct | print, punct | print,
  941. punct | print, punct | print,
  942. punct | print, punct | print,
  943. punct | print, punct | print,
  944. digit | print | xdigit, digit | print | xdigit,
  945. digit | print | xdigit, digit | print | xdigit,
  946. digit | print | xdigit, digit | print | xdigit,
  947. digit | print | xdigit, digit | print | xdigit,
  948. digit | print | xdigit, digit | print | xdigit,
  949. punct | print, punct | print,
  950. punct | print, punct | print,
  951. punct | print, punct | print,
  952. punct | print, upper | xdigit | print | alpha,
  953. upper | xdigit | print | alpha, upper | xdigit | print | alpha,
  954. upper | xdigit | print | alpha, upper | xdigit | print | alpha,
  955. upper | xdigit | print | alpha, upper | print | alpha,
  956. upper | print | alpha, upper | print | alpha,
  957. upper | print | alpha, upper | print | alpha,
  958. upper | print | alpha, upper | print | alpha,
  959. upper | print | alpha, upper | print | alpha,
  960. upper | print | alpha, upper | print | alpha,
  961. upper | print | alpha, upper | print | alpha,
  962. upper | print | alpha, upper | print | alpha,
  963. upper | print | alpha, upper | print | alpha,
  964. upper | print | alpha, upper | print | alpha,
  965. upper | print | alpha, punct | print,
  966. punct | print, punct | print,
  967. punct | print, punct | print,
  968. punct | print, lower | xdigit | print | alpha,
  969. lower | xdigit | print | alpha, lower | xdigit | print | alpha,
  970. lower | xdigit | print | alpha, lower | xdigit | print | alpha,
  971. lower | xdigit | print | alpha, lower | print | alpha,
  972. lower | print | alpha, lower | print | alpha,
  973. lower | print | alpha, lower | print | alpha,
  974. lower | print | alpha, lower | print | alpha,
  975. lower | print | alpha, lower | print | alpha,
  976. lower | print | alpha, lower | print | alpha,
  977. lower | print | alpha, lower | print | alpha,
  978. lower | print | alpha, lower | print | alpha,
  979. lower | print | alpha, lower | print | alpha,
  980. lower | print | alpha, lower | print | alpha,
  981. lower | print | alpha, punct | print,
  982. punct | print, punct | print,
  983. punct | print, cntrl,
  984. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  985. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  986. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  987. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  988. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  989. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  990. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  991. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  992. };
  993. return builtin_table;
  994. }
  995. #else
  996. const ctype<char>::mask*
  997. ctype<char>::classic_table() _NOEXCEPT
  998. {
  999. #if defined(__APPLE__) || defined(__FreeBSD__)
  1000. return _DefaultRuneLocale.__runetype;
  1001. #elif defined(__NetBSD__)
  1002. return _C_ctype_tab_ + 1;
  1003. #elif defined(__GLIBC__)
  1004. return _LIBCPP_GET_C_LOCALE->__ctype_b;
  1005. #elif __sun__
  1006. return __ctype_mask;
  1007. #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
  1008. return _ctype+1; // internal ctype mask table defined in msvcrt.dll
  1009. // This is assumed to be safe, which is a nonsense assumption because we're
  1010. // going to end up dereferencing it later...
  1011. #elif defined(__EMSCRIPTEN__)
  1012. return *__ctype_b_loc();
  1013. #elif defined(_NEWLIB_VERSION)
  1014. // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
  1015. return _ctype_ + 1;
  1016. #elif defined(_AIX)
  1017. return (const unsigned int *)__lc_ctype_ptr->obj->mask;
  1018. #else
  1019. // Platform not supported: abort so the person doing the port knows what to
  1020. // fix
  1021. # warning ctype<char>::classic_table() is not implemented
  1022. printf("ctype<char>::classic_table() is not implemented\n");
  1023. abort();
  1024. return NULL;
  1025. #endif
  1026. }
  1027. #endif
  1028. #if defined(__GLIBC__)
  1029. const int*
  1030. ctype<char>::__classic_lower_table() _NOEXCEPT
  1031. {
  1032. return _LIBCPP_GET_C_LOCALE->__ctype_tolower;
  1033. }
  1034. const int*
  1035. ctype<char>::__classic_upper_table() _NOEXCEPT
  1036. {
  1037. return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
  1038. }
  1039. #elif __NetBSD__
  1040. const short*
  1041. ctype<char>::__classic_lower_table() _NOEXCEPT
  1042. {
  1043. return _C_tolower_tab_ + 1;
  1044. }
  1045. const short*
  1046. ctype<char>::__classic_upper_table() _NOEXCEPT
  1047. {
  1048. return _C_toupper_tab_ + 1;
  1049. }
  1050. #elif defined(__EMSCRIPTEN__)
  1051. const int*
  1052. ctype<char>::__classic_lower_table() _NOEXCEPT
  1053. {
  1054. return *__ctype_tolower_loc();
  1055. }
  1056. const int*
  1057. ctype<char>::__classic_upper_table() _NOEXCEPT
  1058. {
  1059. return *__ctype_toupper_loc();
  1060. }
  1061. #endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__
  1062. // template <> class ctype_byname<char>
  1063. ctype_byname<char>::ctype_byname(const char* name, size_t refs)
  1064. : ctype<char>(0, false, refs),
  1065. __l(newlocale(LC_ALL_MASK, name, 0))
  1066. {
  1067. #ifndef _LIBCPP_NO_EXCEPTIONS
  1068. if (__l == 0)
  1069. throw runtime_error("ctype_byname<char>::ctype_byname"
  1070. " failed to construct for " + string(name));
  1071. #endif // _LIBCPP_NO_EXCEPTIONS
  1072. }
  1073. ctype_byname<char>::ctype_byname(const string& name, size_t refs)
  1074. : ctype<char>(0, false, refs),
  1075. __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
  1076. {
  1077. #ifndef _LIBCPP_NO_EXCEPTIONS
  1078. if (__l == 0)
  1079. throw runtime_error("ctype_byname<char>::ctype_byname"
  1080. " failed to construct for " + name);
  1081. #endif // _LIBCPP_NO_EXCEPTIONS
  1082. }
  1083. ctype_byname<char>::~ctype_byname()
  1084. {
  1085. freelocale(__l);
  1086. }
  1087. char
  1088. ctype_byname<char>::do_toupper(char_type c) const
  1089. {
  1090. return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l));
  1091. }
  1092. const char*
  1093. ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
  1094. {
  1095. for (; low != high; ++low)
  1096. *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l));
  1097. return low;
  1098. }
  1099. char
  1100. ctype_byname<char>::do_tolower(char_type c) const
  1101. {
  1102. return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l));
  1103. }
  1104. const char*
  1105. ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
  1106. {
  1107. for (; low != high; ++low)
  1108. *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l));
  1109. return low;
  1110. }
  1111. // template <> class ctype_byname<wchar_t>
  1112. ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
  1113. : ctype<wchar_t>(refs),
  1114. __l(newlocale(LC_ALL_MASK, name, 0))
  1115. {
  1116. #ifndef _LIBCPP_NO_EXCEPTIONS
  1117. if (__l == 0)
  1118. throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
  1119. " failed to construct for " + string(name));
  1120. #endif // _LIBCPP_NO_EXCEPTIONS
  1121. }
  1122. ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
  1123. : ctype<wchar_t>(refs),
  1124. __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
  1125. {
  1126. #ifndef _LIBCPP_NO_EXCEPTIONS
  1127. if (__l == 0)
  1128. throw runtime_error("ctype_byname<wchar_t>::ctype_byname"
  1129. " failed to construct for " + name);
  1130. #endif // _LIBCPP_NO_EXCEPTIONS
  1131. }
  1132. ctype_byname<wchar_t>::~ctype_byname()
  1133. {
  1134. freelocale(__l);
  1135. }
  1136. bool
  1137. ctype_byname<wchar_t>::do_is(mask m, char_type c) const
  1138. {
  1139. #ifdef _LIBCPP_WCTYPE_IS_MASK
  1140. return static_cast<bool>(iswctype_l(c, m, __l));
  1141. #else
  1142. bool result = false;
  1143. wint_t ch = static_cast<wint_t>(c);
  1144. if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0);
  1145. if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0);
  1146. if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0);
  1147. if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0);
  1148. if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0);
  1149. if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0);
  1150. if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0);
  1151. if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0);
  1152. if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0);
  1153. if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0);
  1154. return result;
  1155. #endif
  1156. }
  1157. const wchar_t*
  1158. ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
  1159. {
  1160. for (; low != high; ++low, ++vec)
  1161. {
  1162. if (isascii(*low))
  1163. *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
  1164. else
  1165. {
  1166. *vec = 0;
  1167. wint_t ch = static_cast<wint_t>(*low);
  1168. if (iswspace_l(ch, __l))
  1169. *vec |= space;
  1170. #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
  1171. if (iswprint_l(ch, __l))
  1172. *vec |= print;
  1173. #endif
  1174. if (iswcntrl_l(ch, __l))
  1175. *vec |= cntrl;
  1176. if (iswupper_l(ch, __l))
  1177. *vec |= upper;
  1178. if (iswlower_l(ch, __l))
  1179. *vec |= lower;
  1180. #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
  1181. if (iswalpha_l(ch, __l))
  1182. *vec |= alpha;
  1183. #endif
  1184. if (iswdigit_l(ch, __l))
  1185. *vec |= digit;
  1186. if (iswpunct_l(ch, __l))
  1187. *vec |= punct;
  1188. #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
  1189. if (iswxdigit_l(ch, __l))
  1190. *vec |= xdigit;
  1191. #endif
  1192. #if !defined(__sun__)
  1193. if (iswblank_l(ch, __l))
  1194. *vec |= blank;
  1195. #endif
  1196. }
  1197. }
  1198. return low;
  1199. }
  1200. const wchar_t*
  1201. ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
  1202. {
  1203. for (; low != high; ++low)
  1204. {
  1205. #ifdef _LIBCPP_WCTYPE_IS_MASK
  1206. if (iswctype_l(*low, m, __l))
  1207. break;
  1208. #else
  1209. wint_t ch = static_cast<wint_t>(*low);
  1210. if ((m & space) == space && iswspace_l(ch, __l)) break;
  1211. if ((m & print) == print && iswprint_l(ch, __l)) break;
  1212. if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break;
  1213. if ((m & upper) == upper && iswupper_l(ch, __l)) break;
  1214. if ((m & lower) == lower && iswlower_l(ch, __l)) break;
  1215. if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break;
  1216. if ((m & digit) == digit && iswdigit_l(ch, __l)) break;
  1217. if ((m & punct) == punct && iswpunct_l(ch, __l)) break;
  1218. if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break;
  1219. if ((m & blank) == blank && iswblank_l(ch, __l)) break;
  1220. #endif
  1221. }
  1222. return low;
  1223. }
  1224. const wchar_t*
  1225. ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
  1226. {
  1227. for (; low != high; ++low)
  1228. {
  1229. #ifdef _LIBCPP_WCTYPE_IS_MASK
  1230. if (!iswctype_l(*low, m, __l))
  1231. break;
  1232. #else
  1233. wint_t ch = static_cast<wint_t>(*low);
  1234. if ((m & space) == space && iswspace_l(ch, __l)) continue;
  1235. if ((m & print) == print && iswprint_l(ch, __l)) continue;
  1236. if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue;
  1237. if ((m & upper) == upper && iswupper_l(ch, __l)) continue;
  1238. if ((m & lower) == lower && iswlower_l(ch, __l)) continue;
  1239. if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue;
  1240. if ((m & digit) == digit && iswdigit_l(ch, __l)) continue;
  1241. if ((m & punct) == punct && iswpunct_l(ch, __l)) continue;
  1242. if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue;
  1243. if ((m & blank) == blank && iswblank_l(ch, __l)) continue;
  1244. break;
  1245. #endif
  1246. }
  1247. return low;
  1248. }
  1249. wchar_t
  1250. ctype_byname<wchar_t>::do_toupper(char_type c) const
  1251. {
  1252. return towupper_l(c, __l);
  1253. }
  1254. const wchar_t*
  1255. ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
  1256. {
  1257. for (; low != high; ++low)
  1258. *low = towupper_l(*low, __l);
  1259. return low;
  1260. }
  1261. wchar_t
  1262. ctype_byname<wchar_t>::do_tolower(char_type c) const
  1263. {
  1264. return towlower_l(c, __l);
  1265. }
  1266. const wchar_t*
  1267. ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
  1268. {
  1269. for (; low != high; ++low)
  1270. *low = towlower_l(*low, __l);
  1271. return low;
  1272. }
  1273. wchar_t
  1274. ctype_byname<wchar_t>::do_widen(char c) const
  1275. {
  1276. return __libcpp_btowc_l(c, __l);
  1277. }
  1278. const char*
  1279. ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
  1280. {
  1281. for (; low != high; ++low, ++dest)
  1282. *dest = __libcpp_btowc_l(*low, __l);
  1283. return low;
  1284. }
  1285. char
  1286. ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
  1287. {
  1288. int r = __libcpp_wctob_l(c, __l);
  1289. return r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
  1290. }
  1291. const wchar_t*
  1292. ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
  1293. {
  1294. for (; low != high; ++low, ++dest)
  1295. {
  1296. int r = __libcpp_wctob_l(*low, __l);
  1297. *dest = r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
  1298. }
  1299. return low;
  1300. }
  1301. // template <> class codecvt<char, char, mbstate_t>
  1302. locale::id codecvt<char, char, mbstate_t>::id;
  1303. codecvt<char, char, mbstate_t>::~codecvt()
  1304. {
  1305. }
  1306. codecvt<char, char, mbstate_t>::result
  1307. codecvt<char, char, mbstate_t>::do_out(state_type&,
  1308. const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
  1309. extern_type* to, extern_type*, extern_type*& to_nxt) const
  1310. {
  1311. frm_nxt = frm;
  1312. to_nxt = to;
  1313. return noconv;
  1314. }
  1315. codecvt<char, char, mbstate_t>::result
  1316. codecvt<char, char, mbstate_t>::do_in(state_type&,
  1317. const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
  1318. intern_type* to, intern_type*, intern_type*& to_nxt) const
  1319. {
  1320. frm_nxt = frm;
  1321. to_nxt = to;
  1322. return noconv;
  1323. }
  1324. codecvt<char, char, mbstate_t>::result
  1325. codecvt<char, char, mbstate_t>::do_unshift(state_type&,
  1326. extern_type* to, extern_type*, extern_type*& to_nxt) const
  1327. {
  1328. to_nxt = to;
  1329. return noconv;
  1330. }
  1331. int
  1332. codecvt<char, char, mbstate_t>::do_encoding() const _NOEXCEPT
  1333. {
  1334. return 1;
  1335. }
  1336. bool
  1337. codecvt<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
  1338. {
  1339. return true;
  1340. }
  1341. int
  1342. codecvt<char, char, mbstate_t>::do_length(state_type&,
  1343. const extern_type* frm, const extern_type* end, size_t mx) const
  1344. {
  1345. return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
  1346. }
  1347. int
  1348. codecvt<char, char, mbstate_t>::do_max_length() const _NOEXCEPT
  1349. {
  1350. return 1;
  1351. }
  1352. // template <> class codecvt<wchar_t, char, mbstate_t>
  1353. locale::id codecvt<wchar_t, char, mbstate_t>::id;
  1354. codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
  1355. : locale::facet(refs),
  1356. __l(_LIBCPP_GET_C_LOCALE)
  1357. {
  1358. }
  1359. codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
  1360. : locale::facet(refs),
  1361. __l(newlocale(LC_ALL_MASK, nm, 0))
  1362. {
  1363. #ifndef _LIBCPP_NO_EXCEPTIONS
  1364. if (__l == 0)
  1365. throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
  1366. " failed to construct for " + string(nm));
  1367. #endif // _LIBCPP_NO_EXCEPTIONS
  1368. }
  1369. codecvt<wchar_t, char, mbstate_t>::~codecvt()
  1370. {
  1371. if (__l != _LIBCPP_GET_C_LOCALE)
  1372. freelocale(__l);
  1373. }
  1374. codecvt<wchar_t, char, mbstate_t>::result
  1375. codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
  1376. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  1377. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  1378. {
  1379. // look for first internal null in frm
  1380. const intern_type* fend = frm;
  1381. for (; fend != frm_end; ++fend)
  1382. if (*fend == 0)
  1383. break;
  1384. // loop over all null-terminated sequences in frm
  1385. to_nxt = to;
  1386. for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
  1387. {
  1388. // save state in case it is needed to recover to_nxt on error
  1389. mbstate_t save_state = st;
  1390. size_t n = __libcpp_wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
  1391. static_cast<size_t>(to_end-to), &st, __l);
  1392. if (n == size_t(-1))
  1393. {
  1394. // need to recover to_nxt
  1395. for (to_nxt = to; frm != frm_nxt; ++frm)
  1396. {
  1397. n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l);
  1398. if (n == size_t(-1))
  1399. break;
  1400. to_nxt += n;
  1401. }
  1402. frm_nxt = frm;
  1403. return error;
  1404. }
  1405. if (n == 0)
  1406. return partial;
  1407. to_nxt += n;
  1408. if (to_nxt == to_end)
  1409. break;
  1410. if (fend != frm_end) // set up next null terminated sequence
  1411. {
  1412. // Try to write the terminating null
  1413. extern_type tmp[MB_LEN_MAX];
  1414. n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l);
  1415. if (n == size_t(-1)) // on error
  1416. return error;
  1417. if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
  1418. return partial;
  1419. for (extern_type* p = tmp; n; --n) // write it
  1420. *to_nxt++ = *p++;
  1421. ++frm_nxt;
  1422. // look for next null in frm
  1423. for (fend = frm_nxt; fend != frm_end; ++fend)
  1424. if (*fend == 0)
  1425. break;
  1426. }
  1427. }
  1428. return frm_nxt == frm_end ? ok : partial;
  1429. }
  1430. codecvt<wchar_t, char, mbstate_t>::result
  1431. codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
  1432. const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
  1433. intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
  1434. {
  1435. // look for first internal null in frm
  1436. const extern_type* fend = frm;
  1437. for (; fend != frm_end; ++fend)
  1438. if (*fend == 0)
  1439. break;
  1440. // loop over all null-terminated sequences in frm
  1441. to_nxt = to;
  1442. for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
  1443. {
  1444. // save state in case it is needed to recover to_nxt on error
  1445. mbstate_t save_state = st;
  1446. size_t n = __libcpp_mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
  1447. static_cast<size_t>(to_end-to), &st, __l);
  1448. if (n == size_t(-1))
  1449. {
  1450. // need to recover to_nxt
  1451. for (to_nxt = to; frm != frm_nxt; ++to_nxt)
  1452. {
  1453. n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
  1454. &save_state, __l);
  1455. switch (n)
  1456. {
  1457. case 0:
  1458. ++frm;
  1459. break;
  1460. case size_t(-1):
  1461. frm_nxt = frm;
  1462. return error;
  1463. case size_t(-2):
  1464. frm_nxt = frm;
  1465. return partial;
  1466. default:
  1467. frm += n;
  1468. break;
  1469. }
  1470. }
  1471. frm_nxt = frm;
  1472. return frm_nxt == frm_end ? ok : partial;
  1473. }
  1474. if (n == size_t(-1))
  1475. return error;
  1476. to_nxt += n;
  1477. if (to_nxt == to_end)
  1478. break;
  1479. if (fend != frm_end) // set up next null terminated sequence
  1480. {
  1481. // Try to write the terminating null
  1482. n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
  1483. if (n != 0) // on error
  1484. return error;
  1485. ++to_nxt;
  1486. ++frm_nxt;
  1487. // look for next null in frm
  1488. for (fend = frm_nxt; fend != frm_end; ++fend)
  1489. if (*fend == 0)
  1490. break;
  1491. }
  1492. }
  1493. return frm_nxt == frm_end ? ok : partial;
  1494. }
  1495. codecvt<wchar_t, char, mbstate_t>::result
  1496. codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
  1497. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  1498. {
  1499. to_nxt = to;
  1500. extern_type tmp[MB_LEN_MAX];
  1501. size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l);
  1502. if (n == size_t(-1) || n == 0) // on error
  1503. return error;
  1504. --n;
  1505. if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
  1506. return partial;
  1507. for (extern_type* p = tmp; n; --n) // write it
  1508. *to_nxt++ = *p++;
  1509. return ok;
  1510. }
  1511. int
  1512. codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
  1513. {
  1514. if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)
  1515. return -1;
  1516. // stateless encoding
  1517. if (__l == 0 || __libcpp_mb_cur_max_l(__l) == 1) // there are no known constant length encodings
  1518. return 1; // which take more than 1 char to form a wchar_t
  1519. return 0;
  1520. }
  1521. bool
  1522. codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
  1523. {
  1524. return false;
  1525. }
  1526. int
  1527. codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
  1528. const extern_type* frm, const extern_type* frm_end, size_t mx) const
  1529. {
  1530. int nbytes = 0;
  1531. for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
  1532. {
  1533. size_t n = __libcpp_mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l);
  1534. switch (n)
  1535. {
  1536. case 0:
  1537. ++nbytes;
  1538. ++frm;
  1539. break;
  1540. case size_t(-1):
  1541. case size_t(-2):
  1542. return nbytes;
  1543. default:
  1544. nbytes += n;
  1545. frm += n;
  1546. break;
  1547. }
  1548. }
  1549. return nbytes;
  1550. }
  1551. int
  1552. codecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
  1553. {
  1554. return __l == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l));
  1555. }
  1556. // Valid UTF ranges
  1557. // UTF-32 UTF-16 UTF-8 # of code points
  1558. // first second first second third fourth
  1559. // 000000 - 00007F 0000 - 007F 00 - 7F 127
  1560. // 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
  1561. // 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
  1562. // 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
  1563. // 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
  1564. // 00D800 - 00DFFF invalid
  1565. // 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
  1566. // 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
  1567. // 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
  1568. // 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
  1569. static
  1570. codecvt_base::result
  1571. utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
  1572. uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
  1573. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  1574. {
  1575. frm_nxt = frm;
  1576. to_nxt = to;
  1577. if (mode & generate_header)
  1578. {
  1579. if (to_end-to_nxt < 3)
  1580. return codecvt_base::partial;
  1581. *to_nxt++ = static_cast<uint8_t>(0xEF);
  1582. *to_nxt++ = static_cast<uint8_t>(0xBB);
  1583. *to_nxt++ = static_cast<uint8_t>(0xBF);
  1584. }
  1585. for (; frm_nxt < frm_end; ++frm_nxt)
  1586. {
  1587. uint16_t wc1 = *frm_nxt;
  1588. if (wc1 > Maxcode)
  1589. return codecvt_base::error;
  1590. if (wc1 < 0x0080)
  1591. {
  1592. if (to_end-to_nxt < 1)
  1593. return codecvt_base::partial;
  1594. *to_nxt++ = static_cast<uint8_t>(wc1);
  1595. }
  1596. else if (wc1 < 0x0800)
  1597. {
  1598. if (to_end-to_nxt < 2)
  1599. return codecvt_base::partial;
  1600. *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
  1601. *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
  1602. }
  1603. else if (wc1 < 0xD800)
  1604. {
  1605. if (to_end-to_nxt < 3)
  1606. return codecvt_base::partial;
  1607. *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
  1608. *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
  1609. *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
  1610. }
  1611. else if (wc1 < 0xDC00)
  1612. {
  1613. if (frm_end-frm_nxt < 2)
  1614. return codecvt_base::partial;
  1615. uint16_t wc2 = frm_nxt[1];
  1616. if ((wc2 & 0xFC00) != 0xDC00)
  1617. return codecvt_base::error;
  1618. if (to_end-to_nxt < 4)
  1619. return codecvt_base::partial;
  1620. if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
  1621. ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
  1622. return codecvt_base::error;
  1623. ++frm_nxt;
  1624. uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
  1625. *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
  1626. *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
  1627. *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
  1628. *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
  1629. }
  1630. else if (wc1 < 0xE000)
  1631. {
  1632. return codecvt_base::error;
  1633. }
  1634. else
  1635. {
  1636. if (to_end-to_nxt < 3)
  1637. return codecvt_base::partial;
  1638. *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
  1639. *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
  1640. *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
  1641. }
  1642. }
  1643. return codecvt_base::ok;
  1644. }
  1645. static
  1646. codecvt_base::result
  1647. utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
  1648. uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
  1649. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  1650. {
  1651. frm_nxt = frm;
  1652. to_nxt = to;
  1653. if (mode & generate_header)
  1654. {
  1655. if (to_end-to_nxt < 3)
  1656. return codecvt_base::partial;
  1657. *to_nxt++ = static_cast<uint8_t>(0xEF);
  1658. *to_nxt++ = static_cast<uint8_t>(0xBB);
  1659. *to_nxt++ = static_cast<uint8_t>(0xBF);
  1660. }
  1661. for (; frm_nxt < frm_end; ++frm_nxt)
  1662. {
  1663. uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
  1664. if (wc1 > Maxcode)
  1665. return codecvt_base::error;
  1666. if (wc1 < 0x0080)
  1667. {
  1668. if (to_end-to_nxt < 1)
  1669. return codecvt_base::partial;
  1670. *to_nxt++ = static_cast<uint8_t>(wc1);
  1671. }
  1672. else if (wc1 < 0x0800)
  1673. {
  1674. if (to_end-to_nxt < 2)
  1675. return codecvt_base::partial;
  1676. *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
  1677. *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
  1678. }
  1679. else if (wc1 < 0xD800)
  1680. {
  1681. if (to_end-to_nxt < 3)
  1682. return codecvt_base::partial;
  1683. *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
  1684. *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
  1685. *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
  1686. }
  1687. else if (wc1 < 0xDC00)
  1688. {
  1689. if (frm_end-frm_nxt < 2)
  1690. return codecvt_base::partial;
  1691. uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
  1692. if ((wc2 & 0xFC00) != 0xDC00)
  1693. return codecvt_base::error;
  1694. if (to_end-to_nxt < 4)
  1695. return codecvt_base::partial;
  1696. if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
  1697. ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
  1698. return codecvt_base::error;
  1699. ++frm_nxt;
  1700. uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
  1701. *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
  1702. *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
  1703. *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
  1704. *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
  1705. }
  1706. else if (wc1 < 0xE000)
  1707. {
  1708. return codecvt_base::error;
  1709. }
  1710. else
  1711. {
  1712. if (to_end-to_nxt < 3)
  1713. return codecvt_base::partial;
  1714. *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
  1715. *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
  1716. *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
  1717. }
  1718. }
  1719. return codecvt_base::ok;
  1720. }
  1721. static
  1722. codecvt_base::result
  1723. utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
  1724. uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
  1725. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  1726. {
  1727. frm_nxt = frm;
  1728. to_nxt = to;
  1729. if (mode & consume_header)
  1730. {
  1731. if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
  1732. frm_nxt[2] == 0xBF)
  1733. frm_nxt += 3;
  1734. }
  1735. for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
  1736. {
  1737. uint8_t c1 = *frm_nxt;
  1738. if (c1 > Maxcode)
  1739. return codecvt_base::error;
  1740. if (c1 < 0x80)
  1741. {
  1742. *to_nxt = static_cast<uint16_t>(c1);
  1743. ++frm_nxt;
  1744. }
  1745. else if (c1 < 0xC2)
  1746. {
  1747. return codecvt_base::error;
  1748. }
  1749. else if (c1 < 0xE0)
  1750. {
  1751. if (frm_end-frm_nxt < 2)
  1752. return codecvt_base::partial;
  1753. uint8_t c2 = frm_nxt[1];
  1754. if ((c2 & 0xC0) != 0x80)
  1755. return codecvt_base::error;
  1756. uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
  1757. if (t > Maxcode)
  1758. return codecvt_base::error;
  1759. *to_nxt = t;
  1760. frm_nxt += 2;
  1761. }
  1762. else if (c1 < 0xF0)
  1763. {
  1764. if (frm_end-frm_nxt < 3)
  1765. return codecvt_base::partial;
  1766. uint8_t c2 = frm_nxt[1];
  1767. uint8_t c3 = frm_nxt[2];
  1768. switch (c1)
  1769. {
  1770. case 0xE0:
  1771. if ((c2 & 0xE0) != 0xA0)
  1772. return codecvt_base::error;
  1773. break;
  1774. case 0xED:
  1775. if ((c2 & 0xE0) != 0x80)
  1776. return codecvt_base::error;
  1777. break;
  1778. default:
  1779. if ((c2 & 0xC0) != 0x80)
  1780. return codecvt_base::error;
  1781. break;
  1782. }
  1783. if ((c3 & 0xC0) != 0x80)
  1784. return codecvt_base::error;
  1785. uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
  1786. | ((c2 & 0x3F) << 6)
  1787. | (c3 & 0x3F));
  1788. if (t > Maxcode)
  1789. return codecvt_base::error;
  1790. *to_nxt = t;
  1791. frm_nxt += 3;
  1792. }
  1793. else if (c1 < 0xF5)
  1794. {
  1795. if (frm_end-frm_nxt < 4)
  1796. return codecvt_base::partial;
  1797. uint8_t c2 = frm_nxt[1];
  1798. uint8_t c3 = frm_nxt[2];
  1799. uint8_t c4 = frm_nxt[3];
  1800. switch (c1)
  1801. {
  1802. case 0xF0:
  1803. if (!(0x90 <= c2 && c2 <= 0xBF))
  1804. return codecvt_base::error;
  1805. break;
  1806. case 0xF4:
  1807. if ((c2 & 0xF0) != 0x80)
  1808. return codecvt_base::error;
  1809. break;
  1810. default:
  1811. if ((c2 & 0xC0) != 0x80)
  1812. return codecvt_base::error;
  1813. break;
  1814. }
  1815. if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
  1816. return codecvt_base::error;
  1817. if (to_end-to_nxt < 2)
  1818. return codecvt_base::partial;
  1819. if ((((c1 & 7UL) << 18) +
  1820. ((c2 & 0x3FUL) << 12) +
  1821. ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
  1822. return codecvt_base::error;
  1823. *to_nxt = static_cast<uint16_t>(
  1824. 0xD800
  1825. | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
  1826. | ((c2 & 0x0F) << 2)
  1827. | ((c3 & 0x30) >> 4));
  1828. *++to_nxt = static_cast<uint16_t>(
  1829. 0xDC00
  1830. | ((c3 & 0x0F) << 6)
  1831. | (c4 & 0x3F));
  1832. frm_nxt += 4;
  1833. }
  1834. else
  1835. {
  1836. return codecvt_base::error;
  1837. }
  1838. }
  1839. return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
  1840. }
  1841. static
  1842. codecvt_base::result
  1843. utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
  1844. uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
  1845. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  1846. {
  1847. frm_nxt = frm;
  1848. to_nxt = to;
  1849. if (mode & consume_header)
  1850. {
  1851. if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
  1852. frm_nxt[2] == 0xBF)
  1853. frm_nxt += 3;
  1854. }
  1855. for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
  1856. {
  1857. uint8_t c1 = *frm_nxt;
  1858. if (c1 > Maxcode)
  1859. return codecvt_base::error;
  1860. if (c1 < 0x80)
  1861. {
  1862. *to_nxt = static_cast<uint32_t>(c1);
  1863. ++frm_nxt;
  1864. }
  1865. else if (c1 < 0xC2)
  1866. {
  1867. return codecvt_base::error;
  1868. }
  1869. else if (c1 < 0xE0)
  1870. {
  1871. if (frm_end-frm_nxt < 2)
  1872. return codecvt_base::partial;
  1873. uint8_t c2 = frm_nxt[1];
  1874. if ((c2 & 0xC0) != 0x80)
  1875. return codecvt_base::error;
  1876. uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
  1877. if (t > Maxcode)
  1878. return codecvt_base::error;
  1879. *to_nxt = static_cast<uint32_t>(t);
  1880. frm_nxt += 2;
  1881. }
  1882. else if (c1 < 0xF0)
  1883. {
  1884. if (frm_end-frm_nxt < 3)
  1885. return codecvt_base::partial;
  1886. uint8_t c2 = frm_nxt[1];
  1887. uint8_t c3 = frm_nxt[2];
  1888. switch (c1)
  1889. {
  1890. case 0xE0:
  1891. if ((c2 & 0xE0) != 0xA0)
  1892. return codecvt_base::error;
  1893. break;
  1894. case 0xED:
  1895. if ((c2 & 0xE0) != 0x80)
  1896. return codecvt_base::error;
  1897. break;
  1898. default:
  1899. if ((c2 & 0xC0) != 0x80)
  1900. return codecvt_base::error;
  1901. break;
  1902. }
  1903. if ((c3 & 0xC0) != 0x80)
  1904. return codecvt_base::error;
  1905. uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
  1906. | ((c2 & 0x3F) << 6)
  1907. | (c3 & 0x3F));
  1908. if (t > Maxcode)
  1909. return codecvt_base::error;
  1910. *to_nxt = static_cast<uint32_t>(t);
  1911. frm_nxt += 3;
  1912. }
  1913. else if (c1 < 0xF5)
  1914. {
  1915. if (frm_end-frm_nxt < 4)
  1916. return codecvt_base::partial;
  1917. uint8_t c2 = frm_nxt[1];
  1918. uint8_t c3 = frm_nxt[2];
  1919. uint8_t c4 = frm_nxt[3];
  1920. switch (c1)
  1921. {
  1922. case 0xF0:
  1923. if (!(0x90 <= c2 && c2 <= 0xBF))
  1924. return codecvt_base::error;
  1925. break;
  1926. case 0xF4:
  1927. if ((c2 & 0xF0) != 0x80)
  1928. return codecvt_base::error;
  1929. break;
  1930. default:
  1931. if ((c2 & 0xC0) != 0x80)
  1932. return codecvt_base::error;
  1933. break;
  1934. }
  1935. if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
  1936. return codecvt_base::error;
  1937. if (to_end-to_nxt < 2)
  1938. return codecvt_base::partial;
  1939. if ((((c1 & 7UL) << 18) +
  1940. ((c2 & 0x3FUL) << 12) +
  1941. ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
  1942. return codecvt_base::error;
  1943. *to_nxt = static_cast<uint32_t>(
  1944. 0xD800
  1945. | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
  1946. | ((c2 & 0x0F) << 2)
  1947. | ((c3 & 0x30) >> 4));
  1948. *++to_nxt = static_cast<uint32_t>(
  1949. 0xDC00
  1950. | ((c3 & 0x0F) << 6)
  1951. | (c4 & 0x3F));
  1952. frm_nxt += 4;
  1953. }
  1954. else
  1955. {
  1956. return codecvt_base::error;
  1957. }
  1958. }
  1959. return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
  1960. }
  1961. static
  1962. int
  1963. utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
  1964. size_t mx, unsigned long Maxcode = 0x10FFFF,
  1965. codecvt_mode mode = codecvt_mode(0))
  1966. {
  1967. const uint8_t* frm_nxt = frm;
  1968. if (mode & consume_header)
  1969. {
  1970. if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
  1971. frm_nxt[2] == 0xBF)
  1972. frm_nxt += 3;
  1973. }
  1974. for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
  1975. {
  1976. uint8_t c1 = *frm_nxt;
  1977. if (c1 > Maxcode)
  1978. break;
  1979. if (c1 < 0x80)
  1980. {
  1981. ++frm_nxt;
  1982. }
  1983. else if (c1 < 0xC2)
  1984. {
  1985. break;
  1986. }
  1987. else if (c1 < 0xE0)
  1988. {
  1989. if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
  1990. break;
  1991. uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
  1992. if (t > Maxcode)
  1993. break;
  1994. frm_nxt += 2;
  1995. }
  1996. else if (c1 < 0xF0)
  1997. {
  1998. if (frm_end-frm_nxt < 3)
  1999. break;
  2000. uint8_t c2 = frm_nxt[1];
  2001. uint8_t c3 = frm_nxt[2];
  2002. switch (c1)
  2003. {
  2004. case 0xE0:
  2005. if ((c2 & 0xE0) != 0xA0)
  2006. return static_cast<int>(frm_nxt - frm);
  2007. break;
  2008. case 0xED:
  2009. if ((c2 & 0xE0) != 0x80)
  2010. return static_cast<int>(frm_nxt - frm);
  2011. break;
  2012. default:
  2013. if ((c2 & 0xC0) != 0x80)
  2014. return static_cast<int>(frm_nxt - frm);
  2015. break;
  2016. }
  2017. if ((c3 & 0xC0) != 0x80)
  2018. break;
  2019. if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
  2020. break;
  2021. frm_nxt += 3;
  2022. }
  2023. else if (c1 < 0xF5)
  2024. {
  2025. if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
  2026. break;
  2027. uint8_t c2 = frm_nxt[1];
  2028. uint8_t c3 = frm_nxt[2];
  2029. uint8_t c4 = frm_nxt[3];
  2030. switch (c1)
  2031. {
  2032. case 0xF0:
  2033. if (!(0x90 <= c2 && c2 <= 0xBF))
  2034. return static_cast<int>(frm_nxt - frm);
  2035. break;
  2036. case 0xF4:
  2037. if ((c2 & 0xF0) != 0x80)
  2038. return static_cast<int>(frm_nxt - frm);
  2039. break;
  2040. default:
  2041. if ((c2 & 0xC0) != 0x80)
  2042. return static_cast<int>(frm_nxt - frm);
  2043. break;
  2044. }
  2045. if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
  2046. break;
  2047. if ((((c1 & 7UL) << 18) +
  2048. ((c2 & 0x3FUL) << 12) +
  2049. ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
  2050. break;
  2051. ++nchar16_t;
  2052. frm_nxt += 4;
  2053. }
  2054. else
  2055. {
  2056. break;
  2057. }
  2058. }
  2059. return static_cast<int>(frm_nxt - frm);
  2060. }
  2061. static
  2062. codecvt_base::result
  2063. ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
  2064. uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
  2065. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  2066. {
  2067. frm_nxt = frm;
  2068. to_nxt = to;
  2069. if (mode & generate_header)
  2070. {
  2071. if (to_end-to_nxt < 3)
  2072. return codecvt_base::partial;
  2073. *to_nxt++ = static_cast<uint8_t>(0xEF);
  2074. *to_nxt++ = static_cast<uint8_t>(0xBB);
  2075. *to_nxt++ = static_cast<uint8_t>(0xBF);
  2076. }
  2077. for (; frm_nxt < frm_end; ++frm_nxt)
  2078. {
  2079. uint32_t wc = *frm_nxt;
  2080. if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
  2081. return codecvt_base::error;
  2082. if (wc < 0x000080)
  2083. {
  2084. if (to_end-to_nxt < 1)
  2085. return codecvt_base::partial;
  2086. *to_nxt++ = static_cast<uint8_t>(wc);
  2087. }
  2088. else if (wc < 0x000800)
  2089. {
  2090. if (to_end-to_nxt < 2)
  2091. return codecvt_base::partial;
  2092. *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
  2093. *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
  2094. }
  2095. else if (wc < 0x010000)
  2096. {
  2097. if (to_end-to_nxt < 3)
  2098. return codecvt_base::partial;
  2099. *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
  2100. *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
  2101. *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
  2102. }
  2103. else // if (wc < 0x110000)
  2104. {
  2105. if (to_end-to_nxt < 4)
  2106. return codecvt_base::partial;
  2107. *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
  2108. *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
  2109. *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
  2110. *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
  2111. }
  2112. }
  2113. return codecvt_base::ok;
  2114. }
  2115. static
  2116. codecvt_base::result
  2117. utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
  2118. uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
  2119. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  2120. {
  2121. frm_nxt = frm;
  2122. to_nxt = to;
  2123. if (mode & consume_header)
  2124. {
  2125. if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
  2126. frm_nxt[2] == 0xBF)
  2127. frm_nxt += 3;
  2128. }
  2129. for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
  2130. {
  2131. uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
  2132. if (c1 < 0x80)
  2133. {
  2134. if (c1 > Maxcode)
  2135. return codecvt_base::error;
  2136. *to_nxt = static_cast<uint32_t>(c1);
  2137. ++frm_nxt;
  2138. }
  2139. else if (c1 < 0xC2)
  2140. {
  2141. return codecvt_base::error;
  2142. }
  2143. else if (c1 < 0xE0)
  2144. {
  2145. if (frm_end-frm_nxt < 2)
  2146. return codecvt_base::partial;
  2147. uint8_t c2 = frm_nxt[1];
  2148. if ((c2 & 0xC0) != 0x80)
  2149. return codecvt_base::error;
  2150. uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
  2151. | (c2 & 0x3F));
  2152. if (t > Maxcode)
  2153. return codecvt_base::error;
  2154. *to_nxt = t;
  2155. frm_nxt += 2;
  2156. }
  2157. else if (c1 < 0xF0)
  2158. {
  2159. if (frm_end-frm_nxt < 3)
  2160. return codecvt_base::partial;
  2161. uint8_t c2 = frm_nxt[1];
  2162. uint8_t c3 = frm_nxt[2];
  2163. switch (c1)
  2164. {
  2165. case 0xE0:
  2166. if ((c2 & 0xE0) != 0xA0)
  2167. return codecvt_base::error;
  2168. break;
  2169. case 0xED:
  2170. if ((c2 & 0xE0) != 0x80)
  2171. return codecvt_base::error;
  2172. break;
  2173. default:
  2174. if ((c2 & 0xC0) != 0x80)
  2175. return codecvt_base::error;
  2176. break;
  2177. }
  2178. if ((c3 & 0xC0) != 0x80)
  2179. return codecvt_base::error;
  2180. uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
  2181. | ((c2 & 0x3F) << 6)
  2182. | (c3 & 0x3F));
  2183. if (t > Maxcode)
  2184. return codecvt_base::error;
  2185. *to_nxt = t;
  2186. frm_nxt += 3;
  2187. }
  2188. else if (c1 < 0xF5)
  2189. {
  2190. if (frm_end-frm_nxt < 4)
  2191. return codecvt_base::partial;
  2192. uint8_t c2 = frm_nxt[1];
  2193. uint8_t c3 = frm_nxt[2];
  2194. uint8_t c4 = frm_nxt[3];
  2195. switch (c1)
  2196. {
  2197. case 0xF0:
  2198. if (!(0x90 <= c2 && c2 <= 0xBF))
  2199. return codecvt_base::error;
  2200. break;
  2201. case 0xF4:
  2202. if ((c2 & 0xF0) != 0x80)
  2203. return codecvt_base::error;
  2204. break;
  2205. default:
  2206. if ((c2 & 0xC0) != 0x80)
  2207. return codecvt_base::error;
  2208. break;
  2209. }
  2210. if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
  2211. return codecvt_base::error;
  2212. uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
  2213. | ((c2 & 0x3F) << 12)
  2214. | ((c3 & 0x3F) << 6)
  2215. | (c4 & 0x3F));
  2216. if (t > Maxcode)
  2217. return codecvt_base::error;
  2218. *to_nxt = t;
  2219. frm_nxt += 4;
  2220. }
  2221. else
  2222. {
  2223. return codecvt_base::error;
  2224. }
  2225. }
  2226. return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
  2227. }
  2228. static
  2229. int
  2230. utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
  2231. size_t mx, unsigned long Maxcode = 0x10FFFF,
  2232. codecvt_mode mode = codecvt_mode(0))
  2233. {
  2234. const uint8_t* frm_nxt = frm;
  2235. if (mode & consume_header)
  2236. {
  2237. if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
  2238. frm_nxt[2] == 0xBF)
  2239. frm_nxt += 3;
  2240. }
  2241. for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
  2242. {
  2243. uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
  2244. if (c1 < 0x80)
  2245. {
  2246. if (c1 > Maxcode)
  2247. break;
  2248. ++frm_nxt;
  2249. }
  2250. else if (c1 < 0xC2)
  2251. {
  2252. break;
  2253. }
  2254. else if (c1 < 0xE0)
  2255. {
  2256. if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
  2257. break;
  2258. if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
  2259. break;
  2260. frm_nxt += 2;
  2261. }
  2262. else if (c1 < 0xF0)
  2263. {
  2264. if (frm_end-frm_nxt < 3)
  2265. break;
  2266. uint8_t c2 = frm_nxt[1];
  2267. uint8_t c3 = frm_nxt[2];
  2268. switch (c1)
  2269. {
  2270. case 0xE0:
  2271. if ((c2 & 0xE0) != 0xA0)
  2272. return static_cast<int>(frm_nxt - frm);
  2273. break;
  2274. case 0xED:
  2275. if ((c2 & 0xE0) != 0x80)
  2276. return static_cast<int>(frm_nxt - frm);
  2277. break;
  2278. default:
  2279. if ((c2 & 0xC0) != 0x80)
  2280. return static_cast<int>(frm_nxt - frm);
  2281. break;
  2282. }
  2283. if ((c3 & 0xC0) != 0x80)
  2284. break;
  2285. if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
  2286. break;
  2287. frm_nxt += 3;
  2288. }
  2289. else if (c1 < 0xF5)
  2290. {
  2291. if (frm_end-frm_nxt < 4)
  2292. break;
  2293. uint8_t c2 = frm_nxt[1];
  2294. uint8_t c3 = frm_nxt[2];
  2295. uint8_t c4 = frm_nxt[3];
  2296. switch (c1)
  2297. {
  2298. case 0xF0:
  2299. if (!(0x90 <= c2 && c2 <= 0xBF))
  2300. return static_cast<int>(frm_nxt - frm);
  2301. break;
  2302. case 0xF4:
  2303. if ((c2 & 0xF0) != 0x80)
  2304. return static_cast<int>(frm_nxt - frm);
  2305. break;
  2306. default:
  2307. if ((c2 & 0xC0) != 0x80)
  2308. return static_cast<int>(frm_nxt - frm);
  2309. break;
  2310. }
  2311. if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
  2312. break;
  2313. if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
  2314. ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode)
  2315. break;
  2316. frm_nxt += 4;
  2317. }
  2318. else
  2319. {
  2320. break;
  2321. }
  2322. }
  2323. return static_cast<int>(frm_nxt - frm);
  2324. }
  2325. static
  2326. codecvt_base::result
  2327. ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
  2328. uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
  2329. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  2330. {
  2331. frm_nxt = frm;
  2332. to_nxt = to;
  2333. if (mode & generate_header)
  2334. {
  2335. if (to_end-to_nxt < 3)
  2336. return codecvt_base::partial;
  2337. *to_nxt++ = static_cast<uint8_t>(0xEF);
  2338. *to_nxt++ = static_cast<uint8_t>(0xBB);
  2339. *to_nxt++ = static_cast<uint8_t>(0xBF);
  2340. }
  2341. for (; frm_nxt < frm_end; ++frm_nxt)
  2342. {
  2343. uint16_t wc = *frm_nxt;
  2344. if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
  2345. return codecvt_base::error;
  2346. if (wc < 0x0080)
  2347. {
  2348. if (to_end-to_nxt < 1)
  2349. return codecvt_base::partial;
  2350. *to_nxt++ = static_cast<uint8_t>(wc);
  2351. }
  2352. else if (wc < 0x0800)
  2353. {
  2354. if (to_end-to_nxt < 2)
  2355. return codecvt_base::partial;
  2356. *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
  2357. *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
  2358. }
  2359. else // if (wc <= 0xFFFF)
  2360. {
  2361. if (to_end-to_nxt < 3)
  2362. return codecvt_base::partial;
  2363. *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
  2364. *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
  2365. *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
  2366. }
  2367. }
  2368. return codecvt_base::ok;
  2369. }
  2370. static
  2371. codecvt_base::result
  2372. utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
  2373. uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
  2374. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  2375. {
  2376. frm_nxt = frm;
  2377. to_nxt = to;
  2378. if (mode & consume_header)
  2379. {
  2380. if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
  2381. frm_nxt[2] == 0xBF)
  2382. frm_nxt += 3;
  2383. }
  2384. for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
  2385. {
  2386. uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
  2387. if (c1 < 0x80)
  2388. {
  2389. if (c1 > Maxcode)
  2390. return codecvt_base::error;
  2391. *to_nxt = static_cast<uint16_t>(c1);
  2392. ++frm_nxt;
  2393. }
  2394. else if (c1 < 0xC2)
  2395. {
  2396. return codecvt_base::error;
  2397. }
  2398. else if (c1 < 0xE0)
  2399. {
  2400. if (frm_end-frm_nxt < 2)
  2401. return codecvt_base::partial;
  2402. uint8_t c2 = frm_nxt[1];
  2403. if ((c2 & 0xC0) != 0x80)
  2404. return codecvt_base::error;
  2405. uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
  2406. | (c2 & 0x3F));
  2407. if (t > Maxcode)
  2408. return codecvt_base::error;
  2409. *to_nxt = t;
  2410. frm_nxt += 2;
  2411. }
  2412. else if (c1 < 0xF0)
  2413. {
  2414. if (frm_end-frm_nxt < 3)
  2415. return codecvt_base::partial;
  2416. uint8_t c2 = frm_nxt[1];
  2417. uint8_t c3 = frm_nxt[2];
  2418. switch (c1)
  2419. {
  2420. case 0xE0:
  2421. if ((c2 & 0xE0) != 0xA0)
  2422. return codecvt_base::error;
  2423. break;
  2424. case 0xED:
  2425. if ((c2 & 0xE0) != 0x80)
  2426. return codecvt_base::error;
  2427. break;
  2428. default:
  2429. if ((c2 & 0xC0) != 0x80)
  2430. return codecvt_base::error;
  2431. break;
  2432. }
  2433. if ((c3 & 0xC0) != 0x80)
  2434. return codecvt_base::error;
  2435. uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
  2436. | ((c2 & 0x3F) << 6)
  2437. | (c3 & 0x3F));
  2438. if (t > Maxcode)
  2439. return codecvt_base::error;
  2440. *to_nxt = t;
  2441. frm_nxt += 3;
  2442. }
  2443. else
  2444. {
  2445. return codecvt_base::error;
  2446. }
  2447. }
  2448. return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
  2449. }
  2450. static
  2451. int
  2452. utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
  2453. size_t mx, unsigned long Maxcode = 0x10FFFF,
  2454. codecvt_mode mode = codecvt_mode(0))
  2455. {
  2456. const uint8_t* frm_nxt = frm;
  2457. if (mode & consume_header)
  2458. {
  2459. if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
  2460. frm_nxt[2] == 0xBF)
  2461. frm_nxt += 3;
  2462. }
  2463. for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
  2464. {
  2465. uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
  2466. if (c1 < 0x80)
  2467. {
  2468. if (c1 > Maxcode)
  2469. break;
  2470. ++frm_nxt;
  2471. }
  2472. else if (c1 < 0xC2)
  2473. {
  2474. break;
  2475. }
  2476. else if (c1 < 0xE0)
  2477. {
  2478. if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
  2479. break;
  2480. if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
  2481. break;
  2482. frm_nxt += 2;
  2483. }
  2484. else if (c1 < 0xF0)
  2485. {
  2486. if (frm_end-frm_nxt < 3)
  2487. break;
  2488. uint8_t c2 = frm_nxt[1];
  2489. uint8_t c3 = frm_nxt[2];
  2490. switch (c1)
  2491. {
  2492. case 0xE0:
  2493. if ((c2 & 0xE0) != 0xA0)
  2494. return static_cast<int>(frm_nxt - frm);
  2495. break;
  2496. case 0xED:
  2497. if ((c2 & 0xE0) != 0x80)
  2498. return static_cast<int>(frm_nxt - frm);
  2499. break;
  2500. default:
  2501. if ((c2 & 0xC0) != 0x80)
  2502. return static_cast<int>(frm_nxt - frm);
  2503. break;
  2504. }
  2505. if ((c3 & 0xC0) != 0x80)
  2506. break;
  2507. if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
  2508. break;
  2509. frm_nxt += 3;
  2510. }
  2511. else
  2512. {
  2513. break;
  2514. }
  2515. }
  2516. return static_cast<int>(frm_nxt - frm);
  2517. }
  2518. static
  2519. codecvt_base::result
  2520. ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
  2521. uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
  2522. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  2523. {
  2524. frm_nxt = frm;
  2525. to_nxt = to;
  2526. if (mode & generate_header)
  2527. {
  2528. if (to_end-to_nxt < 2)
  2529. return codecvt_base::partial;
  2530. *to_nxt++ = static_cast<uint8_t>(0xFE);
  2531. *to_nxt++ = static_cast<uint8_t>(0xFF);
  2532. }
  2533. for (; frm_nxt < frm_end; ++frm_nxt)
  2534. {
  2535. uint32_t wc = *frm_nxt;
  2536. if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
  2537. return codecvt_base::error;
  2538. if (wc < 0x010000)
  2539. {
  2540. if (to_end-to_nxt < 2)
  2541. return codecvt_base::partial;
  2542. *to_nxt++ = static_cast<uint8_t>(wc >> 8);
  2543. *to_nxt++ = static_cast<uint8_t>(wc);
  2544. }
  2545. else
  2546. {
  2547. if (to_end-to_nxt < 4)
  2548. return codecvt_base::partial;
  2549. uint16_t t = static_cast<uint16_t>(
  2550. 0xD800
  2551. | ((((wc & 0x1F0000) >> 16) - 1) << 6)
  2552. | ((wc & 0x00FC00) >> 10));
  2553. *to_nxt++ = static_cast<uint8_t>(t >> 8);
  2554. *to_nxt++ = static_cast<uint8_t>(t);
  2555. t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
  2556. *to_nxt++ = static_cast<uint8_t>(t >> 8);
  2557. *to_nxt++ = static_cast<uint8_t>(t);
  2558. }
  2559. }
  2560. return codecvt_base::ok;
  2561. }
  2562. static
  2563. codecvt_base::result
  2564. utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
  2565. uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
  2566. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  2567. {
  2568. frm_nxt = frm;
  2569. to_nxt = to;
  2570. if (mode & consume_header)
  2571. {
  2572. if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
  2573. frm_nxt += 2;
  2574. }
  2575. for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
  2576. {
  2577. uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
  2578. if ((c1 & 0xFC00) == 0xDC00)
  2579. return codecvt_base::error;
  2580. if ((c1 & 0xFC00) != 0xD800)
  2581. {
  2582. if (c1 > Maxcode)
  2583. return codecvt_base::error;
  2584. *to_nxt = static_cast<uint32_t>(c1);
  2585. frm_nxt += 2;
  2586. }
  2587. else
  2588. {
  2589. if (frm_end-frm_nxt < 4)
  2590. return codecvt_base::partial;
  2591. uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
  2592. if ((c2 & 0xFC00) != 0xDC00)
  2593. return codecvt_base::error;
  2594. uint32_t t = static_cast<uint32_t>(
  2595. ((((c1 & 0x03C0) >> 6) + 1) << 16)
  2596. | ((c1 & 0x003F) << 10)
  2597. | (c2 & 0x03FF));
  2598. if (t > Maxcode)
  2599. return codecvt_base::error;
  2600. *to_nxt = t;
  2601. frm_nxt += 4;
  2602. }
  2603. }
  2604. return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
  2605. }
  2606. static
  2607. int
  2608. utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
  2609. size_t mx, unsigned long Maxcode = 0x10FFFF,
  2610. codecvt_mode mode = codecvt_mode(0))
  2611. {
  2612. const uint8_t* frm_nxt = frm;
  2613. if (mode & consume_header)
  2614. {
  2615. if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
  2616. frm_nxt += 2;
  2617. }
  2618. for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
  2619. {
  2620. uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
  2621. if ((c1 & 0xFC00) == 0xDC00)
  2622. break;
  2623. if ((c1 & 0xFC00) != 0xD800)
  2624. {
  2625. if (c1 > Maxcode)
  2626. break;
  2627. frm_nxt += 2;
  2628. }
  2629. else
  2630. {
  2631. if (frm_end-frm_nxt < 4)
  2632. break;
  2633. uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
  2634. if ((c2 & 0xFC00) != 0xDC00)
  2635. break;
  2636. uint32_t t = static_cast<uint32_t>(
  2637. ((((c1 & 0x03C0) >> 6) + 1) << 16)
  2638. | ((c1 & 0x003F) << 10)
  2639. | (c2 & 0x03FF));
  2640. if (t > Maxcode)
  2641. break;
  2642. frm_nxt += 4;
  2643. }
  2644. }
  2645. return static_cast<int>(frm_nxt - frm);
  2646. }
  2647. static
  2648. codecvt_base::result
  2649. ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
  2650. uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
  2651. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  2652. {
  2653. frm_nxt = frm;
  2654. to_nxt = to;
  2655. if (mode & generate_header)
  2656. {
  2657. if (to_end - to_nxt < 2)
  2658. return codecvt_base::partial;
  2659. *to_nxt++ = static_cast<uint8_t>(0xFF);
  2660. *to_nxt++ = static_cast<uint8_t>(0xFE);
  2661. }
  2662. for (; frm_nxt < frm_end; ++frm_nxt)
  2663. {
  2664. uint32_t wc = *frm_nxt;
  2665. if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
  2666. return codecvt_base::error;
  2667. if (wc < 0x010000)
  2668. {
  2669. if (to_end-to_nxt < 2)
  2670. return codecvt_base::partial;
  2671. *to_nxt++ = static_cast<uint8_t>(wc);
  2672. *to_nxt++ = static_cast<uint8_t>(wc >> 8);
  2673. }
  2674. else
  2675. {
  2676. if (to_end-to_nxt < 4)
  2677. return codecvt_base::partial;
  2678. uint16_t t = static_cast<uint16_t>(
  2679. 0xD800
  2680. | ((((wc & 0x1F0000) >> 16) - 1) << 6)
  2681. | ((wc & 0x00FC00) >> 10));
  2682. *to_nxt++ = static_cast<uint8_t>(t);
  2683. *to_nxt++ = static_cast<uint8_t>(t >> 8);
  2684. t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
  2685. *to_nxt++ = static_cast<uint8_t>(t);
  2686. *to_nxt++ = static_cast<uint8_t>(t >> 8);
  2687. }
  2688. }
  2689. return codecvt_base::ok;
  2690. }
  2691. static
  2692. codecvt_base::result
  2693. utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
  2694. uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
  2695. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  2696. {
  2697. frm_nxt = frm;
  2698. to_nxt = to;
  2699. if (mode & consume_header)
  2700. {
  2701. if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
  2702. frm_nxt += 2;
  2703. }
  2704. for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
  2705. {
  2706. uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
  2707. if ((c1 & 0xFC00) == 0xDC00)
  2708. return codecvt_base::error;
  2709. if ((c1 & 0xFC00) != 0xD800)
  2710. {
  2711. if (c1 > Maxcode)
  2712. return codecvt_base::error;
  2713. *to_nxt = static_cast<uint32_t>(c1);
  2714. frm_nxt += 2;
  2715. }
  2716. else
  2717. {
  2718. if (frm_end-frm_nxt < 4)
  2719. return codecvt_base::partial;
  2720. uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
  2721. if ((c2 & 0xFC00) != 0xDC00)
  2722. return codecvt_base::error;
  2723. uint32_t t = static_cast<uint32_t>(
  2724. ((((c1 & 0x03C0) >> 6) + 1) << 16)
  2725. | ((c1 & 0x003F) << 10)
  2726. | (c2 & 0x03FF));
  2727. if (t > Maxcode)
  2728. return codecvt_base::error;
  2729. *to_nxt = t;
  2730. frm_nxt += 4;
  2731. }
  2732. }
  2733. return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
  2734. }
  2735. static
  2736. int
  2737. utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
  2738. size_t mx, unsigned long Maxcode = 0x10FFFF,
  2739. codecvt_mode mode = codecvt_mode(0))
  2740. {
  2741. const uint8_t* frm_nxt = frm;
  2742. if (mode & consume_header)
  2743. {
  2744. if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
  2745. frm_nxt += 2;
  2746. }
  2747. for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
  2748. {
  2749. uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
  2750. if ((c1 & 0xFC00) == 0xDC00)
  2751. break;
  2752. if ((c1 & 0xFC00) != 0xD800)
  2753. {
  2754. if (c1 > Maxcode)
  2755. break;
  2756. frm_nxt += 2;
  2757. }
  2758. else
  2759. {
  2760. if (frm_end-frm_nxt < 4)
  2761. break;
  2762. uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
  2763. if ((c2 & 0xFC00) != 0xDC00)
  2764. break;
  2765. uint32_t t = static_cast<uint32_t>(
  2766. ((((c1 & 0x03C0) >> 6) + 1) << 16)
  2767. | ((c1 & 0x003F) << 10)
  2768. | (c2 & 0x03FF));
  2769. if (t > Maxcode)
  2770. break;
  2771. frm_nxt += 4;
  2772. }
  2773. }
  2774. return static_cast<int>(frm_nxt - frm);
  2775. }
  2776. static
  2777. codecvt_base::result
  2778. ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
  2779. uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
  2780. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  2781. {
  2782. frm_nxt = frm;
  2783. to_nxt = to;
  2784. if (mode & generate_header)
  2785. {
  2786. if (to_end-to_nxt < 2)
  2787. return codecvt_base::partial;
  2788. *to_nxt++ = static_cast<uint8_t>(0xFE);
  2789. *to_nxt++ = static_cast<uint8_t>(0xFF);
  2790. }
  2791. for (; frm_nxt < frm_end; ++frm_nxt)
  2792. {
  2793. uint16_t wc = *frm_nxt;
  2794. if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
  2795. return codecvt_base::error;
  2796. if (to_end-to_nxt < 2)
  2797. return codecvt_base::partial;
  2798. *to_nxt++ = static_cast<uint8_t>(wc >> 8);
  2799. *to_nxt++ = static_cast<uint8_t>(wc);
  2800. }
  2801. return codecvt_base::ok;
  2802. }
  2803. static
  2804. codecvt_base::result
  2805. utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
  2806. uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
  2807. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  2808. {
  2809. frm_nxt = frm;
  2810. to_nxt = to;
  2811. if (mode & consume_header)
  2812. {
  2813. if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
  2814. frm_nxt += 2;
  2815. }
  2816. for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
  2817. {
  2818. uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
  2819. if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
  2820. return codecvt_base::error;
  2821. *to_nxt = c1;
  2822. frm_nxt += 2;
  2823. }
  2824. return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
  2825. }
  2826. static
  2827. int
  2828. utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
  2829. size_t mx, unsigned long Maxcode = 0x10FFFF,
  2830. codecvt_mode mode = codecvt_mode(0))
  2831. {
  2832. const uint8_t* frm_nxt = frm;
  2833. if (mode & consume_header)
  2834. {
  2835. if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
  2836. frm_nxt += 2;
  2837. }
  2838. for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
  2839. {
  2840. uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
  2841. if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
  2842. break;
  2843. frm_nxt += 2;
  2844. }
  2845. return static_cast<int>(frm_nxt - frm);
  2846. }
  2847. static
  2848. codecvt_base::result
  2849. ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
  2850. uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
  2851. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  2852. {
  2853. frm_nxt = frm;
  2854. to_nxt = to;
  2855. if (mode & generate_header)
  2856. {
  2857. if (to_end-to_nxt < 2)
  2858. return codecvt_base::partial;
  2859. *to_nxt++ = static_cast<uint8_t>(0xFF);
  2860. *to_nxt++ = static_cast<uint8_t>(0xFE);
  2861. }
  2862. for (; frm_nxt < frm_end; ++frm_nxt)
  2863. {
  2864. uint16_t wc = *frm_nxt;
  2865. if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
  2866. return codecvt_base::error;
  2867. if (to_end-to_nxt < 2)
  2868. return codecvt_base::partial;
  2869. *to_nxt++ = static_cast<uint8_t>(wc);
  2870. *to_nxt++ = static_cast<uint8_t>(wc >> 8);
  2871. }
  2872. return codecvt_base::ok;
  2873. }
  2874. static
  2875. codecvt_base::result
  2876. utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
  2877. uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
  2878. unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
  2879. {
  2880. frm_nxt = frm;
  2881. to_nxt = to;
  2882. if (mode & consume_header)
  2883. {
  2884. if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
  2885. frm_nxt += 2;
  2886. }
  2887. for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
  2888. {
  2889. uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
  2890. if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
  2891. return codecvt_base::error;
  2892. *to_nxt = c1;
  2893. frm_nxt += 2;
  2894. }
  2895. return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
  2896. }
  2897. static
  2898. int
  2899. utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
  2900. size_t mx, unsigned long Maxcode = 0x10FFFF,
  2901. codecvt_mode mode = codecvt_mode(0))
  2902. {
  2903. const uint8_t* frm_nxt = frm;
  2904. frm_nxt = frm;
  2905. if (mode & consume_header)
  2906. {
  2907. if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
  2908. frm_nxt += 2;
  2909. }
  2910. for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
  2911. {
  2912. uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
  2913. if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
  2914. break;
  2915. frm_nxt += 2;
  2916. }
  2917. return static_cast<int>(frm_nxt - frm);
  2918. }
  2919. // template <> class codecvt<char16_t, char, mbstate_t>
  2920. locale::id codecvt<char16_t, char, mbstate_t>::id;
  2921. codecvt<char16_t, char, mbstate_t>::~codecvt()
  2922. {
  2923. }
  2924. codecvt<char16_t, char, mbstate_t>::result
  2925. codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
  2926. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  2927. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  2928. {
  2929. const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
  2930. const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
  2931. const uint16_t* _frm_nxt = _frm;
  2932. uint8_t* _to = reinterpret_cast<uint8_t*>(to);
  2933. uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
  2934. uint8_t* _to_nxt = _to;
  2935. result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
  2936. frm_nxt = frm + (_frm_nxt - _frm);
  2937. to_nxt = to + (_to_nxt - _to);
  2938. return r;
  2939. }
  2940. codecvt<char16_t, char, mbstate_t>::result
  2941. codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
  2942. const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
  2943. intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
  2944. {
  2945. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  2946. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  2947. const uint8_t* _frm_nxt = _frm;
  2948. uint16_t* _to = reinterpret_cast<uint16_t*>(to);
  2949. uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
  2950. uint16_t* _to_nxt = _to;
  2951. result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
  2952. frm_nxt = frm + (_frm_nxt - _frm);
  2953. to_nxt = to + (_to_nxt - _to);
  2954. return r;
  2955. }
  2956. codecvt<char16_t, char, mbstate_t>::result
  2957. codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
  2958. extern_type* to, extern_type*, extern_type*& to_nxt) const
  2959. {
  2960. to_nxt = to;
  2961. return noconv;
  2962. }
  2963. int
  2964. codecvt<char16_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
  2965. {
  2966. return 0;
  2967. }
  2968. bool
  2969. codecvt<char16_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
  2970. {
  2971. return false;
  2972. }
  2973. int
  2974. codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
  2975. const extern_type* frm, const extern_type* frm_end, size_t mx) const
  2976. {
  2977. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  2978. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  2979. return utf8_to_utf16_length(_frm, _frm_end, mx);
  2980. }
  2981. int
  2982. codecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
  2983. {
  2984. return 4;
  2985. }
  2986. // template <> class codecvt<char32_t, char, mbstate_t>
  2987. locale::id codecvt<char32_t, char, mbstate_t>::id;
  2988. codecvt<char32_t, char, mbstate_t>::~codecvt()
  2989. {
  2990. }
  2991. codecvt<char32_t, char, mbstate_t>::result
  2992. codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
  2993. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  2994. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  2995. {
  2996. const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
  2997. const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
  2998. const uint32_t* _frm_nxt = _frm;
  2999. uint8_t* _to = reinterpret_cast<uint8_t*>(to);
  3000. uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
  3001. uint8_t* _to_nxt = _to;
  3002. result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
  3003. frm_nxt = frm + (_frm_nxt - _frm);
  3004. to_nxt = to + (_to_nxt - _to);
  3005. return r;
  3006. }
  3007. codecvt<char32_t, char, mbstate_t>::result
  3008. codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
  3009. const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
  3010. intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
  3011. {
  3012. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3013. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3014. const uint8_t* _frm_nxt = _frm;
  3015. uint32_t* _to = reinterpret_cast<uint32_t*>(to);
  3016. uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
  3017. uint32_t* _to_nxt = _to;
  3018. result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
  3019. frm_nxt = frm + (_frm_nxt - _frm);
  3020. to_nxt = to + (_to_nxt - _to);
  3021. return r;
  3022. }
  3023. codecvt<char32_t, char, mbstate_t>::result
  3024. codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
  3025. extern_type* to, extern_type*, extern_type*& to_nxt) const
  3026. {
  3027. to_nxt = to;
  3028. return noconv;
  3029. }
  3030. int
  3031. codecvt<char32_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
  3032. {
  3033. return 0;
  3034. }
  3035. bool
  3036. codecvt<char32_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
  3037. {
  3038. return false;
  3039. }
  3040. int
  3041. codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
  3042. const extern_type* frm, const extern_type* frm_end, size_t mx) const
  3043. {
  3044. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3045. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3046. return utf8_to_ucs4_length(_frm, _frm_end, mx);
  3047. }
  3048. int
  3049. codecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
  3050. {
  3051. return 4;
  3052. }
  3053. // __codecvt_utf8<wchar_t>
  3054. __codecvt_utf8<wchar_t>::result
  3055. __codecvt_utf8<wchar_t>::do_out(state_type&,
  3056. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  3057. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  3058. {
  3059. #if _WIN32
  3060. const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
  3061. const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
  3062. const uint16_t* _frm_nxt = _frm;
  3063. #else
  3064. const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
  3065. const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
  3066. const uint32_t* _frm_nxt = _frm;
  3067. #endif
  3068. uint8_t* _to = reinterpret_cast<uint8_t*>(to);
  3069. uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
  3070. uint8_t* _to_nxt = _to;
  3071. #if _WIN32
  3072. result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3073. _Maxcode_, _Mode_);
  3074. #else
  3075. result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3076. _Maxcode_, _Mode_);
  3077. #endif
  3078. frm_nxt = frm + (_frm_nxt - _frm);
  3079. to_nxt = to + (_to_nxt - _to);
  3080. return r;
  3081. }
  3082. __codecvt_utf8<wchar_t>::result
  3083. __codecvt_utf8<wchar_t>::do_in(state_type&,
  3084. const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
  3085. intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
  3086. {
  3087. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3088. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3089. const uint8_t* _frm_nxt = _frm;
  3090. #if _WIN32
  3091. uint16_t* _to = reinterpret_cast<uint16_t*>(to);
  3092. uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
  3093. uint16_t* _to_nxt = _to;
  3094. result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3095. _Maxcode_, _Mode_);
  3096. #else
  3097. uint32_t* _to = reinterpret_cast<uint32_t*>(to);
  3098. uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
  3099. uint32_t* _to_nxt = _to;
  3100. result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3101. _Maxcode_, _Mode_);
  3102. #endif
  3103. frm_nxt = frm + (_frm_nxt - _frm);
  3104. to_nxt = to + (_to_nxt - _to);
  3105. return r;
  3106. }
  3107. __codecvt_utf8<wchar_t>::result
  3108. __codecvt_utf8<wchar_t>::do_unshift(state_type&,
  3109. extern_type* to, extern_type*, extern_type*& to_nxt) const
  3110. {
  3111. to_nxt = to;
  3112. return noconv;
  3113. }
  3114. int
  3115. __codecvt_utf8<wchar_t>::do_encoding() const _NOEXCEPT
  3116. {
  3117. return 0;
  3118. }
  3119. bool
  3120. __codecvt_utf8<wchar_t>::do_always_noconv() const _NOEXCEPT
  3121. {
  3122. return false;
  3123. }
  3124. int
  3125. __codecvt_utf8<wchar_t>::do_length(state_type&,
  3126. const extern_type* frm, const extern_type* frm_end, size_t mx) const
  3127. {
  3128. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3129. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3130. return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
  3131. }
  3132. int
  3133. __codecvt_utf8<wchar_t>::do_max_length() const _NOEXCEPT
  3134. {
  3135. if (_Mode_ & consume_header)
  3136. return 7;
  3137. return 4;
  3138. }
  3139. // __codecvt_utf8<char16_t>
  3140. __codecvt_utf8<char16_t>::result
  3141. __codecvt_utf8<char16_t>::do_out(state_type&,
  3142. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  3143. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  3144. {
  3145. const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
  3146. const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
  3147. const uint16_t* _frm_nxt = _frm;
  3148. uint8_t* _to = reinterpret_cast<uint8_t*>(to);
  3149. uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
  3150. uint8_t* _to_nxt = _to;
  3151. result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3152. _Maxcode_, _Mode_);
  3153. frm_nxt = frm + (_frm_nxt - _frm);
  3154. to_nxt = to + (_to_nxt - _to);
  3155. return r;
  3156. }
  3157. __codecvt_utf8<char16_t>::result
  3158. __codecvt_utf8<char16_t>::do_in(state_type&,
  3159. const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
  3160. intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
  3161. {
  3162. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3163. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3164. const uint8_t* _frm_nxt = _frm;
  3165. uint16_t* _to = reinterpret_cast<uint16_t*>(to);
  3166. uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
  3167. uint16_t* _to_nxt = _to;
  3168. result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3169. _Maxcode_, _Mode_);
  3170. frm_nxt = frm + (_frm_nxt - _frm);
  3171. to_nxt = to + (_to_nxt - _to);
  3172. return r;
  3173. }
  3174. __codecvt_utf8<char16_t>::result
  3175. __codecvt_utf8<char16_t>::do_unshift(state_type&,
  3176. extern_type* to, extern_type*, extern_type*& to_nxt) const
  3177. {
  3178. to_nxt = to;
  3179. return noconv;
  3180. }
  3181. int
  3182. __codecvt_utf8<char16_t>::do_encoding() const _NOEXCEPT
  3183. {
  3184. return 0;
  3185. }
  3186. bool
  3187. __codecvt_utf8<char16_t>::do_always_noconv() const _NOEXCEPT
  3188. {
  3189. return false;
  3190. }
  3191. int
  3192. __codecvt_utf8<char16_t>::do_length(state_type&,
  3193. const extern_type* frm, const extern_type* frm_end, size_t mx) const
  3194. {
  3195. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3196. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3197. return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
  3198. }
  3199. int
  3200. __codecvt_utf8<char16_t>::do_max_length() const _NOEXCEPT
  3201. {
  3202. if (_Mode_ & consume_header)
  3203. return 6;
  3204. return 3;
  3205. }
  3206. // __codecvt_utf8<char32_t>
  3207. __codecvt_utf8<char32_t>::result
  3208. __codecvt_utf8<char32_t>::do_out(state_type&,
  3209. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  3210. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  3211. {
  3212. const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
  3213. const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
  3214. const uint32_t* _frm_nxt = _frm;
  3215. uint8_t* _to = reinterpret_cast<uint8_t*>(to);
  3216. uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
  3217. uint8_t* _to_nxt = _to;
  3218. result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3219. _Maxcode_, _Mode_);
  3220. frm_nxt = frm + (_frm_nxt - _frm);
  3221. to_nxt = to + (_to_nxt - _to);
  3222. return r;
  3223. }
  3224. __codecvt_utf8<char32_t>::result
  3225. __codecvt_utf8<char32_t>::do_in(state_type&,
  3226. const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
  3227. intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
  3228. {
  3229. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3230. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3231. const uint8_t* _frm_nxt = _frm;
  3232. uint32_t* _to = reinterpret_cast<uint32_t*>(to);
  3233. uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
  3234. uint32_t* _to_nxt = _to;
  3235. result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3236. _Maxcode_, _Mode_);
  3237. frm_nxt = frm + (_frm_nxt - _frm);
  3238. to_nxt = to + (_to_nxt - _to);
  3239. return r;
  3240. }
  3241. __codecvt_utf8<char32_t>::result
  3242. __codecvt_utf8<char32_t>::do_unshift(state_type&,
  3243. extern_type* to, extern_type*, extern_type*& to_nxt) const
  3244. {
  3245. to_nxt = to;
  3246. return noconv;
  3247. }
  3248. int
  3249. __codecvt_utf8<char32_t>::do_encoding() const _NOEXCEPT
  3250. {
  3251. return 0;
  3252. }
  3253. bool
  3254. __codecvt_utf8<char32_t>::do_always_noconv() const _NOEXCEPT
  3255. {
  3256. return false;
  3257. }
  3258. int
  3259. __codecvt_utf8<char32_t>::do_length(state_type&,
  3260. const extern_type* frm, const extern_type* frm_end, size_t mx) const
  3261. {
  3262. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3263. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3264. return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
  3265. }
  3266. int
  3267. __codecvt_utf8<char32_t>::do_max_length() const _NOEXCEPT
  3268. {
  3269. if (_Mode_ & consume_header)
  3270. return 7;
  3271. return 4;
  3272. }
  3273. // __codecvt_utf16<wchar_t, false>
  3274. __codecvt_utf16<wchar_t, false>::result
  3275. __codecvt_utf16<wchar_t, false>::do_out(state_type&,
  3276. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  3277. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  3278. {
  3279. const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
  3280. const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
  3281. const uint32_t* _frm_nxt = _frm;
  3282. uint8_t* _to = reinterpret_cast<uint8_t*>(to);
  3283. uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
  3284. uint8_t* _to_nxt = _to;
  3285. result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3286. _Maxcode_, _Mode_);
  3287. frm_nxt = frm + (_frm_nxt - _frm);
  3288. to_nxt = to + (_to_nxt - _to);
  3289. return r;
  3290. }
  3291. __codecvt_utf16<wchar_t, false>::result
  3292. __codecvt_utf16<wchar_t, false>::do_in(state_type&,
  3293. const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
  3294. intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
  3295. {
  3296. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3297. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3298. const uint8_t* _frm_nxt = _frm;
  3299. uint32_t* _to = reinterpret_cast<uint32_t*>(to);
  3300. uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
  3301. uint32_t* _to_nxt = _to;
  3302. result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3303. _Maxcode_, _Mode_);
  3304. frm_nxt = frm + (_frm_nxt - _frm);
  3305. to_nxt = to + (_to_nxt - _to);
  3306. return r;
  3307. }
  3308. __codecvt_utf16<wchar_t, false>::result
  3309. __codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
  3310. extern_type* to, extern_type*, extern_type*& to_nxt) const
  3311. {
  3312. to_nxt = to;
  3313. return noconv;
  3314. }
  3315. int
  3316. __codecvt_utf16<wchar_t, false>::do_encoding() const _NOEXCEPT
  3317. {
  3318. return 0;
  3319. }
  3320. bool
  3321. __codecvt_utf16<wchar_t, false>::do_always_noconv() const _NOEXCEPT
  3322. {
  3323. return false;
  3324. }
  3325. int
  3326. __codecvt_utf16<wchar_t, false>::do_length(state_type&,
  3327. const extern_type* frm, const extern_type* frm_end, size_t mx) const
  3328. {
  3329. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3330. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3331. return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
  3332. }
  3333. int
  3334. __codecvt_utf16<wchar_t, false>::do_max_length() const _NOEXCEPT
  3335. {
  3336. if (_Mode_ & consume_header)
  3337. return 6;
  3338. return 4;
  3339. }
  3340. // __codecvt_utf16<wchar_t, true>
  3341. __codecvt_utf16<wchar_t, true>::result
  3342. __codecvt_utf16<wchar_t, true>::do_out(state_type&,
  3343. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  3344. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  3345. {
  3346. const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
  3347. const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
  3348. const uint32_t* _frm_nxt = _frm;
  3349. uint8_t* _to = reinterpret_cast<uint8_t*>(to);
  3350. uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
  3351. uint8_t* _to_nxt = _to;
  3352. result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3353. _Maxcode_, _Mode_);
  3354. frm_nxt = frm + (_frm_nxt - _frm);
  3355. to_nxt = to + (_to_nxt - _to);
  3356. return r;
  3357. }
  3358. __codecvt_utf16<wchar_t, true>::result
  3359. __codecvt_utf16<wchar_t, true>::do_in(state_type&,
  3360. const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
  3361. intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
  3362. {
  3363. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3364. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3365. const uint8_t* _frm_nxt = _frm;
  3366. uint32_t* _to = reinterpret_cast<uint32_t*>(to);
  3367. uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
  3368. uint32_t* _to_nxt = _to;
  3369. result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3370. _Maxcode_, _Mode_);
  3371. frm_nxt = frm + (_frm_nxt - _frm);
  3372. to_nxt = to + (_to_nxt - _to);
  3373. return r;
  3374. }
  3375. __codecvt_utf16<wchar_t, true>::result
  3376. __codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
  3377. extern_type* to, extern_type*, extern_type*& to_nxt) const
  3378. {
  3379. to_nxt = to;
  3380. return noconv;
  3381. }
  3382. int
  3383. __codecvt_utf16<wchar_t, true>::do_encoding() const _NOEXCEPT
  3384. {
  3385. return 0;
  3386. }
  3387. bool
  3388. __codecvt_utf16<wchar_t, true>::do_always_noconv() const _NOEXCEPT
  3389. {
  3390. return false;
  3391. }
  3392. int
  3393. __codecvt_utf16<wchar_t, true>::do_length(state_type&,
  3394. const extern_type* frm, const extern_type* frm_end, size_t mx) const
  3395. {
  3396. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3397. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3398. return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
  3399. }
  3400. int
  3401. __codecvt_utf16<wchar_t, true>::do_max_length() const _NOEXCEPT
  3402. {
  3403. if (_Mode_ & consume_header)
  3404. return 6;
  3405. return 4;
  3406. }
  3407. // __codecvt_utf16<char16_t, false>
  3408. __codecvt_utf16<char16_t, false>::result
  3409. __codecvt_utf16<char16_t, false>::do_out(state_type&,
  3410. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  3411. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  3412. {
  3413. const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
  3414. const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
  3415. const uint16_t* _frm_nxt = _frm;
  3416. uint8_t* _to = reinterpret_cast<uint8_t*>(to);
  3417. uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
  3418. uint8_t* _to_nxt = _to;
  3419. result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3420. _Maxcode_, _Mode_);
  3421. frm_nxt = frm + (_frm_nxt - _frm);
  3422. to_nxt = to + (_to_nxt - _to);
  3423. return r;
  3424. }
  3425. __codecvt_utf16<char16_t, false>::result
  3426. __codecvt_utf16<char16_t, false>::do_in(state_type&,
  3427. const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
  3428. intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
  3429. {
  3430. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3431. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3432. const uint8_t* _frm_nxt = _frm;
  3433. uint16_t* _to = reinterpret_cast<uint16_t*>(to);
  3434. uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
  3435. uint16_t* _to_nxt = _to;
  3436. result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3437. _Maxcode_, _Mode_);
  3438. frm_nxt = frm + (_frm_nxt - _frm);
  3439. to_nxt = to + (_to_nxt - _to);
  3440. return r;
  3441. }
  3442. __codecvt_utf16<char16_t, false>::result
  3443. __codecvt_utf16<char16_t, false>::do_unshift(state_type&,
  3444. extern_type* to, extern_type*, extern_type*& to_nxt) const
  3445. {
  3446. to_nxt = to;
  3447. return noconv;
  3448. }
  3449. int
  3450. __codecvt_utf16<char16_t, false>::do_encoding() const _NOEXCEPT
  3451. {
  3452. return 0;
  3453. }
  3454. bool
  3455. __codecvt_utf16<char16_t, false>::do_always_noconv() const _NOEXCEPT
  3456. {
  3457. return false;
  3458. }
  3459. int
  3460. __codecvt_utf16<char16_t, false>::do_length(state_type&,
  3461. const extern_type* frm, const extern_type* frm_end, size_t mx) const
  3462. {
  3463. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3464. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3465. return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
  3466. }
  3467. int
  3468. __codecvt_utf16<char16_t, false>::do_max_length() const _NOEXCEPT
  3469. {
  3470. if (_Mode_ & consume_header)
  3471. return 4;
  3472. return 2;
  3473. }
  3474. // __codecvt_utf16<char16_t, true>
  3475. __codecvt_utf16<char16_t, true>::result
  3476. __codecvt_utf16<char16_t, true>::do_out(state_type&,
  3477. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  3478. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  3479. {
  3480. const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
  3481. const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
  3482. const uint16_t* _frm_nxt = _frm;
  3483. uint8_t* _to = reinterpret_cast<uint8_t*>(to);
  3484. uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
  3485. uint8_t* _to_nxt = _to;
  3486. result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3487. _Maxcode_, _Mode_);
  3488. frm_nxt = frm + (_frm_nxt - _frm);
  3489. to_nxt = to + (_to_nxt - _to);
  3490. return r;
  3491. }
  3492. __codecvt_utf16<char16_t, true>::result
  3493. __codecvt_utf16<char16_t, true>::do_in(state_type&,
  3494. const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
  3495. intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
  3496. {
  3497. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3498. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3499. const uint8_t* _frm_nxt = _frm;
  3500. uint16_t* _to = reinterpret_cast<uint16_t*>(to);
  3501. uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
  3502. uint16_t* _to_nxt = _to;
  3503. result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3504. _Maxcode_, _Mode_);
  3505. frm_nxt = frm + (_frm_nxt - _frm);
  3506. to_nxt = to + (_to_nxt - _to);
  3507. return r;
  3508. }
  3509. __codecvt_utf16<char16_t, true>::result
  3510. __codecvt_utf16<char16_t, true>::do_unshift(state_type&,
  3511. extern_type* to, extern_type*, extern_type*& to_nxt) const
  3512. {
  3513. to_nxt = to;
  3514. return noconv;
  3515. }
  3516. int
  3517. __codecvt_utf16<char16_t, true>::do_encoding() const _NOEXCEPT
  3518. {
  3519. return 0;
  3520. }
  3521. bool
  3522. __codecvt_utf16<char16_t, true>::do_always_noconv() const _NOEXCEPT
  3523. {
  3524. return false;
  3525. }
  3526. int
  3527. __codecvt_utf16<char16_t, true>::do_length(state_type&,
  3528. const extern_type* frm, const extern_type* frm_end, size_t mx) const
  3529. {
  3530. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3531. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3532. return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
  3533. }
  3534. int
  3535. __codecvt_utf16<char16_t, true>::do_max_length() const _NOEXCEPT
  3536. {
  3537. if (_Mode_ & consume_header)
  3538. return 4;
  3539. return 2;
  3540. }
  3541. // __codecvt_utf16<char32_t, false>
  3542. __codecvt_utf16<char32_t, false>::result
  3543. __codecvt_utf16<char32_t, false>::do_out(state_type&,
  3544. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  3545. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  3546. {
  3547. const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
  3548. const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
  3549. const uint32_t* _frm_nxt = _frm;
  3550. uint8_t* _to = reinterpret_cast<uint8_t*>(to);
  3551. uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
  3552. uint8_t* _to_nxt = _to;
  3553. result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3554. _Maxcode_, _Mode_);
  3555. frm_nxt = frm + (_frm_nxt - _frm);
  3556. to_nxt = to + (_to_nxt - _to);
  3557. return r;
  3558. }
  3559. __codecvt_utf16<char32_t, false>::result
  3560. __codecvt_utf16<char32_t, false>::do_in(state_type&,
  3561. const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
  3562. intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
  3563. {
  3564. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3565. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3566. const uint8_t* _frm_nxt = _frm;
  3567. uint32_t* _to = reinterpret_cast<uint32_t*>(to);
  3568. uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
  3569. uint32_t* _to_nxt = _to;
  3570. result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3571. _Maxcode_, _Mode_);
  3572. frm_nxt = frm + (_frm_nxt - _frm);
  3573. to_nxt = to + (_to_nxt - _to);
  3574. return r;
  3575. }
  3576. __codecvt_utf16<char32_t, false>::result
  3577. __codecvt_utf16<char32_t, false>::do_unshift(state_type&,
  3578. extern_type* to, extern_type*, extern_type*& to_nxt) const
  3579. {
  3580. to_nxt = to;
  3581. return noconv;
  3582. }
  3583. int
  3584. __codecvt_utf16<char32_t, false>::do_encoding() const _NOEXCEPT
  3585. {
  3586. return 0;
  3587. }
  3588. bool
  3589. __codecvt_utf16<char32_t, false>::do_always_noconv() const _NOEXCEPT
  3590. {
  3591. return false;
  3592. }
  3593. int
  3594. __codecvt_utf16<char32_t, false>::do_length(state_type&,
  3595. const extern_type* frm, const extern_type* frm_end, size_t mx) const
  3596. {
  3597. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3598. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3599. return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
  3600. }
  3601. int
  3602. __codecvt_utf16<char32_t, false>::do_max_length() const _NOEXCEPT
  3603. {
  3604. if (_Mode_ & consume_header)
  3605. return 6;
  3606. return 4;
  3607. }
  3608. // __codecvt_utf16<char32_t, true>
  3609. __codecvt_utf16<char32_t, true>::result
  3610. __codecvt_utf16<char32_t, true>::do_out(state_type&,
  3611. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  3612. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  3613. {
  3614. const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
  3615. const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
  3616. const uint32_t* _frm_nxt = _frm;
  3617. uint8_t* _to = reinterpret_cast<uint8_t*>(to);
  3618. uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
  3619. uint8_t* _to_nxt = _to;
  3620. result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3621. _Maxcode_, _Mode_);
  3622. frm_nxt = frm + (_frm_nxt - _frm);
  3623. to_nxt = to + (_to_nxt - _to);
  3624. return r;
  3625. }
  3626. __codecvt_utf16<char32_t, true>::result
  3627. __codecvt_utf16<char32_t, true>::do_in(state_type&,
  3628. const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
  3629. intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
  3630. {
  3631. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3632. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3633. const uint8_t* _frm_nxt = _frm;
  3634. uint32_t* _to = reinterpret_cast<uint32_t*>(to);
  3635. uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
  3636. uint32_t* _to_nxt = _to;
  3637. result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3638. _Maxcode_, _Mode_);
  3639. frm_nxt = frm + (_frm_nxt - _frm);
  3640. to_nxt = to + (_to_nxt - _to);
  3641. return r;
  3642. }
  3643. __codecvt_utf16<char32_t, true>::result
  3644. __codecvt_utf16<char32_t, true>::do_unshift(state_type&,
  3645. extern_type* to, extern_type*, extern_type*& to_nxt) const
  3646. {
  3647. to_nxt = to;
  3648. return noconv;
  3649. }
  3650. int
  3651. __codecvt_utf16<char32_t, true>::do_encoding() const _NOEXCEPT
  3652. {
  3653. return 0;
  3654. }
  3655. bool
  3656. __codecvt_utf16<char32_t, true>::do_always_noconv() const _NOEXCEPT
  3657. {
  3658. return false;
  3659. }
  3660. int
  3661. __codecvt_utf16<char32_t, true>::do_length(state_type&,
  3662. const extern_type* frm, const extern_type* frm_end, size_t mx) const
  3663. {
  3664. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3665. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3666. return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
  3667. }
  3668. int
  3669. __codecvt_utf16<char32_t, true>::do_max_length() const _NOEXCEPT
  3670. {
  3671. if (_Mode_ & consume_header)
  3672. return 6;
  3673. return 4;
  3674. }
  3675. // __codecvt_utf8_utf16<wchar_t>
  3676. __codecvt_utf8_utf16<wchar_t>::result
  3677. __codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
  3678. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  3679. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  3680. {
  3681. const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
  3682. const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
  3683. const uint32_t* _frm_nxt = _frm;
  3684. uint8_t* _to = reinterpret_cast<uint8_t*>(to);
  3685. uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
  3686. uint8_t* _to_nxt = _to;
  3687. result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3688. _Maxcode_, _Mode_);
  3689. frm_nxt = frm + (_frm_nxt - _frm);
  3690. to_nxt = to + (_to_nxt - _to);
  3691. return r;
  3692. }
  3693. __codecvt_utf8_utf16<wchar_t>::result
  3694. __codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
  3695. const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
  3696. intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
  3697. {
  3698. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3699. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3700. const uint8_t* _frm_nxt = _frm;
  3701. uint32_t* _to = reinterpret_cast<uint32_t*>(to);
  3702. uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
  3703. uint32_t* _to_nxt = _to;
  3704. result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3705. _Maxcode_, _Mode_);
  3706. frm_nxt = frm + (_frm_nxt - _frm);
  3707. to_nxt = to + (_to_nxt - _to);
  3708. return r;
  3709. }
  3710. __codecvt_utf8_utf16<wchar_t>::result
  3711. __codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
  3712. extern_type* to, extern_type*, extern_type*& to_nxt) const
  3713. {
  3714. to_nxt = to;
  3715. return noconv;
  3716. }
  3717. int
  3718. __codecvt_utf8_utf16<wchar_t>::do_encoding() const _NOEXCEPT
  3719. {
  3720. return 0;
  3721. }
  3722. bool
  3723. __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const _NOEXCEPT
  3724. {
  3725. return false;
  3726. }
  3727. int
  3728. __codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
  3729. const extern_type* frm, const extern_type* frm_end, size_t mx) const
  3730. {
  3731. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3732. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3733. return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
  3734. }
  3735. int
  3736. __codecvt_utf8_utf16<wchar_t>::do_max_length() const _NOEXCEPT
  3737. {
  3738. if (_Mode_ & consume_header)
  3739. return 7;
  3740. return 4;
  3741. }
  3742. // __codecvt_utf8_utf16<char16_t>
  3743. __codecvt_utf8_utf16<char16_t>::result
  3744. __codecvt_utf8_utf16<char16_t>::do_out(state_type&,
  3745. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  3746. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  3747. {
  3748. const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
  3749. const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
  3750. const uint16_t* _frm_nxt = _frm;
  3751. uint8_t* _to = reinterpret_cast<uint8_t*>(to);
  3752. uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
  3753. uint8_t* _to_nxt = _to;
  3754. result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3755. _Maxcode_, _Mode_);
  3756. frm_nxt = frm + (_frm_nxt - _frm);
  3757. to_nxt = to + (_to_nxt - _to);
  3758. return r;
  3759. }
  3760. __codecvt_utf8_utf16<char16_t>::result
  3761. __codecvt_utf8_utf16<char16_t>::do_in(state_type&,
  3762. const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
  3763. intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
  3764. {
  3765. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3766. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3767. const uint8_t* _frm_nxt = _frm;
  3768. uint16_t* _to = reinterpret_cast<uint16_t*>(to);
  3769. uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
  3770. uint16_t* _to_nxt = _to;
  3771. result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3772. _Maxcode_, _Mode_);
  3773. frm_nxt = frm + (_frm_nxt - _frm);
  3774. to_nxt = to + (_to_nxt - _to);
  3775. return r;
  3776. }
  3777. __codecvt_utf8_utf16<char16_t>::result
  3778. __codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
  3779. extern_type* to, extern_type*, extern_type*& to_nxt) const
  3780. {
  3781. to_nxt = to;
  3782. return noconv;
  3783. }
  3784. int
  3785. __codecvt_utf8_utf16<char16_t>::do_encoding() const _NOEXCEPT
  3786. {
  3787. return 0;
  3788. }
  3789. bool
  3790. __codecvt_utf8_utf16<char16_t>::do_always_noconv() const _NOEXCEPT
  3791. {
  3792. return false;
  3793. }
  3794. int
  3795. __codecvt_utf8_utf16<char16_t>::do_length(state_type&,
  3796. const extern_type* frm, const extern_type* frm_end, size_t mx) const
  3797. {
  3798. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3799. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3800. return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
  3801. }
  3802. int
  3803. __codecvt_utf8_utf16<char16_t>::do_max_length() const _NOEXCEPT
  3804. {
  3805. if (_Mode_ & consume_header)
  3806. return 7;
  3807. return 4;
  3808. }
  3809. // __codecvt_utf8_utf16<char32_t>
  3810. __codecvt_utf8_utf16<char32_t>::result
  3811. __codecvt_utf8_utf16<char32_t>::do_out(state_type&,
  3812. const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
  3813. extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
  3814. {
  3815. const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
  3816. const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
  3817. const uint32_t* _frm_nxt = _frm;
  3818. uint8_t* _to = reinterpret_cast<uint8_t*>(to);
  3819. uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
  3820. uint8_t* _to_nxt = _to;
  3821. result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3822. _Maxcode_, _Mode_);
  3823. frm_nxt = frm + (_frm_nxt - _frm);
  3824. to_nxt = to + (_to_nxt - _to);
  3825. return r;
  3826. }
  3827. __codecvt_utf8_utf16<char32_t>::result
  3828. __codecvt_utf8_utf16<char32_t>::do_in(state_type&,
  3829. const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
  3830. intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
  3831. {
  3832. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3833. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3834. const uint8_t* _frm_nxt = _frm;
  3835. uint32_t* _to = reinterpret_cast<uint32_t*>(to);
  3836. uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
  3837. uint32_t* _to_nxt = _to;
  3838. result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
  3839. _Maxcode_, _Mode_);
  3840. frm_nxt = frm + (_frm_nxt - _frm);
  3841. to_nxt = to + (_to_nxt - _to);
  3842. return r;
  3843. }
  3844. __codecvt_utf8_utf16<char32_t>::result
  3845. __codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
  3846. extern_type* to, extern_type*, extern_type*& to_nxt) const
  3847. {
  3848. to_nxt = to;
  3849. return noconv;
  3850. }
  3851. int
  3852. __codecvt_utf8_utf16<char32_t>::do_encoding() const _NOEXCEPT
  3853. {
  3854. return 0;
  3855. }
  3856. bool
  3857. __codecvt_utf8_utf16<char32_t>::do_always_noconv() const _NOEXCEPT
  3858. {
  3859. return false;
  3860. }
  3861. int
  3862. __codecvt_utf8_utf16<char32_t>::do_length(state_type&,
  3863. const extern_type* frm, const extern_type* frm_end, size_t mx) const
  3864. {
  3865. const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
  3866. const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
  3867. return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
  3868. }
  3869. int
  3870. __codecvt_utf8_utf16<char32_t>::do_max_length() const _NOEXCEPT
  3871. {
  3872. if (_Mode_ & consume_header)
  3873. return 7;
  3874. return 4;
  3875. }
  3876. // __narrow_to_utf8<16>
  3877. __narrow_to_utf8<16>::~__narrow_to_utf8()
  3878. {
  3879. }
  3880. // __narrow_to_utf8<32>
  3881. __narrow_to_utf8<32>::~__narrow_to_utf8()
  3882. {
  3883. }
  3884. // __widen_from_utf8<16>
  3885. __widen_from_utf8<16>::~__widen_from_utf8()
  3886. {
  3887. }
  3888. // __widen_from_utf8<32>
  3889. __widen_from_utf8<32>::~__widen_from_utf8()
  3890. {
  3891. }
  3892. // numpunct<char> && numpunct<wchar_t>
  3893. locale::id numpunct< char >::id;
  3894. locale::id numpunct<wchar_t>::id;
  3895. numpunct<char>::numpunct(size_t refs)
  3896. : locale::facet(refs),
  3897. __decimal_point_('.'),
  3898. __thousands_sep_(',')
  3899. {
  3900. }
  3901. numpunct<wchar_t>::numpunct(size_t refs)
  3902. : locale::facet(refs),
  3903. __decimal_point_(L'.'),
  3904. __thousands_sep_(L',')
  3905. {
  3906. }
  3907. numpunct<char>::~numpunct()
  3908. {
  3909. }
  3910. numpunct<wchar_t>::~numpunct()
  3911. {
  3912. }
  3913. char numpunct< char >::do_decimal_point() const {return __decimal_point_;}
  3914. wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
  3915. char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;}
  3916. wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
  3917. string numpunct< char >::do_grouping() const {return __grouping_;}
  3918. string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
  3919. string numpunct< char >::do_truename() const {return "true";}
  3920. wstring numpunct<wchar_t>::do_truename() const {return L"true";}
  3921. string numpunct< char >::do_falsename() const {return "false";}
  3922. wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
  3923. // numpunct_byname<char>
  3924. numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
  3925. : numpunct<char>(refs)
  3926. {
  3927. __init(nm);
  3928. }
  3929. numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
  3930. : numpunct<char>(refs)
  3931. {
  3932. __init(nm.c_str());
  3933. }
  3934. numpunct_byname<char>::~numpunct_byname()
  3935. {
  3936. }
  3937. void
  3938. numpunct_byname<char>::__init(const char* nm)
  3939. {
  3940. if (strcmp(nm, "C") != 0)
  3941. {
  3942. __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
  3943. #ifndef _LIBCPP_NO_EXCEPTIONS
  3944. if (loc == nullptr)
  3945. throw runtime_error("numpunct_byname<char>::numpunct_byname"
  3946. " failed to construct for " + string(nm));
  3947. #endif // _LIBCPP_NO_EXCEPTIONS
  3948. lconv* lc = __libcpp_localeconv_l(loc.get());
  3949. if (*lc->decimal_point)
  3950. __decimal_point_ = *lc->decimal_point;
  3951. if (*lc->thousands_sep)
  3952. __thousands_sep_ = *lc->thousands_sep;
  3953. __grouping_ = lc->grouping;
  3954. // localization for truename and falsename is not available
  3955. }
  3956. }
  3957. // numpunct_byname<wchar_t>
  3958. numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
  3959. : numpunct<wchar_t>(refs)
  3960. {
  3961. __init(nm);
  3962. }
  3963. numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
  3964. : numpunct<wchar_t>(refs)
  3965. {
  3966. __init(nm.c_str());
  3967. }
  3968. numpunct_byname<wchar_t>::~numpunct_byname()
  3969. {
  3970. }
  3971. void
  3972. numpunct_byname<wchar_t>::__init(const char* nm)
  3973. {
  3974. if (strcmp(nm, "C") != 0)
  3975. {
  3976. __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
  3977. #ifndef _LIBCPP_NO_EXCEPTIONS
  3978. if (loc == nullptr)
  3979. throw runtime_error("numpunct_byname<char>::numpunct_byname"
  3980. " failed to construct for " + string(nm));
  3981. #endif // _LIBCPP_NO_EXCEPTIONS
  3982. lconv* lc = __libcpp_localeconv_l(loc.get());
  3983. if (*lc->decimal_point)
  3984. __decimal_point_ = *lc->decimal_point;
  3985. if (*lc->thousands_sep)
  3986. __thousands_sep_ = *lc->thousands_sep;
  3987. __grouping_ = lc->grouping;
  3988. // locallization for truename and falsename is not available
  3989. }
  3990. }
  3991. // num_get helpers
  3992. int
  3993. __num_get_base::__get_base(ios_base& iob)
  3994. {
  3995. ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
  3996. if (__basefield == ios_base::oct)
  3997. return 8;
  3998. else if (__basefield == ios_base::hex)
  3999. return 16;
  4000. else if (__basefield == 0)
  4001. return 0;
  4002. return 10;
  4003. }
  4004. const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
  4005. void
  4006. __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
  4007. ios_base::iostate& __err)
  4008. {
  4009. if (__grouping.size() != 0)
  4010. {
  4011. reverse(__g, __g_end);
  4012. const char* __ig = __grouping.data();
  4013. const char* __eg = __ig + __grouping.size();
  4014. for (unsigned* __r = __g; __r < __g_end-1; ++__r)
  4015. {
  4016. if (0 < *__ig && *__ig < numeric_limits<char>::max())
  4017. {
  4018. if (static_cast<unsigned>(*__ig) != *__r)
  4019. {
  4020. __err = ios_base::failbit;
  4021. return;
  4022. }
  4023. }
  4024. if (__eg - __ig > 1)
  4025. ++__ig;
  4026. }
  4027. if (0 < *__ig && *__ig < numeric_limits<char>::max())
  4028. {
  4029. if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
  4030. __err = ios_base::failbit;
  4031. }
  4032. }
  4033. }
  4034. void
  4035. __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
  4036. ios_base::fmtflags __flags)
  4037. {
  4038. if (__flags & ios_base::showpos)
  4039. *__fmtp++ = '+';
  4040. if (__flags & ios_base::showbase)
  4041. *__fmtp++ = '#';
  4042. while(*__len)
  4043. *__fmtp++ = *__len++;
  4044. if ((__flags & ios_base::basefield) == ios_base::oct)
  4045. *__fmtp = 'o';
  4046. else if ((__flags & ios_base::basefield) == ios_base::hex)
  4047. {
  4048. if (__flags & ios_base::uppercase)
  4049. *__fmtp = 'X';
  4050. else
  4051. *__fmtp = 'x';
  4052. }
  4053. else if (__signd)
  4054. *__fmtp = 'd';
  4055. else
  4056. *__fmtp = 'u';
  4057. }
  4058. bool
  4059. __num_put_base::__format_float(char* __fmtp, const char* __len,
  4060. ios_base::fmtflags __flags)
  4061. {
  4062. bool specify_precision = true;
  4063. if (__flags & ios_base::showpos)
  4064. *__fmtp++ = '+';
  4065. if (__flags & ios_base::showpoint)
  4066. *__fmtp++ = '#';
  4067. ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
  4068. bool uppercase = (__flags & ios_base::uppercase) != 0;
  4069. if (floatfield == (ios_base::fixed | ios_base::scientific))
  4070. specify_precision = false;
  4071. else
  4072. {
  4073. *__fmtp++ = '.';
  4074. *__fmtp++ = '*';
  4075. }
  4076. while(*__len)
  4077. *__fmtp++ = *__len++;
  4078. if (floatfield == ios_base::fixed)
  4079. {
  4080. if (uppercase)
  4081. *__fmtp = 'F';
  4082. else
  4083. *__fmtp = 'f';
  4084. }
  4085. else if (floatfield == ios_base::scientific)
  4086. {
  4087. if (uppercase)
  4088. *__fmtp = 'E';
  4089. else
  4090. *__fmtp = 'e';
  4091. }
  4092. else if (floatfield == (ios_base::fixed | ios_base::scientific))
  4093. {
  4094. if (uppercase)
  4095. *__fmtp = 'A';
  4096. else
  4097. *__fmtp = 'a';
  4098. }
  4099. else
  4100. {
  4101. if (uppercase)
  4102. *__fmtp = 'G';
  4103. else
  4104. *__fmtp = 'g';
  4105. }
  4106. return specify_precision;
  4107. }
  4108. char*
  4109. __num_put_base::__identify_padding(char* __nb, char* __ne,
  4110. const ios_base& __iob)
  4111. {
  4112. switch (__iob.flags() & ios_base::adjustfield)
  4113. {
  4114. case ios_base::internal:
  4115. if (__nb[0] == '-' || __nb[0] == '+')
  4116. return __nb+1;
  4117. if (__ne - __nb >= 2 && __nb[0] == '0'
  4118. && (__nb[1] == 'x' || __nb[1] == 'X'))
  4119. return __nb+2;
  4120. break;
  4121. case ios_base::left:
  4122. return __ne;
  4123. case ios_base::right:
  4124. default:
  4125. break;
  4126. }
  4127. return __nb;
  4128. }
  4129. // time_get
  4130. static
  4131. string*
  4132. init_weeks()
  4133. {
  4134. static string weeks[14];
  4135. weeks[0] = "Sunday";
  4136. weeks[1] = "Monday";
  4137. weeks[2] = "Tuesday";
  4138. weeks[3] = "Wednesday";
  4139. weeks[4] = "Thursday";
  4140. weeks[5] = "Friday";
  4141. weeks[6] = "Saturday";
  4142. weeks[7] = "Sun";
  4143. weeks[8] = "Mon";
  4144. weeks[9] = "Tue";
  4145. weeks[10] = "Wed";
  4146. weeks[11] = "Thu";
  4147. weeks[12] = "Fri";
  4148. weeks[13] = "Sat";
  4149. return weeks;
  4150. }
  4151. static
  4152. wstring*
  4153. init_wweeks()
  4154. {
  4155. static wstring weeks[14];
  4156. weeks[0] = L"Sunday";
  4157. weeks[1] = L"Monday";
  4158. weeks[2] = L"Tuesday";
  4159. weeks[3] = L"Wednesday";
  4160. weeks[4] = L"Thursday";
  4161. weeks[5] = L"Friday";
  4162. weeks[6] = L"Saturday";
  4163. weeks[7] = L"Sun";
  4164. weeks[8] = L"Mon";
  4165. weeks[9] = L"Tue";
  4166. weeks[10] = L"Wed";
  4167. weeks[11] = L"Thu";
  4168. weeks[12] = L"Fri";
  4169. weeks[13] = L"Sat";
  4170. return weeks;
  4171. }
  4172. template <>
  4173. const string*
  4174. __time_get_c_storage<char>::__weeks() const
  4175. {
  4176. static const string* weeks = init_weeks();
  4177. return weeks;
  4178. }
  4179. template <>
  4180. const wstring*
  4181. __time_get_c_storage<wchar_t>::__weeks() const
  4182. {
  4183. static const wstring* weeks = init_wweeks();
  4184. return weeks;
  4185. }
  4186. static
  4187. string*
  4188. init_months()
  4189. {
  4190. static string months[24];
  4191. months[0] = "January";
  4192. months[1] = "February";
  4193. months[2] = "March";
  4194. months[3] = "April";
  4195. months[4] = "May";
  4196. months[5] = "June";
  4197. months[6] = "July";
  4198. months[7] = "August";
  4199. months[8] = "September";
  4200. months[9] = "October";
  4201. months[10] = "November";
  4202. months[11] = "December";
  4203. months[12] = "Jan";
  4204. months[13] = "Feb";
  4205. months[14] = "Mar";
  4206. months[15] = "Apr";
  4207. months[16] = "May";
  4208. months[17] = "Jun";
  4209. months[18] = "Jul";
  4210. months[19] = "Aug";
  4211. months[20] = "Sep";
  4212. months[21] = "Oct";
  4213. months[22] = "Nov";
  4214. months[23] = "Dec";
  4215. return months;
  4216. }
  4217. static
  4218. wstring*
  4219. init_wmonths()
  4220. {
  4221. static wstring months[24];
  4222. months[0] = L"January";
  4223. months[1] = L"February";
  4224. months[2] = L"March";
  4225. months[3] = L"April";
  4226. months[4] = L"May";
  4227. months[5] = L"June";
  4228. months[6] = L"July";
  4229. months[7] = L"August";
  4230. months[8] = L"September";
  4231. months[9] = L"October";
  4232. months[10] = L"November";
  4233. months[11] = L"December";
  4234. months[12] = L"Jan";
  4235. months[13] = L"Feb";
  4236. months[14] = L"Mar";
  4237. months[15] = L"Apr";
  4238. months[16] = L"May";
  4239. months[17] = L"Jun";
  4240. months[18] = L"Jul";
  4241. months[19] = L"Aug";
  4242. months[20] = L"Sep";
  4243. months[21] = L"Oct";
  4244. months[22] = L"Nov";
  4245. months[23] = L"Dec";
  4246. return months;
  4247. }
  4248. template <>
  4249. const string*
  4250. __time_get_c_storage<char>::__months() const
  4251. {
  4252. static const string* months = init_months();
  4253. return months;
  4254. }
  4255. template <>
  4256. const wstring*
  4257. __time_get_c_storage<wchar_t>::__months() const
  4258. {
  4259. static const wstring* months = init_wmonths();
  4260. return months;
  4261. }
  4262. static
  4263. string*
  4264. init_am_pm()
  4265. {
  4266. static string am_pm[24];
  4267. am_pm[0] = "AM";
  4268. am_pm[1] = "PM";
  4269. return am_pm;
  4270. }
  4271. static
  4272. wstring*
  4273. init_wam_pm()
  4274. {
  4275. static wstring am_pm[24];
  4276. am_pm[0] = L"AM";
  4277. am_pm[1] = L"PM";
  4278. return am_pm;
  4279. }
  4280. template <>
  4281. const string*
  4282. __time_get_c_storage<char>::__am_pm() const
  4283. {
  4284. static const string* am_pm = init_am_pm();
  4285. return am_pm;
  4286. }
  4287. template <>
  4288. const wstring*
  4289. __time_get_c_storage<wchar_t>::__am_pm() const
  4290. {
  4291. static const wstring* am_pm = init_wam_pm();
  4292. return am_pm;
  4293. }
  4294. template <>
  4295. const string&
  4296. __time_get_c_storage<char>::__x() const
  4297. {
  4298. static string s("%m/%d/%y");
  4299. return s;
  4300. }
  4301. template <>
  4302. const wstring&
  4303. __time_get_c_storage<wchar_t>::__x() const
  4304. {
  4305. static wstring s(L"%m/%d/%y");
  4306. return s;
  4307. }
  4308. template <>
  4309. const string&
  4310. __time_get_c_storage<char>::__X() const
  4311. {
  4312. static string s("%H:%M:%S");
  4313. return s;
  4314. }
  4315. template <>
  4316. const wstring&
  4317. __time_get_c_storage<wchar_t>::__X() const
  4318. {
  4319. static wstring s(L"%H:%M:%S");
  4320. return s;
  4321. }
  4322. template <>
  4323. const string&
  4324. __time_get_c_storage<char>::__c() const
  4325. {
  4326. static string s("%a %b %d %H:%M:%S %Y");
  4327. return s;
  4328. }
  4329. template <>
  4330. const wstring&
  4331. __time_get_c_storage<wchar_t>::__c() const
  4332. {
  4333. static wstring s(L"%a %b %d %H:%M:%S %Y");
  4334. return s;
  4335. }
  4336. template <>
  4337. const string&
  4338. __time_get_c_storage<char>::__r() const
  4339. {
  4340. static string s("%I:%M:%S %p");
  4341. return s;
  4342. }
  4343. template <>
  4344. const wstring&
  4345. __time_get_c_storage<wchar_t>::__r() const
  4346. {
  4347. static wstring s(L"%I:%M:%S %p");
  4348. return s;
  4349. }
  4350. // time_get_byname
  4351. __time_get::__time_get(const char* nm)
  4352. : __loc_(newlocale(LC_ALL_MASK, nm, 0))
  4353. {
  4354. #ifndef _LIBCPP_NO_EXCEPTIONS
  4355. if (__loc_ == 0)
  4356. throw runtime_error("time_get_byname"
  4357. " failed to construct for " + string(nm));
  4358. #endif // _LIBCPP_NO_EXCEPTIONS
  4359. }
  4360. __time_get::__time_get(const string& nm)
  4361. : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
  4362. {
  4363. #ifndef _LIBCPP_NO_EXCEPTIONS
  4364. if (__loc_ == 0)
  4365. throw runtime_error("time_get_byname"
  4366. " failed to construct for " + nm);
  4367. #endif // _LIBCPP_NO_EXCEPTIONS
  4368. }
  4369. __time_get::~__time_get()
  4370. {
  4371. freelocale(__loc_);
  4372. }
  4373. #if defined(__clang__)
  4374. #pragma clang diagnostic ignored "-Wmissing-field-initializers"
  4375. #endif
  4376. #if defined(__GNUG__)
  4377. #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
  4378. #endif
  4379. template <>
  4380. string
  4381. __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
  4382. {
  4383. tm t = {0};
  4384. t.tm_sec = 59;
  4385. t.tm_min = 55;
  4386. t.tm_hour = 23;
  4387. t.tm_mday = 31;
  4388. t.tm_mon = 11;
  4389. t.tm_year = 161;
  4390. t.tm_wday = 6;
  4391. t.tm_yday = 364;
  4392. t.tm_isdst = -1;
  4393. char buf[100];
  4394. char f[3] = {0};
  4395. f[0] = '%';
  4396. f[1] = fmt;
  4397. size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);
  4398. char* bb = buf;
  4399. char* be = buf + n;
  4400. string result;
  4401. while (bb != be)
  4402. {
  4403. if (ct.is(ctype_base::space, *bb))
  4404. {
  4405. result.push_back(' ');
  4406. for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
  4407. ;
  4408. continue;
  4409. }
  4410. char* w = bb;
  4411. ios_base::iostate err = ios_base::goodbit;
  4412. ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
  4413. ct, err, false)
  4414. - this->__weeks_;
  4415. if (i < 14)
  4416. {
  4417. result.push_back('%');
  4418. if (i < 7)
  4419. result.push_back('A');
  4420. else
  4421. result.push_back('a');
  4422. bb = w;
  4423. continue;
  4424. }
  4425. w = bb;
  4426. i = __scan_keyword(w, be, this->__months_, this->__months_+24,
  4427. ct, err, false)
  4428. - this->__months_;
  4429. if (i < 24)
  4430. {
  4431. result.push_back('%');
  4432. if (i < 12)
  4433. result.push_back('B');
  4434. else
  4435. result.push_back('b');
  4436. if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
  4437. result.back() = 'm';
  4438. bb = w;
  4439. continue;
  4440. }
  4441. if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
  4442. {
  4443. w = bb;
  4444. i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
  4445. ct, err, false) - this->__am_pm_;
  4446. if (i < 2)
  4447. {
  4448. result.push_back('%');
  4449. result.push_back('p');
  4450. bb = w;
  4451. continue;
  4452. }
  4453. }
  4454. w = bb;
  4455. if (ct.is(ctype_base::digit, *bb))
  4456. {
  4457. switch(__get_up_to_n_digits(bb, be, err, ct, 4))
  4458. {
  4459. case 6:
  4460. result.push_back('%');
  4461. result.push_back('w');
  4462. break;
  4463. case 7:
  4464. result.push_back('%');
  4465. result.push_back('u');
  4466. break;
  4467. case 11:
  4468. result.push_back('%');
  4469. result.push_back('I');
  4470. break;
  4471. case 12:
  4472. result.push_back('%');
  4473. result.push_back('m');
  4474. break;
  4475. case 23:
  4476. result.push_back('%');
  4477. result.push_back('H');
  4478. break;
  4479. case 31:
  4480. result.push_back('%');
  4481. result.push_back('d');
  4482. break;
  4483. case 55:
  4484. result.push_back('%');
  4485. result.push_back('M');
  4486. break;
  4487. case 59:
  4488. result.push_back('%');
  4489. result.push_back('S');
  4490. break;
  4491. case 61:
  4492. result.push_back('%');
  4493. result.push_back('y');
  4494. break;
  4495. case 364:
  4496. result.push_back('%');
  4497. result.push_back('j');
  4498. break;
  4499. case 2061:
  4500. result.push_back('%');
  4501. result.push_back('Y');
  4502. break;
  4503. default:
  4504. for (; w != bb; ++w)
  4505. result.push_back(*w);
  4506. break;
  4507. }
  4508. continue;
  4509. }
  4510. if (*bb == '%')
  4511. {
  4512. result.push_back('%');
  4513. result.push_back('%');
  4514. ++bb;
  4515. continue;
  4516. }
  4517. result.push_back(*bb);
  4518. ++bb;
  4519. }
  4520. return result;
  4521. }
  4522. #if defined(__clang__)
  4523. #pragma clang diagnostic ignored "-Wmissing-braces"
  4524. #endif
  4525. template <>
  4526. wstring
  4527. __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
  4528. {
  4529. tm t = {0};
  4530. t.tm_sec = 59;
  4531. t.tm_min = 55;
  4532. t.tm_hour = 23;
  4533. t.tm_mday = 31;
  4534. t.tm_mon = 11;
  4535. t.tm_year = 161;
  4536. t.tm_wday = 6;
  4537. t.tm_yday = 364;
  4538. t.tm_isdst = -1;
  4539. char buf[100];
  4540. char f[3] = {0};
  4541. f[0] = '%';
  4542. f[1] = fmt;
  4543. strftime_l(buf, countof(buf), f, &t, __loc_);
  4544. wchar_t wbuf[100];
  4545. wchar_t* wbb = wbuf;
  4546. mbstate_t mb = {0};
  4547. const char* bb = buf;
  4548. size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
  4549. if (j == size_t(-1))
  4550. __throw_runtime_error("locale not supported");
  4551. wchar_t* wbe = wbb + j;
  4552. wstring result;
  4553. while (wbb != wbe)
  4554. {
  4555. if (ct.is(ctype_base::space, *wbb))
  4556. {
  4557. result.push_back(L' ');
  4558. for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
  4559. ;
  4560. continue;
  4561. }
  4562. wchar_t* w = wbb;
  4563. ios_base::iostate err = ios_base::goodbit;
  4564. ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
  4565. ct, err, false)
  4566. - this->__weeks_;
  4567. if (i < 14)
  4568. {
  4569. result.push_back(L'%');
  4570. if (i < 7)
  4571. result.push_back(L'A');
  4572. else
  4573. result.push_back(L'a');
  4574. wbb = w;
  4575. continue;
  4576. }
  4577. w = wbb;
  4578. i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
  4579. ct, err, false)
  4580. - this->__months_;
  4581. if (i < 24)
  4582. {
  4583. result.push_back(L'%');
  4584. if (i < 12)
  4585. result.push_back(L'B');
  4586. else
  4587. result.push_back(L'b');
  4588. if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
  4589. result.back() = L'm';
  4590. wbb = w;
  4591. continue;
  4592. }
  4593. if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
  4594. {
  4595. w = wbb;
  4596. i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
  4597. ct, err, false) - this->__am_pm_;
  4598. if (i < 2)
  4599. {
  4600. result.push_back(L'%');
  4601. result.push_back(L'p');
  4602. wbb = w;
  4603. continue;
  4604. }
  4605. }
  4606. w = wbb;
  4607. if (ct.is(ctype_base::digit, *wbb))
  4608. {
  4609. switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
  4610. {
  4611. case 6:
  4612. result.push_back(L'%');
  4613. result.push_back(L'w');
  4614. break;
  4615. case 7:
  4616. result.push_back(L'%');
  4617. result.push_back(L'u');
  4618. break;
  4619. case 11:
  4620. result.push_back(L'%');
  4621. result.push_back(L'I');
  4622. break;
  4623. case 12:
  4624. result.push_back(L'%');
  4625. result.push_back(L'm');
  4626. break;
  4627. case 23:
  4628. result.push_back(L'%');
  4629. result.push_back(L'H');
  4630. break;
  4631. case 31:
  4632. result.push_back(L'%');
  4633. result.push_back(L'd');
  4634. break;
  4635. case 55:
  4636. result.push_back(L'%');
  4637. result.push_back(L'M');
  4638. break;
  4639. case 59:
  4640. result.push_back(L'%');
  4641. result.push_back(L'S');
  4642. break;
  4643. case 61:
  4644. result.push_back(L'%');
  4645. result.push_back(L'y');
  4646. break;
  4647. case 364:
  4648. result.push_back(L'%');
  4649. result.push_back(L'j');
  4650. break;
  4651. case 2061:
  4652. result.push_back(L'%');
  4653. result.push_back(L'Y');
  4654. break;
  4655. default:
  4656. for (; w != wbb; ++w)
  4657. result.push_back(*w);
  4658. break;
  4659. }
  4660. continue;
  4661. }
  4662. if (ct.narrow(*wbb, 0) == '%')
  4663. {
  4664. result.push_back(L'%');
  4665. result.push_back(L'%');
  4666. ++wbb;
  4667. continue;
  4668. }
  4669. result.push_back(*wbb);
  4670. ++wbb;
  4671. }
  4672. return result;
  4673. }
  4674. template <>
  4675. void
  4676. __time_get_storage<char>::init(const ctype<char>& ct)
  4677. {
  4678. tm t = {0};
  4679. char buf[100];
  4680. // __weeks_
  4681. for (int i = 0; i < 7; ++i)
  4682. {
  4683. t.tm_wday = i;
  4684. strftime_l(buf, countof(buf), "%A", &t, __loc_);
  4685. __weeks_[i] = buf;
  4686. strftime_l(buf, countof(buf), "%a", &t, __loc_);
  4687. __weeks_[i+7] = buf;
  4688. }
  4689. // __months_
  4690. for (int i = 0; i < 12; ++i)
  4691. {
  4692. t.tm_mon = i;
  4693. strftime_l(buf, countof(buf), "%B", &t, __loc_);
  4694. __months_[i] = buf;
  4695. strftime_l(buf, countof(buf), "%b", &t, __loc_);
  4696. __months_[i+12] = buf;
  4697. }
  4698. // __am_pm_
  4699. t.tm_hour = 1;
  4700. strftime_l(buf, countof(buf), "%p", &t, __loc_);
  4701. __am_pm_[0] = buf;
  4702. t.tm_hour = 13;
  4703. strftime_l(buf, countof(buf), "%p", &t, __loc_);
  4704. __am_pm_[1] = buf;
  4705. __c_ = __analyze('c', ct);
  4706. __r_ = __analyze('r', ct);
  4707. __x_ = __analyze('x', ct);
  4708. __X_ = __analyze('X', ct);
  4709. }
  4710. template <>
  4711. void
  4712. __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
  4713. {
  4714. tm t = {0};
  4715. char buf[100];
  4716. wchar_t wbuf[100];
  4717. wchar_t* wbe;
  4718. mbstate_t mb = {0};
  4719. // __weeks_
  4720. for (int i = 0; i < 7; ++i)
  4721. {
  4722. t.tm_wday = i;
  4723. strftime_l(buf, countof(buf), "%A", &t, __loc_);
  4724. mb = mbstate_t();
  4725. const char* bb = buf;
  4726. size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
  4727. if (j == size_t(-1))
  4728. __throw_runtime_error("locale not supported");
  4729. wbe = wbuf + j;
  4730. __weeks_[i].assign(wbuf, wbe);
  4731. strftime_l(buf, countof(buf), "%a", &t, __loc_);
  4732. mb = mbstate_t();
  4733. bb = buf;
  4734. j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
  4735. if (j == size_t(-1))
  4736. __throw_runtime_error("locale not supported");
  4737. wbe = wbuf + j;
  4738. __weeks_[i+7].assign(wbuf, wbe);
  4739. }
  4740. // __months_
  4741. for (int i = 0; i < 12; ++i)
  4742. {
  4743. t.tm_mon = i;
  4744. strftime_l(buf, countof(buf), "%B", &t, __loc_);
  4745. mb = mbstate_t();
  4746. const char* bb = buf;
  4747. size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
  4748. if (j == size_t(-1))
  4749. __throw_runtime_error("locale not supported");
  4750. wbe = wbuf + j;
  4751. __months_[i].assign(wbuf, wbe);
  4752. strftime_l(buf, countof(buf), "%b", &t, __loc_);
  4753. mb = mbstate_t();
  4754. bb = buf;
  4755. j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
  4756. if (j == size_t(-1))
  4757. __throw_runtime_error("locale not supported");
  4758. wbe = wbuf + j;
  4759. __months_[i+12].assign(wbuf, wbe);
  4760. }
  4761. // __am_pm_
  4762. t.tm_hour = 1;
  4763. strftime_l(buf, countof(buf), "%p", &t, __loc_);
  4764. mb = mbstate_t();
  4765. const char* bb = buf;
  4766. size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
  4767. if (j == size_t(-1))
  4768. __throw_runtime_error("locale not supported");
  4769. wbe = wbuf + j;
  4770. __am_pm_[0].assign(wbuf, wbe);
  4771. t.tm_hour = 13;
  4772. strftime_l(buf, countof(buf), "%p", &t, __loc_);
  4773. mb = mbstate_t();
  4774. bb = buf;
  4775. j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
  4776. if (j == size_t(-1))
  4777. __throw_runtime_error("locale not supported");
  4778. wbe = wbuf + j;
  4779. __am_pm_[1].assign(wbuf, wbe);
  4780. __c_ = __analyze('c', ct);
  4781. __r_ = __analyze('r', ct);
  4782. __x_ = __analyze('x', ct);
  4783. __X_ = __analyze('X', ct);
  4784. }
  4785. template <class CharT>
  4786. struct _LIBCPP_HIDDEN __time_get_temp
  4787. : public ctype_byname<CharT>
  4788. {
  4789. explicit __time_get_temp(const char* nm)
  4790. : ctype_byname<CharT>(nm, 1) {}
  4791. explicit __time_get_temp(const string& nm)
  4792. : ctype_byname<CharT>(nm, 1) {}
  4793. };
  4794. template <>
  4795. __time_get_storage<char>::__time_get_storage(const char* __nm)
  4796. : __time_get(__nm)
  4797. {
  4798. const __time_get_temp<char> ct(__nm);
  4799. init(ct);
  4800. }
  4801. template <>
  4802. __time_get_storage<char>::__time_get_storage(const string& __nm)
  4803. : __time_get(__nm)
  4804. {
  4805. const __time_get_temp<char> ct(__nm);
  4806. init(ct);
  4807. }
  4808. template <>
  4809. __time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
  4810. : __time_get(__nm)
  4811. {
  4812. const __time_get_temp<wchar_t> ct(__nm);
  4813. init(ct);
  4814. }
  4815. template <>
  4816. __time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
  4817. : __time_get(__nm)
  4818. {
  4819. const __time_get_temp<wchar_t> ct(__nm);
  4820. init(ct);
  4821. }
  4822. template <>
  4823. time_base::dateorder
  4824. __time_get_storage<char>::__do_date_order() const
  4825. {
  4826. unsigned i;
  4827. for (i = 0; i < __x_.size(); ++i)
  4828. if (__x_[i] == '%')
  4829. break;
  4830. ++i;
  4831. switch (__x_[i])
  4832. {
  4833. case 'y':
  4834. case 'Y':
  4835. for (++i; i < __x_.size(); ++i)
  4836. if (__x_[i] == '%')
  4837. break;
  4838. if (i == __x_.size())
  4839. break;
  4840. ++i;
  4841. switch (__x_[i])
  4842. {
  4843. case 'm':
  4844. for (++i; i < __x_.size(); ++i)
  4845. if (__x_[i] == '%')
  4846. break;
  4847. if (i == __x_.size())
  4848. break;
  4849. ++i;
  4850. if (__x_[i] == 'd')
  4851. return time_base::ymd;
  4852. break;
  4853. case 'd':
  4854. for (++i; i < __x_.size(); ++i)
  4855. if (__x_[i] == '%')
  4856. break;
  4857. if (i == __x_.size())
  4858. break;
  4859. ++i;
  4860. if (__x_[i] == 'm')
  4861. return time_base::ydm;
  4862. break;
  4863. }
  4864. break;
  4865. case 'm':
  4866. for (++i; i < __x_.size(); ++i)
  4867. if (__x_[i] == '%')
  4868. break;
  4869. if (i == __x_.size())
  4870. break;
  4871. ++i;
  4872. if (__x_[i] == 'd')
  4873. {
  4874. for (++i; i < __x_.size(); ++i)
  4875. if (__x_[i] == '%')
  4876. break;
  4877. if (i == __x_.size())
  4878. break;
  4879. ++i;
  4880. if (__x_[i] == 'y' || __x_[i] == 'Y')
  4881. return time_base::mdy;
  4882. break;
  4883. }
  4884. break;
  4885. case 'd':
  4886. for (++i; i < __x_.size(); ++i)
  4887. if (__x_[i] == '%')
  4888. break;
  4889. if (i == __x_.size())
  4890. break;
  4891. ++i;
  4892. if (__x_[i] == 'm')
  4893. {
  4894. for (++i; i < __x_.size(); ++i)
  4895. if (__x_[i] == '%')
  4896. break;
  4897. if (i == __x_.size())
  4898. break;
  4899. ++i;
  4900. if (__x_[i] == 'y' || __x_[i] == 'Y')
  4901. return time_base::dmy;
  4902. break;
  4903. }
  4904. break;
  4905. }
  4906. return time_base::no_order;
  4907. }
  4908. template <>
  4909. time_base::dateorder
  4910. __time_get_storage<wchar_t>::__do_date_order() const
  4911. {
  4912. unsigned i;
  4913. for (i = 0; i < __x_.size(); ++i)
  4914. if (__x_[i] == L'%')
  4915. break;
  4916. ++i;
  4917. switch (__x_[i])
  4918. {
  4919. case L'y':
  4920. case L'Y':
  4921. for (++i; i < __x_.size(); ++i)
  4922. if (__x_[i] == L'%')
  4923. break;
  4924. if (i == __x_.size())
  4925. break;
  4926. ++i;
  4927. switch (__x_[i])
  4928. {
  4929. case L'm':
  4930. for (++i; i < __x_.size(); ++i)
  4931. if (__x_[i] == L'%')
  4932. break;
  4933. if (i == __x_.size())
  4934. break;
  4935. ++i;
  4936. if (__x_[i] == L'd')
  4937. return time_base::ymd;
  4938. break;
  4939. case L'd':
  4940. for (++i; i < __x_.size(); ++i)
  4941. if (__x_[i] == L'%')
  4942. break;
  4943. if (i == __x_.size())
  4944. break;
  4945. ++i;
  4946. if (__x_[i] == L'm')
  4947. return time_base::ydm;
  4948. break;
  4949. }
  4950. break;
  4951. case L'm':
  4952. for (++i; i < __x_.size(); ++i)
  4953. if (__x_[i] == L'%')
  4954. break;
  4955. if (i == __x_.size())
  4956. break;
  4957. ++i;
  4958. if (__x_[i] == L'd')
  4959. {
  4960. for (++i; i < __x_.size(); ++i)
  4961. if (__x_[i] == L'%')
  4962. break;
  4963. if (i == __x_.size())
  4964. break;
  4965. ++i;
  4966. if (__x_[i] == L'y' || __x_[i] == L'Y')
  4967. return time_base::mdy;
  4968. break;
  4969. }
  4970. break;
  4971. case L'd':
  4972. for (++i; i < __x_.size(); ++i)
  4973. if (__x_[i] == L'%')
  4974. break;
  4975. if (i == __x_.size())
  4976. break;
  4977. ++i;
  4978. if (__x_[i] == L'm')
  4979. {
  4980. for (++i; i < __x_.size(); ++i)
  4981. if (__x_[i] == L'%')
  4982. break;
  4983. if (i == __x_.size())
  4984. break;
  4985. ++i;
  4986. if (__x_[i] == L'y' || __x_[i] == L'Y')
  4987. return time_base::dmy;
  4988. break;
  4989. }
  4990. break;
  4991. }
  4992. return time_base::no_order;
  4993. }
  4994. // time_put
  4995. __time_put::__time_put(const char* nm)
  4996. : __loc_(newlocale(LC_ALL_MASK, nm, 0))
  4997. {
  4998. #ifndef _LIBCPP_NO_EXCEPTIONS
  4999. if (__loc_ == 0)
  5000. throw runtime_error("time_put_byname"
  5001. " failed to construct for " + string(nm));
  5002. #endif // _LIBCPP_NO_EXCEPTIONS
  5003. }
  5004. __time_put::__time_put(const string& nm)
  5005. : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
  5006. {
  5007. #ifndef _LIBCPP_NO_EXCEPTIONS
  5008. if (__loc_ == 0)
  5009. throw runtime_error("time_put_byname"
  5010. " failed to construct for " + nm);
  5011. #endif // _LIBCPP_NO_EXCEPTIONS
  5012. }
  5013. __time_put::~__time_put()
  5014. {
  5015. if (__loc_ != _LIBCPP_GET_C_LOCALE)
  5016. freelocale(__loc_);
  5017. }
  5018. void
  5019. __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
  5020. char __fmt, char __mod) const
  5021. {
  5022. char fmt[] = {'%', __fmt, __mod, 0};
  5023. if (__mod != 0)
  5024. swap(fmt[1], fmt[2]);
  5025. size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
  5026. __ne = __nb + n;
  5027. }
  5028. void
  5029. __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
  5030. char __fmt, char __mod) const
  5031. {
  5032. char __nar[100];
  5033. char* __ne = __nar + 100;
  5034. __do_put(__nar, __ne, __tm, __fmt, __mod);
  5035. mbstate_t mb = {0};
  5036. const char* __nb = __nar;
  5037. size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
  5038. if (j == size_t(-1))
  5039. __throw_runtime_error("locale not supported");
  5040. __we = __wb + j;
  5041. }
  5042. // moneypunct_byname
  5043. template <class charT>
  5044. static
  5045. void
  5046. __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
  5047. bool intl, char cs_precedes, char sep_by_space, char sign_posn,
  5048. charT space_char)
  5049. {
  5050. const char sign = static_cast<char>(money_base::sign);
  5051. const char space = static_cast<char>(money_base::space);
  5052. const char none = static_cast<char>(money_base::none);
  5053. const char symbol = static_cast<char>(money_base::symbol);
  5054. const char value = static_cast<char>(money_base::value);
  5055. const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
  5056. // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
  5057. // function'. "Space between sign and symbol or value" means that
  5058. // if the sign is adjacent to the symbol, there's a space between
  5059. // them, and otherwise there's a space between the sign and value.
  5060. //
  5061. // C11's localeconv specifies that the fourth character of an
  5062. // international curr_symbol is used to separate the sign and
  5063. // value when sep_by_space says to do so. C++ can't represent
  5064. // that, so we just use a space. When sep_by_space says to
  5065. // separate the symbol and value-or-sign with a space, we rearrange the
  5066. // curr_symbol to put its spacing character on the correct side of
  5067. // the symbol.
  5068. //
  5069. // We also need to avoid adding an extra space between the sign
  5070. // and value when the currency symbol is suppressed (by not
  5071. // setting showbase). We match glibc's strfmon by interpreting
  5072. // sep_by_space==1 as "omit the space when the currency symbol is
  5073. // absent".
  5074. //
  5075. // Users who want to get this right should use ICU instead.
  5076. switch (cs_precedes)
  5077. {
  5078. case 0: // value before curr_symbol
  5079. if (symbol_contains_sep) {
  5080. // Move the separator to before the symbol, to place it
  5081. // between the value and symbol.
  5082. rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,
  5083. __curr_symbol_.end());
  5084. }
  5085. switch (sign_posn)
  5086. {
  5087. case 0: // Parentheses surround the quantity and currency symbol.
  5088. pat.field[0] = sign;
  5089. pat.field[1] = value;
  5090. pat.field[2] = none; // Any space appears in the symbol.
  5091. pat.field[3] = symbol;
  5092. switch (sep_by_space)
  5093. {
  5094. case 0: // No space separates the currency symbol and value.
  5095. // This case may have changed between C99 and C11;
  5096. // assume the currency symbol matches the intention.
  5097. case 2: // Space between sign and currency or value.
  5098. // The "sign" is two parentheses, so no space here either.
  5099. return;
  5100. case 1: // Space between currency-and-sign or currency and value.
  5101. if (!symbol_contains_sep) {
  5102. // We insert the space into the symbol instead of
  5103. // setting pat.field[2]=space so that when
  5104. // showbase is not set, the space goes away too.
  5105. __curr_symbol_.insert(0, 1, space_char);
  5106. }
  5107. return;
  5108. default:
  5109. break;
  5110. }
  5111. break;
  5112. case 1: // The sign string precedes the quantity and currency symbol.
  5113. pat.field[0] = sign;
  5114. pat.field[3] = symbol;
  5115. switch (sep_by_space)
  5116. {
  5117. case 0: // No space separates the currency symbol and value.
  5118. pat.field[1] = value;
  5119. pat.field[2] = none;
  5120. return;
  5121. case 1: // Space between currency-and-sign or currency and value.
  5122. pat.field[1] = value;
  5123. pat.field[2] = none;
  5124. if (!symbol_contains_sep) {
  5125. // We insert the space into the symbol instead of
  5126. // setting pat.field[2]=space so that when
  5127. // showbase is not set, the space goes away too.
  5128. __curr_symbol_.insert(0, 1, space_char);
  5129. }
  5130. return;
  5131. case 2: // Space between sign and currency or value.
  5132. pat.field[1] = space;
  5133. pat.field[2] = value;
  5134. if (symbol_contains_sep) {
  5135. // Remove the separator from the symbol, since it
  5136. // has already appeared after the sign.
  5137. __curr_symbol_.erase(__curr_symbol_.begin());
  5138. }
  5139. return;
  5140. default:
  5141. break;
  5142. }
  5143. break;
  5144. case 2: // The sign string succeeds the quantity and currency symbol.
  5145. pat.field[0] = value;
  5146. pat.field[3] = sign;
  5147. switch (sep_by_space)
  5148. {
  5149. case 0: // No space separates the currency symbol and value.
  5150. pat.field[1] = none;
  5151. pat.field[2] = symbol;
  5152. return;
  5153. case 1: // Space between currency-and-sign or currency and value.
  5154. if (!symbol_contains_sep) {
  5155. // We insert the space into the symbol instead of
  5156. // setting pat.field[1]=space so that when
  5157. // showbase is not set, the space goes away too.
  5158. __curr_symbol_.insert(0, 1, space_char);
  5159. }
  5160. pat.field[1] = none;
  5161. pat.field[2] = symbol;
  5162. return;
  5163. case 2: // Space between sign and currency or value.
  5164. pat.field[1] = symbol;
  5165. pat.field[2] = space;
  5166. if (symbol_contains_sep) {
  5167. // Remove the separator from the symbol, since it
  5168. // should not be removed if showbase is absent.
  5169. __curr_symbol_.erase(__curr_symbol_.begin());
  5170. }
  5171. return;
  5172. default:
  5173. break;
  5174. }
  5175. break;
  5176. case 3: // The sign string immediately precedes the currency symbol.
  5177. pat.field[0] = value;
  5178. pat.field[3] = symbol;
  5179. switch (sep_by_space)
  5180. {
  5181. case 0: // No space separates the currency symbol and value.
  5182. pat.field[1] = none;
  5183. pat.field[2] = sign;
  5184. return;
  5185. case 1: // Space between currency-and-sign or currency and value.
  5186. pat.field[1] = space;
  5187. pat.field[2] = sign;
  5188. if (symbol_contains_sep) {
  5189. // Remove the separator from the symbol, since it
  5190. // has already appeared before the sign.
  5191. __curr_symbol_.erase(__curr_symbol_.begin());
  5192. }
  5193. return;
  5194. case 2: // Space between sign and currency or value.
  5195. pat.field[1] = sign;
  5196. pat.field[2] = none;
  5197. if (!symbol_contains_sep) {
  5198. // We insert the space into the symbol instead of
  5199. // setting pat.field[2]=space so that when
  5200. // showbase is not set, the space goes away too.
  5201. __curr_symbol_.insert(0, 1, space_char);
  5202. }
  5203. return;
  5204. default:
  5205. break;
  5206. }
  5207. break;
  5208. case 4: // The sign string immediately succeeds the currency symbol.
  5209. pat.field[0] = value;
  5210. pat.field[3] = sign;
  5211. switch (sep_by_space)
  5212. {
  5213. case 0: // No space separates the currency symbol and value.
  5214. pat.field[1] = none;
  5215. pat.field[2] = symbol;
  5216. return;
  5217. case 1: // Space between currency-and-sign or currency and value.
  5218. pat.field[1] = none;
  5219. pat.field[2] = symbol;
  5220. if (!symbol_contains_sep) {
  5221. // We insert the space into the symbol instead of
  5222. // setting pat.field[1]=space so that when
  5223. // showbase is not set, the space goes away too.
  5224. __curr_symbol_.insert(0, 1, space_char);
  5225. }
  5226. return;
  5227. case 2: // Space between sign and currency or value.
  5228. pat.field[1] = symbol;
  5229. pat.field[2] = space;
  5230. if (symbol_contains_sep) {
  5231. // Remove the separator from the symbol, since it
  5232. // should not disappear when showbase is absent.
  5233. __curr_symbol_.erase(__curr_symbol_.begin());
  5234. }
  5235. return;
  5236. default:
  5237. break;
  5238. }
  5239. break;
  5240. default:
  5241. break;
  5242. }
  5243. break;
  5244. case 1: // curr_symbol before value
  5245. switch (sign_posn)
  5246. {
  5247. case 0: // Parentheses surround the quantity and currency symbol.
  5248. pat.field[0] = sign;
  5249. pat.field[1] = symbol;
  5250. pat.field[2] = none; // Any space appears in the symbol.
  5251. pat.field[3] = value;
  5252. switch (sep_by_space)
  5253. {
  5254. case 0: // No space separates the currency symbol and value.
  5255. // This case may have changed between C99 and C11;
  5256. // assume the currency symbol matches the intention.
  5257. case 2: // Space between sign and currency or value.
  5258. // The "sign" is two parentheses, so no space here either.
  5259. return;
  5260. case 1: // Space between currency-and-sign or currency and value.
  5261. if (!symbol_contains_sep) {
  5262. // We insert the space into the symbol instead of
  5263. // setting pat.field[2]=space so that when
  5264. // showbase is not set, the space goes away too.
  5265. __curr_symbol_.insert(0, 1, space_char);
  5266. }
  5267. return;
  5268. default:
  5269. break;
  5270. }
  5271. break;
  5272. case 1: // The sign string precedes the quantity and currency symbol.
  5273. pat.field[0] = sign;
  5274. pat.field[3] = value;
  5275. switch (sep_by_space)
  5276. {
  5277. case 0: // No space separates the currency symbol and value.
  5278. pat.field[1] = symbol;
  5279. pat.field[2] = none;
  5280. return;
  5281. case 1: // Space between currency-and-sign or currency and value.
  5282. pat.field[1] = symbol;
  5283. pat.field[2] = none;
  5284. if (!symbol_contains_sep) {
  5285. // We insert the space into the symbol instead of
  5286. // setting pat.field[2]=space so that when
  5287. // showbase is not set, the space goes away too.
  5288. __curr_symbol_.push_back(space_char);
  5289. }
  5290. return;
  5291. case 2: // Space between sign and currency or value.
  5292. pat.field[1] = space;
  5293. pat.field[2] = symbol;
  5294. if (symbol_contains_sep) {
  5295. // Remove the separator from the symbol, since it
  5296. // has already appeared after the sign.
  5297. __curr_symbol_.pop_back();
  5298. }
  5299. return;
  5300. default:
  5301. break;
  5302. }
  5303. break;
  5304. case 2: // The sign string succeeds the quantity and currency symbol.
  5305. pat.field[0] = symbol;
  5306. pat.field[3] = sign;
  5307. switch (sep_by_space)
  5308. {
  5309. case 0: // No space separates the currency symbol and value.
  5310. pat.field[1] = none;
  5311. pat.field[2] = value;
  5312. return;
  5313. case 1: // Space between currency-and-sign or currency and value.
  5314. pat.field[1] = none;
  5315. pat.field[2] = value;
  5316. if (!symbol_contains_sep) {
  5317. // We insert the space into the symbol instead of
  5318. // setting pat.field[1]=space so that when
  5319. // showbase is not set, the space goes away too.
  5320. __curr_symbol_.push_back(space_char);
  5321. }
  5322. return;
  5323. case 2: // Space between sign and currency or value.
  5324. pat.field[1] = value;
  5325. pat.field[2] = space;
  5326. if (symbol_contains_sep) {
  5327. // Remove the separator from the symbol, since it
  5328. // will appear before the sign.
  5329. __curr_symbol_.pop_back();
  5330. }
  5331. return;
  5332. default:
  5333. break;
  5334. }
  5335. break;
  5336. case 3: // The sign string immediately precedes the currency symbol.
  5337. pat.field[0] = sign;
  5338. pat.field[3] = value;
  5339. switch (sep_by_space)
  5340. {
  5341. case 0: // No space separates the currency symbol and value.
  5342. pat.field[1] = symbol;
  5343. pat.field[2] = none;
  5344. return;
  5345. case 1: // Space between currency-and-sign or currency and value.
  5346. pat.field[1] = symbol;
  5347. pat.field[2] = none;
  5348. if (!symbol_contains_sep) {
  5349. // We insert the space into the symbol instead of
  5350. // setting pat.field[2]=space so that when
  5351. // showbase is not set, the space goes away too.
  5352. __curr_symbol_.push_back(space_char);
  5353. }
  5354. return;
  5355. case 2: // Space between sign and currency or value.
  5356. pat.field[1] = space;
  5357. pat.field[2] = symbol;
  5358. if (symbol_contains_sep) {
  5359. // Remove the separator from the symbol, since it
  5360. // has already appeared after the sign.
  5361. __curr_symbol_.pop_back();
  5362. }
  5363. return;
  5364. default:
  5365. break;
  5366. }
  5367. break;
  5368. case 4: // The sign string immediately succeeds the currency symbol.
  5369. pat.field[0] = symbol;
  5370. pat.field[3] = value;
  5371. switch (sep_by_space)
  5372. {
  5373. case 0: // No space separates the currency symbol and value.
  5374. pat.field[1] = sign;
  5375. pat.field[2] = none;
  5376. return;
  5377. case 1: // Space between currency-and-sign or currency and value.
  5378. pat.field[1] = sign;
  5379. pat.field[2] = space;
  5380. if (symbol_contains_sep) {
  5381. // Remove the separator from the symbol, since it
  5382. // should not disappear when showbase is absent.
  5383. __curr_symbol_.pop_back();
  5384. }
  5385. return;
  5386. case 2: // Space between sign and currency or value.
  5387. pat.field[1] = none;
  5388. pat.field[2] = sign;
  5389. if (!symbol_contains_sep) {
  5390. // We insert the space into the symbol instead of
  5391. // setting pat.field[1]=space so that when
  5392. // showbase is not set, the space goes away too.
  5393. __curr_symbol_.push_back(space_char);
  5394. }
  5395. return;
  5396. default:
  5397. break;
  5398. }
  5399. break;
  5400. default:
  5401. break;
  5402. }
  5403. break;
  5404. default:
  5405. break;
  5406. }
  5407. pat.field[0] = symbol;
  5408. pat.field[1] = sign;
  5409. pat.field[2] = none;
  5410. pat.field[3] = value;
  5411. }
  5412. template<>
  5413. void
  5414. moneypunct_byname<char, false>::init(const char* nm)
  5415. {
  5416. typedef moneypunct<char, false> base;
  5417. __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
  5418. #ifndef _LIBCPP_NO_EXCEPTIONS
  5419. if (loc == nullptr)
  5420. throw runtime_error("moneypunct_byname"
  5421. " failed to construct for " + string(nm));
  5422. #endif // _LIBCPP_NO_EXCEPTIONS
  5423. lconv* lc = __libcpp_localeconv_l(loc.get());
  5424. if (*lc->mon_decimal_point)
  5425. __decimal_point_ = *lc->mon_decimal_point;
  5426. else
  5427. __decimal_point_ = base::do_decimal_point();
  5428. if (*lc->mon_thousands_sep)
  5429. __thousands_sep_ = *lc->mon_thousands_sep;
  5430. else
  5431. __thousands_sep_ = base::do_thousands_sep();
  5432. __grouping_ = lc->mon_grouping;
  5433. __curr_symbol_ = lc->currency_symbol;
  5434. if (lc->frac_digits != CHAR_MAX)
  5435. __frac_digits_ = lc->frac_digits;
  5436. else
  5437. __frac_digits_ = base::do_frac_digits();
  5438. if (lc->p_sign_posn == 0)
  5439. __positive_sign_ = "()";
  5440. else
  5441. __positive_sign_ = lc->positive_sign;
  5442. if (lc->n_sign_posn == 0)
  5443. __negative_sign_ = "()";
  5444. else
  5445. __negative_sign_ = lc->negative_sign;
  5446. // Assume the positive and negative formats will want spaces in
  5447. // the same places in curr_symbol since there's no way to
  5448. // represent anything else.
  5449. string_type __dummy_curr_symbol = __curr_symbol_;
  5450. __init_pat(__pos_format_, __dummy_curr_symbol, false,
  5451. lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
  5452. __init_pat(__neg_format_, __curr_symbol_, false,
  5453. lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
  5454. }
  5455. template<>
  5456. void
  5457. moneypunct_byname<char, true>::init(const char* nm)
  5458. {
  5459. typedef moneypunct<char, true> base;
  5460. __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
  5461. #ifndef _LIBCPP_NO_EXCEPTIONS
  5462. if (loc == nullptr)
  5463. throw runtime_error("moneypunct_byname"
  5464. " failed to construct for " + string(nm));
  5465. #endif // _LIBCPP_NO_EXCEPTIONS
  5466. lconv* lc = __libcpp_localeconv_l(loc.get());
  5467. if (*lc->mon_decimal_point)
  5468. __decimal_point_ = *lc->mon_decimal_point;
  5469. else
  5470. __decimal_point_ = base::do_decimal_point();
  5471. if (*lc->mon_thousands_sep)
  5472. __thousands_sep_ = *lc->mon_thousands_sep;
  5473. else
  5474. __thousands_sep_ = base::do_thousands_sep();
  5475. __grouping_ = lc->mon_grouping;
  5476. __curr_symbol_ = lc->int_curr_symbol;
  5477. if (lc->int_frac_digits != CHAR_MAX)
  5478. __frac_digits_ = lc->int_frac_digits;
  5479. else
  5480. __frac_digits_ = base::do_frac_digits();
  5481. #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
  5482. if (lc->p_sign_posn == 0)
  5483. #else // _LIBCPP_MSVCRT
  5484. if (lc->int_p_sign_posn == 0)
  5485. #endif // !_LIBCPP_MSVCRT
  5486. __positive_sign_ = "()";
  5487. else
  5488. __positive_sign_ = lc->positive_sign;
  5489. #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
  5490. if(lc->n_sign_posn == 0)
  5491. #else // _LIBCPP_MSVCRT
  5492. if (lc->int_n_sign_posn == 0)
  5493. #endif // !_LIBCPP_MSVCRT
  5494. __negative_sign_ = "()";
  5495. else
  5496. __negative_sign_ = lc->negative_sign;
  5497. // Assume the positive and negative formats will want spaces in
  5498. // the same places in curr_symbol since there's no way to
  5499. // represent anything else.
  5500. string_type __dummy_curr_symbol = __curr_symbol_;
  5501. #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
  5502. __init_pat(__pos_format_, __dummy_curr_symbol, true,
  5503. lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
  5504. __init_pat(__neg_format_, __curr_symbol_, true,
  5505. lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
  5506. #else // _LIBCPP_MSVCRT
  5507. __init_pat(__pos_format_, __dummy_curr_symbol, true,
  5508. lc->int_p_cs_precedes, lc->int_p_sep_by_space,
  5509. lc->int_p_sign_posn, ' ');
  5510. __init_pat(__neg_format_, __curr_symbol_, true,
  5511. lc->int_n_cs_precedes, lc->int_n_sep_by_space,
  5512. lc->int_n_sign_posn, ' ');
  5513. #endif // !_LIBCPP_MSVCRT
  5514. }
  5515. template<>
  5516. void
  5517. moneypunct_byname<wchar_t, false>::init(const char* nm)
  5518. {
  5519. typedef moneypunct<wchar_t, false> base;
  5520. __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
  5521. #ifndef _LIBCPP_NO_EXCEPTIONS
  5522. if (loc == nullptr)
  5523. throw runtime_error("moneypunct_byname"
  5524. " failed to construct for " + string(nm));
  5525. #endif // _LIBCPP_NO_EXCEPTIONS
  5526. lconv* lc = __libcpp_localeconv_l(loc.get());
  5527. if (*lc->mon_decimal_point)
  5528. __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
  5529. else
  5530. __decimal_point_ = base::do_decimal_point();
  5531. if (*lc->mon_thousands_sep)
  5532. __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
  5533. else
  5534. __thousands_sep_ = base::do_thousands_sep();
  5535. __grouping_ = lc->mon_grouping;
  5536. wchar_t wbuf[100];
  5537. mbstate_t mb = {0};
  5538. const char* bb = lc->currency_symbol;
  5539. size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
  5540. if (j == size_t(-1))
  5541. __throw_runtime_error("locale not supported");
  5542. wchar_t* wbe = wbuf + j;
  5543. __curr_symbol_.assign(wbuf, wbe);
  5544. if (lc->frac_digits != CHAR_MAX)
  5545. __frac_digits_ = lc->frac_digits;
  5546. else
  5547. __frac_digits_ = base::do_frac_digits();
  5548. if (lc->p_sign_posn == 0)
  5549. __positive_sign_ = L"()";
  5550. else
  5551. {
  5552. mb = mbstate_t();
  5553. bb = lc->positive_sign;
  5554. j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
  5555. if (j == size_t(-1))
  5556. __throw_runtime_error("locale not supported");
  5557. wbe = wbuf + j;
  5558. __positive_sign_.assign(wbuf, wbe);
  5559. }
  5560. if (lc->n_sign_posn == 0)
  5561. __negative_sign_ = L"()";
  5562. else
  5563. {
  5564. mb = mbstate_t();
  5565. bb = lc->negative_sign;
  5566. j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
  5567. if (j == size_t(-1))
  5568. __throw_runtime_error("locale not supported");
  5569. wbe = wbuf + j;
  5570. __negative_sign_.assign(wbuf, wbe);
  5571. }
  5572. // Assume the positive and negative formats will want spaces in
  5573. // the same places in curr_symbol since there's no way to
  5574. // represent anything else.
  5575. string_type __dummy_curr_symbol = __curr_symbol_;
  5576. __init_pat(__pos_format_, __dummy_curr_symbol, false,
  5577. lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
  5578. __init_pat(__neg_format_, __curr_symbol_, false,
  5579. lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
  5580. }
  5581. template<>
  5582. void
  5583. moneypunct_byname<wchar_t, true>::init(const char* nm)
  5584. {
  5585. typedef moneypunct<wchar_t, true> base;
  5586. __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
  5587. #ifndef _LIBCPP_NO_EXCEPTIONS
  5588. if (loc == nullptr)
  5589. throw runtime_error("moneypunct_byname"
  5590. " failed to construct for " + string(nm));
  5591. #endif // _LIBCPP_NO_EXCEPTIONS
  5592. lconv* lc = __libcpp_localeconv_l(loc.get());
  5593. if (*lc->mon_decimal_point)
  5594. __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
  5595. else
  5596. __decimal_point_ = base::do_decimal_point();
  5597. if (*lc->mon_thousands_sep)
  5598. __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
  5599. else
  5600. __thousands_sep_ = base::do_thousands_sep();
  5601. __grouping_ = lc->mon_grouping;
  5602. wchar_t wbuf[100];
  5603. mbstate_t mb = {0};
  5604. const char* bb = lc->int_curr_symbol;
  5605. size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
  5606. if (j == size_t(-1))
  5607. __throw_runtime_error("locale not supported");
  5608. wchar_t* wbe = wbuf + j;
  5609. __curr_symbol_.assign(wbuf, wbe);
  5610. if (lc->int_frac_digits != CHAR_MAX)
  5611. __frac_digits_ = lc->int_frac_digits;
  5612. else
  5613. __frac_digits_ = base::do_frac_digits();
  5614. #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
  5615. if (lc->p_sign_posn == 0)
  5616. #else // _LIBCPP_MSVCRT
  5617. if (lc->int_p_sign_posn == 0)
  5618. #endif // !_LIBCPP_MSVCRT
  5619. __positive_sign_ = L"()";
  5620. else
  5621. {
  5622. mb = mbstate_t();
  5623. bb = lc->positive_sign;
  5624. j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
  5625. if (j == size_t(-1))
  5626. __throw_runtime_error("locale not supported");
  5627. wbe = wbuf + j;
  5628. __positive_sign_.assign(wbuf, wbe);
  5629. }
  5630. #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
  5631. if (lc->n_sign_posn == 0)
  5632. #else // _LIBCPP_MSVCRT
  5633. if (lc->int_n_sign_posn == 0)
  5634. #endif // !_LIBCPP_MSVCRT
  5635. __negative_sign_ = L"()";
  5636. else
  5637. {
  5638. mb = mbstate_t();
  5639. bb = lc->negative_sign;
  5640. j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
  5641. if (j == size_t(-1))
  5642. __throw_runtime_error("locale not supported");
  5643. wbe = wbuf + j;
  5644. __negative_sign_.assign(wbuf, wbe);
  5645. }
  5646. // Assume the positive and negative formats will want spaces in
  5647. // the same places in curr_symbol since there's no way to
  5648. // represent anything else.
  5649. string_type __dummy_curr_symbol = __curr_symbol_;
  5650. #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
  5651. __init_pat(__pos_format_, __dummy_curr_symbol, true,
  5652. lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
  5653. __init_pat(__neg_format_, __curr_symbol_, true,
  5654. lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
  5655. #else // _LIBCPP_MSVCRT
  5656. __init_pat(__pos_format_, __dummy_curr_symbol, true,
  5657. lc->int_p_cs_precedes, lc->int_p_sep_by_space,
  5658. lc->int_p_sign_posn, L' ');
  5659. __init_pat(__neg_format_, __curr_symbol_, true,
  5660. lc->int_n_cs_precedes, lc->int_n_sep_by_space,
  5661. lc->int_n_sign_posn, L' ');
  5662. #endif // !_LIBCPP_MSVCRT
  5663. }
  5664. void __do_nothing(void*) {}
  5665. void __throw_runtime_error(const char* msg)
  5666. {
  5667. #ifndef _LIBCPP_NO_EXCEPTIONS
  5668. throw runtime_error(msg);
  5669. #else
  5670. (void)msg;
  5671. #endif
  5672. }
  5673. template class collate<char>;
  5674. template class collate<wchar_t>;
  5675. template class num_get<char>;
  5676. template class num_get<wchar_t>;
  5677. template struct __num_get<char>;
  5678. template struct __num_get<wchar_t>;
  5679. template class num_put<char>;
  5680. template class num_put<wchar_t>;
  5681. template struct __num_put<char>;
  5682. template struct __num_put<wchar_t>;
  5683. template class time_get<char>;
  5684. template class time_get<wchar_t>;
  5685. template class time_get_byname<char>;
  5686. template class time_get_byname<wchar_t>;
  5687. template class time_put<char>;
  5688. template class time_put<wchar_t>;
  5689. template class time_put_byname<char>;
  5690. template class time_put_byname<wchar_t>;
  5691. template class moneypunct<char, false>;
  5692. template class moneypunct<char, true>;
  5693. template class moneypunct<wchar_t, false>;
  5694. template class moneypunct<wchar_t, true>;
  5695. template class moneypunct_byname<char, false>;
  5696. template class moneypunct_byname<char, true>;
  5697. template class moneypunct_byname<wchar_t, false>;
  5698. template class moneypunct_byname<wchar_t, true>;
  5699. template class money_get<char>;
  5700. template class money_get<wchar_t>;
  5701. template class __money_get<char>;
  5702. template class __money_get<wchar_t>;
  5703. template class money_put<char>;
  5704. template class money_put<wchar_t>;
  5705. template class __money_put<char>;
  5706. template class __money_put<wchar_t>;
  5707. template class messages<char>;
  5708. template class messages<wchar_t>;
  5709. template class messages_byname<char>;
  5710. template class messages_byname<wchar_t>;
  5711. template class codecvt_byname<char, char, mbstate_t>;
  5712. template class codecvt_byname<wchar_t, char, mbstate_t>;
  5713. template class codecvt_byname<char16_t, char, mbstate_t>;
  5714. template class codecvt_byname<char32_t, char, mbstate_t>;
  5715. template class __vector_base_common<true>;
  5716. _LIBCPP_END_NAMESPACE_STD
  5717. #endif // !defined(_LIBCPP_SGX_CONFIG)