static_string.hpp 187 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206
  1. //
  2. // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. // Copyright (c) 2019-2020 Krystian Stasiowski (sdkrystian at gmail dot com)
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // Official repository: https://github.com/boostorg/static_string
  9. //
  10. #ifndef BOOST_STATIC_STRING_STATIC_STRING_HPP
  11. #define BOOST_STATIC_STRING_STATIC_STRING_HPP
  12. #if defined(__GNUC__) && __GNUC__ >= 8
  13. #pragma GCC diagnostic push
  14. #pragma GCC system_header
  15. // false positives
  16. #pragma GCC diagnostic ignored "-Warray-bounds"
  17. #pragma GCC diagnostic ignored "-Wrestrict"
  18. #pragma GCC diagnostic ignored "-Wstringop-overflow"
  19. #endif
  20. #if defined(__GNUC__) && __GNUC__ >= 7
  21. #pragma GCC diagnostic push
  22. #pragma GCC diagnostic ignored "-Wnoexcept-type"
  23. #endif
  24. // External include guard
  25. #ifndef BOOST_STATIC_STRING_CONFIG_HPP
  26. #include <boost/static_string/config.hpp>
  27. #include <boost/config/workaround.hpp>
  28. #endif
  29. #include <algorithm>
  30. #include <cstdint>
  31. #include <cstdio>
  32. #if defined(BOOST_STATIC_STRING_USE_STD_FORMAT)
  33. #include <format>
  34. #endif
  35. #include <functional>
  36. #include <initializer_list>
  37. #include <limits>
  38. #include <iosfwd>
  39. #include <type_traits>
  40. #include <utility>
  41. namespace boost {
  42. namespace static_strings {
  43. #ifndef BOOST_STATIC_STRING_DOCS
  44. template<std::size_t N, typename CharT, typename Traits>
  45. class basic_static_string;
  46. //------------------------------------------------------------------------------
  47. //
  48. // Aliases
  49. //
  50. //------------------------------------------------------------------------------
  51. template<std::size_t N>
  52. using static_string =
  53. basic_static_string<N, char, std::char_traits<char>>;
  54. #ifdef BOOST_STATIC_STRING_HAS_WCHAR
  55. template<std::size_t N>
  56. using static_wstring =
  57. basic_static_string<N, wchar_t, std::char_traits<wchar_t>>;
  58. #endif
  59. template<std::size_t N>
  60. using static_u16string =
  61. basic_static_string<N, char16_t, std::char_traits<char16_t>>;
  62. template<std::size_t N>
  63. using static_u32string =
  64. basic_static_string<N, char32_t, std::char_traits<char32_t>>;
  65. #ifdef __cpp_char8_t
  66. template<std::size_t N>
  67. using static_u8string =
  68. basic_static_string<N, char8_t, std::char_traits<char8_t>>;
  69. #endif
  70. //--------------------------------------------------------------------------
  71. //
  72. // Detail
  73. //
  74. //--------------------------------------------------------------------------
  75. namespace detail {
  76. // Find the smallest width integral type that can hold a value as large as N (Glen Fernandes)
  77. template<std::size_t N>
  78. using smallest_width =
  79. typename std::conditional<(N <= (std::numeric_limits<unsigned char>::max)()), unsigned char,
  80. typename std::conditional<(N <= (std::numeric_limits<unsigned short>::max)()), unsigned short,
  81. typename std::conditional<(N <= (std::numeric_limits<unsigned int>::max)()), unsigned int,
  82. typename std::conditional<(N <= (std::numeric_limits<unsigned long>::max)()), unsigned long,
  83. typename std::conditional<(N <= (std::numeric_limits<unsigned long long>::max)()), unsigned long long,
  84. std::size_t>::type>::type>::type>::type>::type;
  85. // std::is_nothrow_convertible is C++20
  86. template<typename To>
  87. void is_nothrow_convertible_helper(To) noexcept;
  88. // MSVC is unable to parse this as a single expression, so a helper is needed
  89. template<typename From, typename To, typename =
  90. decltype(is_nothrow_convertible_helper<To>(std::declval<From>()))>
  91. struct is_nothrow_convertible_msvc_helper
  92. {
  93. static const bool value =
  94. noexcept(is_nothrow_convertible_helper<To>(std::declval<From>()));
  95. };
  96. template<typename From, typename To, typename = void>
  97. struct is_nothrow_convertible
  98. : std::false_type { };
  99. template<typename From, typename To>
  100. struct is_nothrow_convertible<From, To, typename std::enable_if<
  101. is_nothrow_convertible_msvc_helper<From, To>::value>::type>
  102. : std::true_type { };
  103. // GCC 4.8, 4.9 workaround for void_t to make the defining-type-id dependant
  104. template<typename...>
  105. struct void_t_helper
  106. {
  107. using type = void;
  108. };
  109. // void_t for c++11
  110. template<typename... Ts>
  111. using void_t = typename void_t_helper<Ts...>::type;
  112. template <class T, typename CharT, typename = void>
  113. struct is_string_like : std::false_type {};
  114. template<typename T, typename CharT>
  115. struct is_string_like<
  116. T, CharT,
  117. void_t<
  118. decltype(std::declval<CharT const*&>() = std::declval<T>().data()),
  119. decltype(std::declval<std::size_t&>() = std::declval<T>().size())>>
  120. : std::true_type
  121. {};
  122. // Check if a type can be used for templated
  123. // overloads string_view_type
  124. // This will be used by overloads that accept the string_view types
  125. // directly and other convertible types such as std::string.
  126. // When no string_view type is available, then we check for the
  127. // data and size member functions, and use them directly for assignments.
  128. // Types convertible to basic_static_string are not considered viewable
  129. // to prevent any ambiguity during overload resolution.
  130. template<std::size_t N, typename T, typename CharT, typename Traits, typename = void>
  131. struct enable_if_viewable { };
  132. template<std::size_t N, typename T, typename CharT, typename Traits>
  133. struct enable_if_viewable<N, T, CharT, Traits,
  134. typename std::enable_if<
  135. #if !defined(BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW)
  136. is_string_like<T, CharT>::value &&
  137. !std::is_convertible<const T&, const basic_static_string<N, CharT, Traits>&>::value
  138. #elif defined(BOOST_STATIC_STRING_STANDALONE)
  139. std::is_convertible<const T&, std::basic_string_view<CharT, Traits>>::value &&
  140. !std::is_convertible<const T&, const CharT*>::value &&
  141. !std::is_convertible<const T&, const basic_static_string<N, CharT, Traits>&>::value
  142. #else
  143. (
  144. std::is_convertible<const T&, basic_string_view<CharT, Traits>>::value ||
  145. std::is_convertible<const T&, core::basic_string_view<CharT>>::value
  146. ) &&
  147. !std::is_convertible<const T&, const CharT*>::value &&
  148. !std::is_convertible<const T&, const basic_static_string<N, CharT, Traits>&>::value
  149. #endif
  150. >::type>
  151. {
  152. using type = void;
  153. };
  154. template<std::size_t N, typename T, typename CharT, typename Traits>
  155. using enable_if_viewable_t = typename enable_if_viewable<N, T, CharT, Traits>::type;
  156. // The common string_view type used in private operations with enable_if_viewable_t
  157. // - T const& itself when no string_view type is available
  158. // - basic_string_view (boost::string_view or std::string_view) when in
  159. // standalone because core::detail::string_view is unavailable
  160. // - core::detail::basic_string_view otherwise because it's convertible
  161. // to and from most types, including std::string_view
  162. // After converting a parameter to a common_string_view_type reference, we
  163. // can use the data() and size() member functions.
  164. #if !defined(BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW)
  165. template<typename T, typename CharT, typename Traits>
  166. using common_string_view_type = T const&;
  167. #elif defined(BOOST_STATIC_STRING_STANDALONE)
  168. template<typename T, typename CharT, typename Traits>
  169. using common_string_view_type = basic_string_view<CharT, Traits>;
  170. #else
  171. template <class T, typename CharT, typename Traits, typename = void>
  172. struct common_string_view_type_impl {};
  173. template<typename T, typename CharT, typename Traits>
  174. struct common_string_view_type_impl<
  175. T, CharT, Traits,
  176. typename std::enable_if<
  177. is_string_like<T, CharT>::value &&
  178. !std::is_convertible<const T&, basic_string_view<CharT, Traits>>::value &&
  179. !std::is_convertible<const T&, core::basic_string_view<CharT>>::value>::type>
  180. {
  181. using type = T const&;
  182. };
  183. template<typename T, typename CharT, typename Traits>
  184. struct common_string_view_type_impl<
  185. T, CharT, Traits,
  186. typename std::enable_if<
  187. std::is_convertible<const T&, basic_string_view<CharT, Traits>>::value &&
  188. !std::is_convertible<const T&, core::basic_string_view<CharT>>::value>::type>
  189. {
  190. using type = basic_string_view<CharT, Traits>;
  191. };
  192. template<typename T, typename CharT, typename Traits>
  193. struct common_string_view_type_impl<
  194. T, CharT, Traits,
  195. typename std::enable_if<
  196. std::is_convertible<const T&, core::basic_string_view<CharT>>::value>::type>
  197. {
  198. using type = core::basic_string_view<CharT>;
  199. };
  200. template<typename T, typename CharT, typename Traits>
  201. using common_string_view_type = typename common_string_view_type_impl<T, CharT, Traits>::type;
  202. #endif
  203. // Simplified check for if a type is an iterator
  204. template<typename T, typename = void>
  205. struct is_iterator : std::false_type { };
  206. template<typename T>
  207. struct is_iterator<T,
  208. typename std::enable_if<std::is_class<T>::value,
  209. void_t<typename T::iterator_category>>::type>
  210. : std::true_type { };
  211. template<typename T>
  212. struct is_iterator<T*, void>
  213. : std::true_type { };
  214. template<typename T, typename = void>
  215. struct is_input_iterator : std::false_type { };
  216. template<typename T>
  217. struct is_input_iterator<T, typename std::enable_if<is_iterator<T>::value &&
  218. std::is_convertible<typename std::iterator_traits<T>::iterator_category,
  219. std::input_iterator_tag>::value>::type>
  220. : std::true_type { };
  221. template<typename T, typename = void>
  222. struct is_forward_iterator : std::false_type { };
  223. template<typename T>
  224. struct is_forward_iterator<T, typename std::enable_if<is_iterator<T>::value &&
  225. std::is_convertible<typename std::iterator_traits<T>::iterator_category,
  226. std::forward_iterator_tag>::value>::type>
  227. : std::true_type { };
  228. template<typename T, typename = void>
  229. struct is_subtractable
  230. : std::false_type { };
  231. template<typename T>
  232. struct is_subtractable<T, void_t<decltype(std::declval<T&>() - std::declval<T&>())>>
  233. : std::true_type { };
  234. // constexpr distance for c++14
  235. template<
  236. typename ForwardIt,
  237. typename std::enable_if<!is_subtractable<ForwardIt>::value>::type* = nullptr>
  238. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  239. std::size_t
  240. distance(ForwardIt first, ForwardIt last)
  241. {
  242. std::size_t dist = 0;
  243. for (; first != last; ++first, ++dist);
  244. return dist;
  245. }
  246. template<
  247. typename RandomIt,
  248. typename std::enable_if<is_subtractable<RandomIt>::value>::type* = nullptr>
  249. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  250. std::size_t
  251. distance(RandomIt first, RandomIt last)
  252. {
  253. return last - first;
  254. }
  255. // Copy using traits, respecting iterator rules
  256. template<typename Traits, typename InputIt, typename CharT>
  257. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  258. void
  259. copy_with_traits(
  260. InputIt first,
  261. InputIt last,
  262. CharT* out)
  263. {
  264. for (; first != last; ++first, ++out)
  265. Traits::assign(*out, *first);
  266. }
  267. // Optimization for using the smallest possible type
  268. template<std::size_t N, typename CharT, typename Traits>
  269. class static_string_base
  270. {
  271. private:
  272. using size_type = smallest_width<N>;
  273. using value_type = typename Traits::char_type;
  274. using pointer = value_type*;
  275. using const_pointer = const value_type*;
  276. public:
  277. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  278. static_string_base() noexcept { };
  279. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  280. pointer
  281. data_impl() noexcept
  282. {
  283. return data_;
  284. }
  285. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  286. const_pointer
  287. data_impl() const noexcept
  288. {
  289. return data_;
  290. }
  291. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  292. std::size_t
  293. size_impl() const noexcept
  294. {
  295. return size_;
  296. }
  297. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  298. std::size_t
  299. set_size(std::size_t n) noexcept
  300. {
  301. // Functions that set size will throw
  302. // if the new size would exceed max_size()
  303. // therefore we can guarantee that this will
  304. // not lose data.
  305. return size_ = size_type(n);
  306. }
  307. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  308. void
  309. term_impl() noexcept
  310. {
  311. Traits::assign(data_[size_], value_type());
  312. }
  313. size_type size_ = 0;
  314. value_type data_[N + 1]{};
  315. };
  316. // Optimization for when the size is 0
  317. template<typename CharT, typename Traits>
  318. class static_string_base<0, CharT, Traits>
  319. {
  320. private:
  321. using value_type = typename Traits::char_type;
  322. using pointer = value_type*;
  323. public:
  324. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  325. static_string_base() noexcept { }
  326. // Modifying the null terminator is UB
  327. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  328. pointer
  329. data_impl() const noexcept
  330. {
  331. return const_cast<pointer>(&null_);
  332. }
  333. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  334. std::size_t
  335. size_impl() const noexcept
  336. {
  337. return 0;
  338. }
  339. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  340. std::size_t
  341. set_size(std::size_t) const noexcept
  342. {
  343. return 0;
  344. }
  345. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  346. void
  347. term_impl() const noexcept { }
  348. private:
  349. static constexpr const value_type null_{};
  350. };
  351. // This is only needed in C++14 and lower.
  352. // see http://eel.is/c++draft/depr.static.constexpr
  353. #ifndef BOOST_STATIC_STRING_CPP17
  354. template<typename CharT, typename Traits>
  355. constexpr
  356. const
  357. typename static_string_base<0, CharT, Traits>::value_type
  358. static_string_base<0, CharT, Traits>::
  359. null_;
  360. #endif
  361. template<typename CharT, typename Traits>
  362. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  363. inline
  364. int
  365. lexicographical_compare(
  366. const CharT* s1,
  367. std::size_t n1,
  368. const CharT* s2,
  369. std::size_t n2) noexcept
  370. {
  371. if(n1 < n2)
  372. return Traits::compare(
  373. s1, s2, n1) <= 0 ? -1 : 1;
  374. if(n1 > n2)
  375. return Traits::compare(
  376. s1, s2, n2) >= 0 ? 1 : -1;
  377. return Traits::compare(s1, s2, n1);
  378. }
  379. template<typename Traits, typename Integer>
  380. inline
  381. char*
  382. integer_to_string(
  383. char* str_end,
  384. Integer value,
  385. std::true_type) noexcept
  386. {
  387. if (value == 0)
  388. {
  389. Traits::assign(*--str_end, '0');
  390. return str_end;
  391. }
  392. if (value < 0)
  393. {
  394. const bool is_min = value == (std::numeric_limits<Integer>::min)();
  395. // negation of a min value cannot be represented
  396. if (is_min)
  397. value = (std::numeric_limits<Integer>::max)();
  398. else
  399. value = -value;
  400. const auto last_char = str_end - 1;
  401. for (; value > 0; value /= 10)
  402. Traits::assign(*--str_end, "0123456789"[value % 10]);
  403. // minimum values are powers of 2, so it will
  404. // never terminate with a 9.
  405. if (is_min)
  406. Traits::assign(*last_char, Traits::to_char_type(
  407. Traits::to_int_type(*last_char) + 1));
  408. Traits::assign(*--str_end, '-');
  409. return str_end;
  410. }
  411. for (; value > 0; value /= 10)
  412. Traits::assign(*--str_end, "0123456789"[value % 10]);
  413. return str_end;
  414. }
  415. template<typename Traits, typename Integer>
  416. inline
  417. char*
  418. integer_to_string(
  419. char* str_end,
  420. Integer value,
  421. std::false_type) noexcept
  422. {
  423. if (value == 0)
  424. {
  425. Traits::assign(*--str_end, '0');
  426. return str_end;
  427. }
  428. for (; value > 0; value /= 10)
  429. Traits::assign(*--str_end, "0123456789"[value % 10]);
  430. return str_end;
  431. }
  432. template<typename Traits, typename Integer>
  433. inline
  434. wchar_t*
  435. integer_to_wstring(
  436. wchar_t* str_end,
  437. Integer value,
  438. std::true_type) noexcept
  439. {
  440. if (value == 0)
  441. {
  442. Traits::assign(*--str_end, L'0');
  443. return str_end;
  444. }
  445. if (value < 0)
  446. {
  447. const bool is_min = value == (std::numeric_limits<Integer>::min)();
  448. // negation of a min value cannot be represented
  449. if (is_min)
  450. value = (std::numeric_limits<Integer>::max)();
  451. else
  452. value = -value;
  453. const auto last_char = str_end - 1;
  454. for (; value > 0; value /= 10)
  455. Traits::assign(*--str_end, L"0123456789"[value % 10]);
  456. // minimum values are powers of 2, so it will
  457. // never terminate with a 9.
  458. if (is_min)
  459. Traits::assign(*last_char, Traits::to_char_type(
  460. Traits::to_int_type(*last_char) + 1));
  461. Traits::assign(*--str_end, L'-');
  462. return str_end;
  463. }
  464. for (; value > 0; value /= 10)
  465. Traits::assign(*--str_end, L"0123456789"[value % 10]);
  466. return str_end;
  467. }
  468. template<typename Traits, typename Integer>
  469. inline
  470. wchar_t*
  471. integer_to_wstring(
  472. wchar_t* str_end,
  473. Integer value,
  474. std::false_type) noexcept
  475. {
  476. if (value == 0)
  477. {
  478. Traits::assign(*--str_end, L'0');
  479. return str_end;
  480. }
  481. for (; value > 0; value /= 10)
  482. Traits::assign(*--str_end, L"0123456789"[value % 10]);
  483. return str_end;
  484. }
  485. template<std::size_t N, typename Integer>
  486. inline
  487. static_string<N>
  488. to_static_string_int_impl(Integer value) noexcept
  489. {
  490. using size_type = typename static_string<N>::size_type;
  491. static_string<N> result;
  492. result.resize_and_overwrite(
  493. N,
  494. [&](char* buffer, size_type) -> size_type
  495. {
  496. char* const digits_end = buffer + N;
  497. char* const digits_begin = integer_to_string<std::char_traits<char>, Integer>(
  498. digits_end, value, std::is_signed<Integer>{});
  499. const size_type len = digits_end - digits_begin;
  500. std::char_traits<char>::move(buffer, digits_begin, len);
  501. return len;
  502. }
  503. );
  504. return result;
  505. }
  506. #ifdef BOOST_STATIC_STRING_HAS_WCHAR
  507. template<std::size_t N, typename Integer>
  508. inline
  509. static_wstring<N>
  510. to_static_wstring_int_impl(Integer value) noexcept
  511. {
  512. using size_type = typename static_wstring<N>::size_type;
  513. static_wstring<N> result;
  514. result.resize_and_overwrite(
  515. N,
  516. [&](wchar_t* buffer, size_type) -> size_type
  517. {
  518. wchar_t* const digits_end = buffer + N;
  519. wchar_t* const digits_begin = integer_to_wstring<std::char_traits<wchar_t>, Integer>(
  520. digits_end, value, std::is_signed<Integer>{});
  521. const size_type len = digits_end - digits_begin;
  522. std::char_traits<wchar_t>::move(buffer, digits_begin, len);
  523. return len;
  524. }
  525. );
  526. return result;
  527. }
  528. #endif
  529. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  530. inline
  531. int
  532. count_digits(std::size_t value)
  533. {
  534. return value < 10 ? 1 : count_digits(value / 10) + 1;
  535. }
  536. // Ignore -Wformat-truncation, we know what
  537. // we are doing here. The version check does
  538. // not need to be extremely precise.
  539. #if defined(__GNUC__) && __GNUC__ >= 7
  540. #pragma GCC diagnostic push
  541. #pragma GCC diagnostic ignored "-Wformat-truncation"
  542. #endif
  543. #if defined(BOOST_STATIC_STRING_USE_STD_FORMAT)
  544. template<std::size_t N, typename FloatingPoint>
  545. inline
  546. static_string<N>
  547. cpp26_to_static_string(FloatingPoint value) noexcept
  548. {
  549. using size_type = typename static_string<N>::size_type;
  550. static_string<N> result;
  551. result.resize_and_overwrite(
  552. N,
  553. [&](char* buffer, size_type) -> size_type
  554. {
  555. const auto formatted = std::format_to_n(buffer, N, "{}", value);
  556. return formatted.size;
  557. }
  558. );
  559. return result;
  560. }
  561. #endif
  562. template<std::size_t N>
  563. inline
  564. static_string<N>
  565. to_static_string_float_impl(double value) noexcept
  566. {
  567. #if defined(BOOST_STATIC_STRING_USE_STD_FORMAT)
  568. return cpp26_to_static_string<N>(value);
  569. #else
  570. using size_type = typename static_string<N>::size_type;
  571. static_string<N> result;
  572. // we have to assume here that no reasonable implementation
  573. // will require more than 2^63 chars to represent a float value.
  574. const long long narrow =
  575. static_cast<long long>(N);
  576. result.resize_and_overwrite(
  577. N,
  578. [&](char* buffer, size_type) -> size_type
  579. {
  580. // we know that a formatting error will not occur, so
  581. // we assume that the result is always positive
  582. std::size_t length = std::snprintf(buffer, N + 1, "%f", value);
  583. if (length > N)
  584. {
  585. // the + 4 is for the decimal, 'e',
  586. // its sign, and the sign of the integral portion
  587. const int reserved_count =
  588. (std::max)(2, count_digits(
  589. std::numeric_limits<double>::max_exponent10)) + 4;
  590. const int precision = narrow > reserved_count ?
  591. N - reserved_count : 0;
  592. // switch to scientific notation
  593. length = std::snprintf(buffer, N + 1, "%.*e", precision, value);
  594. }
  595. return length;
  596. }
  597. );
  598. return result;
  599. #endif
  600. }
  601. template<std::size_t N>
  602. inline
  603. static_string<N>
  604. to_static_string_float_impl(float value) noexcept
  605. {
  606. #if defined(BOOST_STATIC_STRING_USE_STD_FORMAT)
  607. return cpp26_to_static_string<N>(value);
  608. #else
  609. return to_static_string_float_impl<N>(static_cast<double>(value));
  610. #endif
  611. }
  612. template<std::size_t N>
  613. inline
  614. static_string<N>
  615. to_static_string_float_impl(long double value) noexcept
  616. {
  617. #if defined(BOOST_STATIC_STRING_USE_STD_FORMAT)
  618. return cpp26_to_static_string<N>(value);
  619. #else
  620. using size_type = typename static_string<N>::size_type;
  621. static_string<N> result;
  622. // we have to assume here that no reasonable implementation
  623. // will require more than 2^63 chars to represent a float value.
  624. const long long narrow =
  625. static_cast<long long>(N);
  626. result.resize_and_overwrite(
  627. N,
  628. [&](char* buffer, size_type)->size_type
  629. {
  630. // snprintf returns the number of characters
  631. // that would have been written
  632. // we know that a formatting error will not occur, so
  633. // we assume that the result is always positive
  634. std::size_t length = std::snprintf(buffer, N + 1, "%Lf", value);
  635. if (length > N)
  636. {
  637. // the + 4 is for the decimal, 'e',
  638. // its sign, and the sign of the integral portion
  639. const int reserved_count =
  640. (std::max)(2, count_digits(
  641. std::numeric_limits<long double>::max_exponent10)) + 4;
  642. const int precision = narrow > reserved_count ?
  643. N - reserved_count : 0;
  644. // switch to scientific notation
  645. length = std::snprintf(buffer, N + 1, "%.*Le", precision, value);
  646. }
  647. return length;
  648. }
  649. );
  650. return result;
  651. #endif
  652. }
  653. #ifdef BOOST_STATIC_STRING_HAS_WCHAR
  654. #if defined(BOOST_STATIC_STRING_USE_STD_FORMAT)
  655. template<std::size_t N, typename FloatingPoint>
  656. inline
  657. static_wstring<N>
  658. cpp26_to_static_wstring(FloatingPoint value) noexcept
  659. {
  660. using size_type = typename static_wstring<N>::size_type;
  661. static_wstring<N> result;
  662. result.resize_and_overwrite(
  663. N,
  664. [&](wchar_t* buffer, size_type) -> size_type
  665. {
  666. const auto formatted = std::format_to_n(buffer, N, L"{}", value);
  667. return formatted.size;
  668. }
  669. );
  670. return result;
  671. }
  672. #endif
  673. template<std::size_t N>
  674. inline
  675. static_wstring<N>
  676. to_static_wstring_float_impl(double value) noexcept
  677. {
  678. #if defined(BOOST_STATIC_STRING_USE_STD_FORMAT)
  679. return cpp26_to_static_wstring<N>(value);
  680. #else
  681. using size_type = typename static_wstring<N>::size_type;
  682. static_wstring<N> result;
  683. // we have to assume here that no reasonable implementation
  684. // will require more than 2^63 chars to represent a float value.
  685. const long long narrow =
  686. static_cast<long long>(N);
  687. result.resize_and_overwrite(
  688. N,
  689. [&](wchar_t* buffer, size_type) -> size_type
  690. {
  691. // swprintf returns a negative number if it can't
  692. // fit all the characters in the buffer.
  693. // mingw has a non-standard swprintf, so
  694. // this just covers all the bases. short
  695. // circuit evaluation will ensure that the
  696. // second operand is not evaluated on conforming
  697. // implementations.
  698. int num_written =
  699. std::swprintf(buffer, N + 1, L"%f", value);
  700. if (num_written < 0 ||
  701. num_written > narrow)
  702. {
  703. // the + 4 is for the decimal, 'e',
  704. // its sign, and the sign of the integral portion
  705. const int reserved_count =
  706. (std::max)(2, count_digits(
  707. std::numeric_limits<double>::max_exponent10)) + 4;
  708. const int precision = narrow > reserved_count ?
  709. N - reserved_count : 0;
  710. // switch to scientific notation
  711. num_written = std::swprintf(buffer, N + 1, L"%.*e", precision, value);
  712. }
  713. return num_written;
  714. }
  715. );
  716. return result;
  717. #endif
  718. }
  719. template<std::size_t N>
  720. inline
  721. static_wstring<N>
  722. to_static_wstring_float_impl(float value) noexcept
  723. {
  724. #if defined(BOOST_STATIC_STRING_USE_STD_FORMAT)
  725. return cpp26_to_static_wstring<N>(value);
  726. #else
  727. return to_static_wstring_float_impl<N>(static_cast<double>(value));
  728. #endif
  729. }
  730. template<std::size_t N>
  731. inline
  732. static_wstring<N>
  733. to_static_wstring_float_impl(long double value) noexcept
  734. {
  735. #if defined(BOOST_STATIC_STRING_USE_STD_FORMAT)
  736. return cpp26_to_static_wstring<N>(value);
  737. #else
  738. using size_type = typename static_wstring<N>::size_type;
  739. static_wstring<N> result;
  740. // we have to assume here that no reasonable implementation
  741. // will require more than 2^63 chars to represent a float value.
  742. const long long narrow =
  743. static_cast<long long>(N);
  744. result.resize_and_overwrite(
  745. N,
  746. [&](wchar_t* buffer, size_type) -> size_type
  747. {
  748. // swprintf returns a negative number if it can't
  749. // fit all the characters in the buffer.
  750. // mingw has a non-standard swprintf, so
  751. // this just covers all the bases. short
  752. // circuit evaluation will ensure that the
  753. // second operand is not evaluated on conforming
  754. // implementations.
  755. int num_written =
  756. std::swprintf(buffer, N + 1, L"%Lf", value);
  757. if (num_written < 0 ||
  758. num_written > narrow)
  759. {
  760. // the + 4 is for the decimal, 'e',
  761. // its sign, and the sign of the integral portion
  762. const int reserved_count =
  763. (std::max)(2, count_digits(
  764. std::numeric_limits<long double>::max_exponent10)) + 4;
  765. const int precision = narrow > reserved_count ?
  766. N - reserved_count : 0;
  767. // switch to scientific notation
  768. num_written = std::swprintf(buffer, N + 1, L"%.*Le", precision, value);
  769. }
  770. return num_written;
  771. }
  772. );
  773. return result;
  774. #endif
  775. }
  776. #endif
  777. #if defined(__GNUC__) && __GNUC__ >= 7
  778. #pragma GCC diagnostic pop
  779. #endif
  780. template<typename Traits, typename CharT, typename ForwardIterator>
  781. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  782. inline
  783. ForwardIterator
  784. find_not_of(
  785. ForwardIterator first,
  786. ForwardIterator last,
  787. const CharT* str,
  788. std::size_t n) noexcept
  789. {
  790. for (; first != last; ++first)
  791. if (!Traits::find(str, n, *first))
  792. return first;
  793. return last;
  794. }
  795. // constexpr search for C++14
  796. template<typename ForwardIt1, typename ForwardIt2, typename BinaryPredicate>
  797. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  798. inline
  799. ForwardIt1
  800. search(
  801. ForwardIt1 first,
  802. ForwardIt1 last,
  803. ForwardIt2 s_first,
  804. ForwardIt2 s_last,
  805. BinaryPredicate p)
  806. {
  807. for (; ; ++first)
  808. {
  809. ForwardIt1 it = first;
  810. for (ForwardIt2 s_it = s_first; ; ++it, ++s_it)
  811. {
  812. if (s_it == s_last)
  813. return first;
  814. if (it == last)
  815. return last;
  816. if (!p(*it, *s_it))
  817. break;
  818. }
  819. }
  820. }
  821. template<typename InputIt, typename ForwardIt, typename BinaryPredicate>
  822. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  823. inline
  824. InputIt
  825. find_first_of(
  826. InputIt first,
  827. InputIt last,
  828. ForwardIt s_first,
  829. ForwardIt s_last,
  830. BinaryPredicate p)
  831. {
  832. for (; first != last; ++first)
  833. for (ForwardIt it = s_first; it != s_last; ++it)
  834. if (p(*first, *it))
  835. return first;
  836. return last;
  837. }
  838. // KRYSTIAN TODO: add a constexpr rotate
  839. // Check if a pointer lies within the range {src_first, src_last)
  840. // without unspecified behavior, allowing it to be used
  841. // in a constant evaluation.
  842. template<typename T>
  843. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  844. inline
  845. bool
  846. ptr_in_range(
  847. const T* src_first,
  848. const T* src_last,
  849. const T* ptr)
  850. {
  851. #if defined(BOOST_STATIC_STRING_CPP14) && \
  852. defined(BOOST_STATIC_STRING_IS_CONST_EVAL)
  853. // Our second best option is to use is_constant_evaluated
  854. // and a loop that checks for equality, since equality for
  855. // pointer to object types is never unspecified in this case.
  856. if (BOOST_STATIC_STRING_IS_CONST_EVAL)
  857. {
  858. for (; src_first != src_last; ++src_first)
  859. if (ptr == src_first)
  860. return true;
  861. return false;
  862. }
  863. #endif
  864. // We want to make this usable in constant expressions as much as possible
  865. // while retaining the guarentee that the comparison has a strict total ordering.
  866. // We also want this to be fast. Since different compilers have differing levels
  867. // of conformance, we will settle for the best option that is available.
  868. // We don't care about this in C++11, since this function would have
  869. // no applications in constant expressions.
  870. #if defined(BOOST_STATIC_STRING_CPP14) && \
  871. defined(BOOST_STATIC_STRING_NO_PTR_COMP_FUNCTIONS)
  872. // If library comparison functions don't work,
  873. // we can use try builtin comparison operators instead.
  874. return ptr >= src_first && ptr < src_last;
  875. #else
  876. // Use the library comparison functions if we can't use
  877. // is_constant_evaluated or if we don't need to.
  878. return std::greater_equal<const T*>()(ptr, src_first) &&
  879. std::less<const T*>()(ptr, src_last);
  880. #endif
  881. }
  882. // This workaround is for gcc 5,
  883. // which prohibits throw expressions in constexpr
  884. // functions, but for some reason permits them in
  885. // constructors.
  886. #ifdef BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR
  887. template<typename Exception>
  888. struct throw_exception
  889. {
  890. BOOST_STATIC_STRING_NORETURN
  891. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  892. throw_exception(const char* msg)
  893. {
  894. BOOST_STATIC_STRING_THROW(Exception(msg));
  895. }
  896. };
  897. #else
  898. template<typename Exception>
  899. BOOST_STATIC_STRING_NORETURN
  900. inline
  901. void
  902. throw_exception(const char* msg)
  903. {
  904. BOOST_STATIC_STRING_THROW(Exception(msg));
  905. }
  906. #endif
  907. } // detail
  908. #endif
  909. //--------------------------------------------------------------------------
  910. //
  911. // static_string
  912. //
  913. //--------------------------------------------------------------------------
  914. /** A fixed-capacity string.
  915. These objects behave like `std::string` except that the storage
  916. is not dynamically allocated but rather fixed in size, and
  917. stored in the object itself.
  918. These strings offer performance advantages when an algorithm
  919. can execute with a reasonable upper limit on the size of a value.
  920. @par Aliases
  921. The following alias templates are provided for convenience:
  922. @code
  923. template<std::size_t N>
  924. using static_string =
  925. basic_static_string<N, char, std::char_traits<char>>;
  926. @endcode
  927. @code
  928. template<std::size_t N>
  929. using static_wstring =
  930. basic_static_string<N, wchar_t, std::char_traits<wchar_t>>;
  931. @endcode
  932. @code
  933. template<std::size_t N>
  934. using static_u16string =
  935. basic_static_string<N, char16_t, std::char_traits<char16_t>>;
  936. @endcode
  937. @code
  938. template<std::size_t N>
  939. using static_u32string =
  940. basic_static_string<N, char32_t, std::char_traits<char32_t>>;
  941. @endcode
  942. Addtionally, the alias template `static_u8string` is provided in C++20
  943. @code
  944. template<std::size_t N>
  945. using static_u8string =
  946. basic_static_string<N, char8_t, std::char_traits<char8_t>>;
  947. @endcode
  948. @see @ref to_static_string.
  949. */
  950. template<std::size_t N, typename CharT,
  951. typename Traits = std::char_traits<CharT>>
  952. class basic_static_string
  953. #ifndef BOOST_STATIC_STRING_DOCS
  954. : private detail::static_string_base<N, CharT, Traits>
  955. #endif
  956. {
  957. private:
  958. template<std::size_t, class, class>
  959. friend class basic_static_string;
  960. public:
  961. //--------------------------------------------------------------------------
  962. //
  963. // Member types
  964. //
  965. //--------------------------------------------------------------------------
  966. /// The traits type.
  967. using traits_type = Traits;
  968. /// The character type.
  969. using value_type = typename traits_type::char_type;
  970. /// The size type.
  971. using size_type = std::size_t;
  972. /// The difference type.
  973. using difference_type = std::ptrdiff_t;
  974. /// The pointer type.
  975. using pointer = value_type*;
  976. /// The reference type.
  977. using reference = value_type&;
  978. /// The constant pointer type.
  979. using const_pointer = const value_type*;
  980. /// The constant reference type.
  981. using const_reference = const value_type&;
  982. /// The iterator type.
  983. using iterator = value_type*;
  984. /// The constant iterator type.
  985. using const_iterator = const value_type*;
  986. /// The reverse iterator type.
  987. using reverse_iterator =
  988. std::reverse_iterator<iterator>;
  989. /// The constant reverse iterator type.
  990. using const_reverse_iterator =
  991. std::reverse_iterator<const_iterator>;
  992. #ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
  993. /// The string view type.
  994. using string_view_type =
  995. basic_string_view<value_type, traits_type>;
  996. #endif
  997. //--------------------------------------------------------------------------
  998. //
  999. // Constants
  1000. //
  1001. //--------------------------------------------------------------------------
  1002. /// Maximum size of the string excluding any null terminator
  1003. static constexpr size_type static_capacity = N;
  1004. /// A special index
  1005. static constexpr size_type npos = size_type(-1);
  1006. //--------------------------------------------------------------------------
  1007. //
  1008. // Construction
  1009. //
  1010. //--------------------------------------------------------------------------
  1011. /** Constructor.
  1012. Construct an empty string
  1013. */
  1014. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  1015. basic_static_string() noexcept
  1016. {
  1017. #ifdef BOOST_STATIC_STRING_CPP20
  1018. term();
  1019. #endif
  1020. }
  1021. /** Constructor.
  1022. Construct the string with `count` copies of character `ch`.
  1023. The behavior is undefined if `count >= npos`
  1024. */
  1025. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1026. basic_static_string(
  1027. size_type count,
  1028. value_type ch)
  1029. {
  1030. assign(count, ch);
  1031. }
  1032. /** Constructor.
  1033. Construct with a substring (pos, other.size()) of `other`.
  1034. */
  1035. template<std::size_t M>
  1036. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1037. basic_static_string(
  1038. const basic_static_string<M, CharT, Traits>& other,
  1039. size_type pos)
  1040. {
  1041. assign(other, pos);
  1042. }
  1043. /** Constructor.
  1044. Construct with a substring (pos, count) of `other`.
  1045. */
  1046. template<std::size_t M>
  1047. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1048. basic_static_string(
  1049. const basic_static_string<M, CharT, Traits>& other,
  1050. size_type pos,
  1051. size_type count)
  1052. {
  1053. assign(other, pos, count);
  1054. }
  1055. /** Constructor.
  1056. Construct with the first `count` characters of `s`, including nulls.
  1057. */
  1058. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1059. basic_static_string(
  1060. const_pointer s,
  1061. size_type count)
  1062. {
  1063. assign(s, count);
  1064. }
  1065. /** Constructor.
  1066. Construct from a null terminated string.
  1067. */
  1068. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1069. basic_static_string(const_pointer s)
  1070. {
  1071. assign(s);
  1072. }
  1073. /** Constructor.
  1074. Construct from a range of characters
  1075. */
  1076. template<typename InputIterator
  1077. #ifndef BOOST_STATIC_STRING_DOCS
  1078. , typename std::enable_if<
  1079. detail::is_input_iterator<InputIterator>
  1080. ::value>::type* = nullptr
  1081. #endif
  1082. >
  1083. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1084. basic_static_string(
  1085. InputIterator first,
  1086. InputIterator last)
  1087. {
  1088. // KRYSTIAN TODO: we can use a better algorithm if this is a forward iterator
  1089. assign(first, last);
  1090. }
  1091. /** Constructor.
  1092. Copy constructor.
  1093. */
  1094. basic_static_string(const basic_static_string& other) = default;
  1095. /** Constructor.
  1096. Copy constructor.
  1097. */
  1098. template<std::size_t M>
  1099. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1100. basic_static_string(
  1101. const basic_static_string<M, CharT, Traits>& other)
  1102. {
  1103. assign(other);
  1104. }
  1105. /** Constructor.
  1106. Construct from an initializer list
  1107. */
  1108. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1109. basic_static_string(std::initializer_list<value_type> init)
  1110. {
  1111. assign(init.begin(), init.size());
  1112. }
  1113. /** Constructor.
  1114. Construct from a object convertible to `string_view_type`
  1115. */
  1116. template<typename T
  1117. #ifndef BOOST_STATIC_STRING_DOCS
  1118. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  1119. #endif
  1120. >
  1121. explicit
  1122. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1123. basic_static_string(const T& t)
  1124. {
  1125. assign(t);
  1126. }
  1127. /** Constructor.
  1128. Construct from any object convertible to `string_view_type`.
  1129. The range (pos, n) is extracted from the value
  1130. obtained by converting `t` to `string_view_type`,
  1131. and used to construct the string.
  1132. */
  1133. template<typename T
  1134. #ifndef BOOST_STATIC_STRING_DOCS
  1135. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  1136. #endif
  1137. >
  1138. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1139. basic_static_string(
  1140. const T& t,
  1141. size_type pos,
  1142. size_type n)
  1143. {
  1144. assign(t, pos, n);
  1145. }
  1146. //--------------------------------------------------------------------------
  1147. //
  1148. // Assignment
  1149. //
  1150. //--------------------------------------------------------------------------
  1151. /** Assign to the string.
  1152. Replaces the contents with those of
  1153. the string `s`.
  1154. @par Complexity
  1155. Linear in `s.size()`.
  1156. @par Exception Safety
  1157. Strong guarantee.
  1158. @return `*this`
  1159. @param s The string to replace
  1160. the contents with.
  1161. @throw std::length_error `s.size() > max_size()`.
  1162. */
  1163. basic_static_string&
  1164. operator=(const basic_static_string& s) = default;
  1165. /** Assign to the string.
  1166. Replaces the contents with those of
  1167. the string `s`.
  1168. @par Complexity
  1169. Linear in `s.size()`.
  1170. @par Exception Safety
  1171. Strong guarantee.
  1172. @tparam M The size of the other string.
  1173. @return `*this`
  1174. @param s The string to replace
  1175. the contents with.
  1176. @throw std::length_error `s.size() > max_size()`.
  1177. */
  1178. template<std::size_t M>
  1179. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1180. basic_static_string&
  1181. operator=(const basic_static_string<M, CharT, Traits>& s)
  1182. {
  1183. return assign(s);
  1184. }
  1185. /** Assign to the string.
  1186. Replaces the contents with those of
  1187. `{s, s + traits_type::length(s))`.
  1188. @par Complexity
  1189. Linear in `count`.
  1190. @par Exception Safety
  1191. Strong guarantee.
  1192. @return `*this`
  1193. @param s A pointer to the string to copy from.
  1194. @throw std::length_error `traits_type::length(s) > max_size()`.
  1195. */
  1196. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1197. basic_static_string&
  1198. operator=(const_pointer s)
  1199. {
  1200. return assign(s);
  1201. }
  1202. /** Assign to the string.
  1203. Replaces the contents with a single copy of
  1204. the character `ch`.
  1205. @par Complexity
  1206. Constant.
  1207. @par Exception Safety
  1208. Strong guarantee.
  1209. @return `*this`
  1210. @param ch The character to assign to.
  1211. @throw std::length_error `count > max_size()`.
  1212. */
  1213. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1214. basic_static_string&
  1215. operator=(value_type ch)
  1216. {
  1217. return assign_char(ch,
  1218. std::integral_constant<bool, (N > 0)>{});
  1219. }
  1220. /** Assign to the string.
  1221. Replaces the contents with those of the
  1222. initializer list `ilist`.
  1223. @par Complexity
  1224. Linear in `init.size()`.
  1225. @par Exception Safety
  1226. Strong guarantee.
  1227. @return `*this`
  1228. @param ilist The initializer list to copy from.
  1229. @throw std::length_error `ilist.size() > max_size()`.
  1230. */
  1231. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1232. basic_static_string&
  1233. operator=(std::initializer_list<value_type> ilist)
  1234. {
  1235. return assign(ilist);
  1236. }
  1237. /** Assign to the string.
  1238. Replaces the contents with those of
  1239. `sv`, where `sv` is `string_view_type(t)`.
  1240. @par Complexity
  1241. Linear in `sv.size()`.
  1242. @par Exception Safety
  1243. Strong guarantee.
  1244. @note
  1245. The view can contain null characters.
  1246. @tparam T A type convertible to `string_view_type`.
  1247. @par Constraints
  1248. @code
  1249. std::is_convertible<const T&, string_view>::value &&
  1250. !std::is_convertible<const T&, const CharT*>::value &&
  1251. !std::is_convertible<const T&, const basic_static_string&>::value
  1252. @endcode
  1253. @return `*this`
  1254. @param t The object to assign from.
  1255. @throw std::length_error `sv.size() > max_size()`.
  1256. */
  1257. template<typename T
  1258. #ifndef BOOST_STATIC_STRING_DOCS
  1259. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  1260. #endif
  1261. >
  1262. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1263. basic_static_string&
  1264. operator=(const T& t)
  1265. {
  1266. return assign(t);
  1267. }
  1268. /** Assign to the string.
  1269. Replaces the contents with `count` copies of
  1270. character `ch`.
  1271. @par Complexity
  1272. Linear in `count`.
  1273. @par Exception Safety
  1274. Strong guarantee.
  1275. @return `*this`
  1276. @param count The size of the resulting string.
  1277. @param ch The value to initialize characters
  1278. of the string with.
  1279. @throw std::length_error `count > max_size()`.
  1280. */
  1281. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1282. basic_static_string&
  1283. assign(
  1284. size_type count,
  1285. value_type ch);
  1286. /** Assign to the string.
  1287. Replaces the contents with those of
  1288. the string `s`.
  1289. @par Complexity
  1290. Linear in `s.size()`.
  1291. @par Exception Safety
  1292. Strong guarantee.
  1293. @tparam M The size of the other string.
  1294. @return `*this`
  1295. @param s The string to replace
  1296. the contents with.
  1297. @throw std::length_error `s.size() > max_size()`.
  1298. */
  1299. template<std::size_t M
  1300. #ifndef BOOST_STATIC_STRING_DOCS
  1301. , typename std::enable_if<(M < N)>::type* = nullptr
  1302. #endif
  1303. >
  1304. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1305. basic_static_string&
  1306. assign(const basic_static_string<M, CharT, Traits>& s)
  1307. {
  1308. return assign_unchecked(s.data(), s.size());
  1309. }
  1310. #ifndef BOOST_STATIC_STRING_DOCS
  1311. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1312. basic_static_string&
  1313. assign(const basic_static_string& s) noexcept
  1314. {
  1315. if (data() == s.data())
  1316. return *this;
  1317. return assign_unchecked(s.data(), s.size());
  1318. }
  1319. template<std::size_t M,
  1320. typename std::enable_if<(M > N)>::type* = nullptr>
  1321. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1322. basic_static_string&
  1323. assign(const basic_static_string<M, CharT, Traits>& s)
  1324. {
  1325. return assign(s.data(), s.size());
  1326. }
  1327. #endif
  1328. /** Assign to the string.
  1329. Replaces the contents with those of the string `sub`,
  1330. where `sub` is `s.substr(pos, count)`.
  1331. @par Complexity
  1332. Linear in `sub.size()`.
  1333. @par Exception Safety
  1334. Strong guarantee.
  1335. @tparam M The capacity of the other string.
  1336. @return `*this`
  1337. @param s The string to replace
  1338. the contents with.
  1339. @param pos The index at which to begin the substring.
  1340. @param count The size of the substring. The default
  1341. argument for this parameter is @ref npos.
  1342. @throw std::length_error `sub.size() > max_size()`.
  1343. */
  1344. template<std::size_t M>
  1345. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1346. basic_static_string&
  1347. assign(
  1348. const basic_static_string<M, CharT, Traits>& s,
  1349. size_type pos,
  1350. size_type count = npos)
  1351. {
  1352. return assign(s.data() + pos, s.capped_length(pos, count));
  1353. }
  1354. /** Assign to the string.
  1355. Replaces the contents with those of `{s, s + count)`.
  1356. @par Complexity
  1357. Linear in `count`.
  1358. @par Exception Safety
  1359. Strong guarantee.
  1360. @note
  1361. The range can contain null characters.
  1362. @return `*this`
  1363. @param count The number of characters to copy.
  1364. @param s A pointer to the string to copy from.
  1365. @throw std::length_error `count > max_size()`.
  1366. */
  1367. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1368. basic_static_string&
  1369. assign(
  1370. const_pointer s,
  1371. size_type count);
  1372. /** Assign to the string.
  1373. Replaces the contents with those of
  1374. `{s, s + traits_type::length(s))`.
  1375. @par Complexity
  1376. Linear in `count`.
  1377. @par Exception Safety
  1378. Strong guarantee.
  1379. @return `*this`
  1380. @param s A pointer to the string to copy from.
  1381. @throw std::length_error `traits_type::length(s) > max_size()`.
  1382. */
  1383. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1384. basic_static_string&
  1385. assign(const_pointer s)
  1386. {
  1387. return assign(s, traits_type::length(s));
  1388. }
  1389. /** Assign to the string.
  1390. Replaces the contents with the characters
  1391. in the range `{first, last)`.
  1392. @par Complexity
  1393. Linear in `std::distance(first, last)`.
  1394. @par Exception Safety
  1395. Strong guarantee.
  1396. @tparam InputIterator The type of the iterators.
  1397. @par Constraints
  1398. `InputIterator` satisfies __InputIterator__.
  1399. @return `*this`
  1400. @param first An iterator referring to the
  1401. first character to assign.
  1402. @param last An iterator past the end
  1403. of the range to assign from.
  1404. @throw std::length_error `std::distance(first, last) > max_size()`.
  1405. */
  1406. template<typename InputIterator>
  1407. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1408. #ifdef BOOST_STATIC_STRING_DOCS
  1409. basic_static_string&
  1410. #else
  1411. typename std::enable_if<
  1412. detail::is_input_iterator<InputIterator>::value,
  1413. basic_static_string&>::type
  1414. #endif
  1415. assign(
  1416. InputIterator first,
  1417. InputIterator last);
  1418. /** Assign to the string.
  1419. Replaces the contents with those of the
  1420. initializer list `ilist`.
  1421. @par Complexity
  1422. Linear in `init.size()`.
  1423. @par Exception Safety
  1424. Strong guarantee.
  1425. @return `*this`
  1426. @param ilist The initializer list to copy from.
  1427. @throw std::length_error `ilist.size() > max_size()`.
  1428. */
  1429. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1430. basic_static_string&
  1431. assign(
  1432. std::initializer_list<value_type> ilist)
  1433. {
  1434. return assign(ilist.begin(), ilist.end());
  1435. }
  1436. /** Assign to the string.
  1437. Replaces the contents with those of
  1438. `sv`, where `sv` is `string_view_type(t)`.
  1439. @par Complexity
  1440. Linear in `sv.size()`.
  1441. @par Exception Safety
  1442. Strong guarantee.
  1443. @note
  1444. The view can contain null characters.
  1445. @tparam T A type convertible to `string_view_type`.
  1446. @par Constraints
  1447. @code
  1448. std::is_convertible<const T&, string_view>::value &&
  1449. !std::is_convertible<const T&, const CharT*>::value &&
  1450. !std::is_convertible<const T&, const basic_static_string&>::value
  1451. @endcode
  1452. @return `*this`
  1453. @param t The object to assign from.
  1454. @throw std::length_error `sv.size() > max_size()`.
  1455. */
  1456. template<typename T
  1457. #ifndef BOOST_STATIC_STRING_DOCS
  1458. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  1459. #endif
  1460. >
  1461. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1462. basic_static_string&
  1463. assign(const T& t)
  1464. {
  1465. detail::common_string_view_type<T, CharT, Traits> sv = t;
  1466. return assign(sv.data(), sv.size());
  1467. }
  1468. /** Assign to the string.
  1469. Replaces the contents with those of the substring `sv`,
  1470. where `sv` is `string_view_type(t).substr(pos, count)`.
  1471. @par Complexity
  1472. Linear in `sv.size()`.
  1473. @par Exception Safety
  1474. Strong guarantee.
  1475. @note
  1476. The view can contain null characters.
  1477. @tparam T A type convertible to `string_view_type`.
  1478. @par Constraints
  1479. @code
  1480. std::is_convertible<const T&, string_view>::value &&
  1481. !std::is_convertible<const T&, const CharT*>::value &&
  1482. !std::is_convertible<const T&, const basic_static_string&>::value
  1483. @endcode
  1484. @return `*this`
  1485. @param t The object to assign from.
  1486. @param pos The index at which to begin the substring.
  1487. @param count The size of the substring. The default
  1488. argument for this parameter is @ref npos.
  1489. @throw std::length_error `sv.size() > max_size()`.
  1490. */
  1491. template<typename T
  1492. #ifndef BOOST_STATIC_STRING_DOCS
  1493. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  1494. #endif
  1495. >
  1496. basic_static_string&
  1497. assign(
  1498. const T& t,
  1499. size_type pos,
  1500. size_type count = npos)
  1501. {
  1502. detail::common_string_view_type<T, CharT, Traits> sv = t;
  1503. if( pos > sv.size() )
  1504. detail::throw_exception<std::out_of_range>(
  1505. "pos >= t.size()");
  1506. std::size_t rlen = (std::min)( count, sv.size() - pos );
  1507. return assign(sv.data() + pos, rlen);
  1508. }
  1509. //--------------------------------------------------------------------------
  1510. //
  1511. // Element access
  1512. //
  1513. //--------------------------------------------------------------------------
  1514. /** Access a character with bounds checking.
  1515. Returns a reference to the character at
  1516. index `pos`.
  1517. @par Complexity
  1518. Constant.
  1519. @par Exception Safety
  1520. Strong guarantee.
  1521. @param pos The index to access.
  1522. @throw std::out_of_range `pos >= size()`
  1523. */
  1524. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1525. reference
  1526. at(size_type pos)
  1527. {
  1528. if (pos >= size())
  1529. detail::throw_exception<std::out_of_range>(
  1530. "pos >= size()");
  1531. return data()[pos];
  1532. }
  1533. /** Access a character with bounds checking.
  1534. Returns a reference to the character at
  1535. index `pos`.
  1536. @par Complexity
  1537. Constant.
  1538. @par Exception Safety
  1539. Strong guarantee.
  1540. @param pos The index to access.
  1541. @throw std::out_of_range `pos >= size()`
  1542. */
  1543. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1544. const_reference
  1545. at(size_type pos) const
  1546. {
  1547. if (pos >= size())
  1548. detail::throw_exception<std::out_of_range>(
  1549. "pos >= size()");
  1550. return data()[pos];
  1551. }
  1552. /** Access a character.
  1553. Returns a reference to the character at
  1554. index `pos`.
  1555. @par Complexity
  1556. Constant.
  1557. @par Precondition
  1558. `pos >= size`
  1559. @param pos The index to access.
  1560. */
  1561. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1562. reference
  1563. operator[](size_type pos) noexcept
  1564. {
  1565. return data()[pos];
  1566. }
  1567. /** Access a character.
  1568. Returns a reference to the character at
  1569. index `pos`.
  1570. @par Complexity
  1571. Constant.
  1572. @par Precondition
  1573. `pos >= size`
  1574. @param pos The index to access.
  1575. */
  1576. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1577. const_reference
  1578. operator[](size_type pos) const noexcept
  1579. {
  1580. return data()[pos];
  1581. }
  1582. /** Return the first character.
  1583. Returns a reference to the first character.
  1584. @par Complexity
  1585. Constant.
  1586. @par Precondition
  1587. `not empty()`
  1588. */
  1589. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1590. reference
  1591. front() noexcept
  1592. {
  1593. return data()[0];
  1594. }
  1595. /** Return the first character.
  1596. Returns a reference to the first character.
  1597. @par Complexity
  1598. Constant.
  1599. @par Precondition
  1600. `not empty()`
  1601. */
  1602. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1603. const_reference
  1604. front() const noexcept
  1605. {
  1606. return data()[0];
  1607. }
  1608. /** Return the last character.
  1609. Returns a reference to the last character.
  1610. @par Complexity
  1611. Constant.
  1612. @par Precondition
  1613. `not empty()`
  1614. */
  1615. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1616. reference
  1617. back() noexcept
  1618. {
  1619. return data()[size() - 1];
  1620. }
  1621. /** Return the last character.
  1622. Returns a reference to the last character.
  1623. @par Complexity
  1624. Constant.
  1625. @par Precondition
  1626. `not empty()`
  1627. */
  1628. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1629. const_reference
  1630. back() const noexcept
  1631. {
  1632. return data()[size() - 1];
  1633. }
  1634. /** Return a pointer to the string.
  1635. Returns a pointer to the underlying array
  1636. serving as storage. The value returned is such that
  1637. the range `{data(), data() + size())` is always a
  1638. valid range, even if the container is empty.
  1639. @par Complexity
  1640. Constant.
  1641. @note The value returned from this function
  1642. is never never a null pointer value.
  1643. */
  1644. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1645. pointer
  1646. data() noexcept
  1647. {
  1648. return this->data_impl();
  1649. }
  1650. /** Return a pointer to the string.
  1651. Returns a pointer to the underlying array
  1652. serving as storage. The value returned is such that
  1653. the range `{data(), data() + size())` is always a
  1654. valid range, even if the container is empty.
  1655. @par Complexity
  1656. Constant.
  1657. @note The value returned from this function
  1658. is never never a null pointer value.
  1659. */
  1660. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1661. const_pointer
  1662. data() const noexcept
  1663. {
  1664. return this->data_impl();
  1665. }
  1666. /** Return a pointer to the string.
  1667. Returns a pointer to the underlying array
  1668. serving as storage. The value returned is such that
  1669. the range `{c_str(), c_str() + size())` is always a
  1670. valid range, even if the container is empty.
  1671. @par Complexity
  1672. Constant.
  1673. @note The value returned from this function
  1674. is never never a null pointer value.
  1675. */
  1676. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1677. const_pointer
  1678. c_str() const noexcept
  1679. {
  1680. return data();
  1681. }
  1682. #ifdef BOOST_STATIC_STRING_DOCS
  1683. /** Convert to a string view referring to the string.
  1684. Returns a string view referring to the
  1685. underlying character string.
  1686. @par Complexity
  1687. Constant.
  1688. */
  1689. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  1690. operator string_view_type() const noexcept
  1691. {
  1692. return string_view_type(data(), size());
  1693. }
  1694. #else
  1695. #ifdef BOOST_STATIC_STRING_HAS_STD_STRING_VIEW
  1696. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  1697. operator std::basic_string_view<CharT, Traits>() const noexcept
  1698. {
  1699. return std::basic_string_view<CharT, Traits>(data(), size());
  1700. }
  1701. #endif
  1702. #ifndef BOOST_STATIC_STRING_STANDALONE
  1703. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  1704. operator ::boost::basic_string_view<CharT, Traits>() const noexcept
  1705. {
  1706. return ::boost::basic_string_view<CharT, Traits>(data(), size());
  1707. }
  1708. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  1709. operator ::boost::core::basic_string_view<CharT>() const noexcept
  1710. {
  1711. return ::boost::core::basic_string_view<CharT>(data(), size());
  1712. }
  1713. #endif
  1714. #endif
  1715. //--------------------------------------------------------------------------
  1716. //
  1717. // Iterators
  1718. //
  1719. //--------------------------------------------------------------------------
  1720. /// Return an iterator to the beginning.
  1721. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1722. iterator
  1723. begin() noexcept
  1724. {
  1725. return data();
  1726. }
  1727. /// Return an iterator to the beginning.
  1728. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1729. const_iterator
  1730. begin() const noexcept
  1731. {
  1732. return data();
  1733. }
  1734. /// Return an iterator to the beginning.
  1735. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1736. const_iterator
  1737. cbegin() const noexcept
  1738. {
  1739. return data();
  1740. }
  1741. /// Return an iterator to the end.
  1742. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1743. iterator
  1744. end() noexcept
  1745. {
  1746. return data() + size();
  1747. }
  1748. /// Return an iterator to the end.
  1749. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1750. const_iterator
  1751. end() const noexcept
  1752. {
  1753. return data() + size();
  1754. }
  1755. /// Return an iterator to the end.
  1756. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1757. const_iterator
  1758. cend() const noexcept
  1759. {
  1760. return data() + size();
  1761. }
  1762. /// Return a reverse iterator to the beginning.
  1763. BOOST_STATIC_STRING_CPP17_CONSTEXPR
  1764. reverse_iterator
  1765. rbegin() noexcept
  1766. {
  1767. return reverse_iterator{end()};
  1768. }
  1769. /// Return a reverse iterator to the beginning.
  1770. BOOST_STATIC_STRING_CPP17_CONSTEXPR
  1771. const_reverse_iterator
  1772. rbegin() const noexcept
  1773. {
  1774. return const_reverse_iterator{cend()};
  1775. }
  1776. /// Return a reverse iterator to the beginning.
  1777. BOOST_STATIC_STRING_CPP17_CONSTEXPR
  1778. const_reverse_iterator
  1779. crbegin() const noexcept
  1780. {
  1781. return const_reverse_iterator{cend()};
  1782. }
  1783. /// Return a reverse iterator to the end.
  1784. BOOST_STATIC_STRING_CPP17_CONSTEXPR
  1785. reverse_iterator
  1786. rend() noexcept
  1787. {
  1788. return reverse_iterator{begin()};
  1789. }
  1790. /// Return a reverse iterator to the end.
  1791. BOOST_STATIC_STRING_CPP17_CONSTEXPR
  1792. const_reverse_iterator
  1793. rend() const noexcept
  1794. {
  1795. return const_reverse_iterator{cbegin()};
  1796. }
  1797. /// Return a reverse iterator to the end.
  1798. BOOST_STATIC_STRING_CPP17_CONSTEXPR
  1799. const_reverse_iterator
  1800. crend() const noexcept
  1801. {
  1802. return const_reverse_iterator{cbegin()};
  1803. }
  1804. //--------------------------------------------------------------------------
  1805. //
  1806. // Capacity
  1807. //
  1808. //--------------------------------------------------------------------------
  1809. /** Return if the string is empty.
  1810. Returns whether the string contains no characters.
  1811. @par Complexity
  1812. Constant.
  1813. @return `size() == 0`
  1814. */
  1815. BOOST_STATIC_STRING_NODISCARD
  1816. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  1817. bool
  1818. empty() const noexcept
  1819. {
  1820. return size() == 0;
  1821. }
  1822. /** Return the size of the string.
  1823. Returns the number of characters stored in the
  1824. string, excluding the null terminator.
  1825. @par Complexity
  1826. Constant.
  1827. */
  1828. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  1829. size_type
  1830. size() const noexcept
  1831. {
  1832. return this->size_impl();
  1833. }
  1834. /** Return the size of the string.
  1835. Returns the number of characters stored in the
  1836. string, excluding the null terminator.
  1837. @par Complexity
  1838. Constant.
  1839. */
  1840. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  1841. size_type
  1842. length() const noexcept
  1843. {
  1844. return size();
  1845. }
  1846. /** Return the number of characters that can be stored.
  1847. Returns the maximum size of the string, excluding the
  1848. null terminator. The returned value is always `N`.
  1849. @par Complexity
  1850. Constant.
  1851. */
  1852. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  1853. size_type
  1854. max_size() const noexcept
  1855. {
  1856. return N;
  1857. }
  1858. /** Increase the capacity.
  1859. This function has no effect.
  1860. @throw std::length_error `n > max_size()`
  1861. */
  1862. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1863. void
  1864. reserve(size_type n)
  1865. {
  1866. if (n > max_size())
  1867. detail::throw_exception<std::length_error>(
  1868. "n > max_size()");
  1869. }
  1870. /** Return the number of characters that can be stored.
  1871. Returns the maximum size of the string, excluding the
  1872. null terminator. The returned value is always `N`.
  1873. @par Complexity
  1874. Constant.
  1875. */
  1876. BOOST_STATIC_STRING_CPP11_CONSTEXPR
  1877. size_type
  1878. capacity() const noexcept
  1879. {
  1880. return max_size();
  1881. }
  1882. /** Request the removal of unused capacity.
  1883. This function has no effect.
  1884. */
  1885. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1886. void
  1887. shrink_to_fit() noexcept { }
  1888. //--------------------------------------------------------------------------
  1889. //
  1890. // Operations
  1891. //
  1892. //--------------------------------------------------------------------------
  1893. /** Clear the contents.
  1894. Erases all characters from the string. After this
  1895. call, @ref size() returns zero.
  1896. @par Complexity
  1897. Linear in @ref size().
  1898. @note All references, pointers, or iterators
  1899. referring to contained elements are invalidated. Any
  1900. past-the-end iterators are also invalidated.
  1901. */
  1902. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1903. void
  1904. clear() noexcept
  1905. {
  1906. this->set_size(0);
  1907. term();
  1908. }
  1909. /** Insert into the string.
  1910. Inserts `count` copies of `ch` at the position `index`.
  1911. @par Exception Safety
  1912. Strong guarantee.
  1913. @note All references, pointers, or iterators
  1914. referring to contained elements are invalidated. Any
  1915. past-the-end iterators are also invalidated.
  1916. @return `*this`
  1917. @param index The index to insert at.
  1918. @param count The number of characters to insert.
  1919. @param ch The character to insert.
  1920. @throw std::length_error `size() + count > max_size()`
  1921. @throw std::out_of_range `index > size()`
  1922. */
  1923. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1924. basic_static_string&
  1925. insert(
  1926. size_type index,
  1927. size_type count,
  1928. value_type ch)
  1929. {
  1930. if (index > size())
  1931. detail::throw_exception<std::out_of_range>(
  1932. "index > size()");
  1933. insert(begin() + index, count, ch);
  1934. return *this;
  1935. }
  1936. /** Insert into the string.
  1937. Inserts the null-terminated character string pointed to by `s`
  1938. of length `count` at the position `index` where `count`
  1939. is `traits_type::length(s)`.
  1940. @par Exception Safety
  1941. Strong guarantee.
  1942. @note All references, pointers, or iterators
  1943. referring to contained elements are invalidated. Any
  1944. past-the-end iterators are also invalidated.
  1945. @return `*this`
  1946. @param index The index to insert at.
  1947. @param s The string to insert.
  1948. @throw std::length_error `size() + count > max_size()`
  1949. @throw std::out_of_range `index > size()`
  1950. */
  1951. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1952. basic_static_string&
  1953. insert(
  1954. size_type index,
  1955. const_pointer s)
  1956. {
  1957. return insert(index, s, traits_type::length(s));
  1958. }
  1959. /** Insert into the string.
  1960. Inserts `count` characters of the string pointed to by `s`
  1961. at the position `index`.
  1962. @par Exception Safety
  1963. Strong guarantee.
  1964. @note All references, pointers, or iterators
  1965. referring to contained elements are invalidated. Any
  1966. past-the-end iterators are also invalidated.
  1967. @return `*this`
  1968. @param index The index to insert at.
  1969. @param s The string to insert.
  1970. @param count The length of the string to insert.
  1971. @throw std::length_error `size() + count > max_size()`
  1972. @throw std::out_of_range `index > size()`
  1973. */
  1974. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  1975. basic_static_string&
  1976. insert(
  1977. size_type index,
  1978. const_pointer s,
  1979. size_type count)
  1980. {
  1981. if (index > size())
  1982. detail::throw_exception<std::out_of_range>(
  1983. "index > size()");
  1984. insert(data() + index, s, s + count);
  1985. return *this;
  1986. }
  1987. /** Insert into the string.
  1988. Inserts the string `str`
  1989. at the position `index`.
  1990. @par Exception Safety
  1991. Strong guarantee.
  1992. @note The insertion is done unchecked when
  1993. the capacity of `str` differs from that of the
  1994. string the function is called on.
  1995. @note All references, pointers, or iterators
  1996. referring to contained elements are invalidated. Any
  1997. past-the-end iterators are also invalidated.
  1998. @tparam M The size of the input string.
  1999. @return `*this`
  2000. @param index The index to insert at.
  2001. @param str The string to insert.
  2002. @throw std::length_error `size() + str.size() > max_size()`
  2003. @throw std::out_of_range `index > size()`
  2004. */
  2005. template<std::size_t M>
  2006. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2007. basic_static_string&
  2008. insert(
  2009. size_type index,
  2010. const basic_static_string<M, CharT, Traits>& str)
  2011. {
  2012. return insert_unchecked(index, str.data(), str.size());
  2013. }
  2014. #ifndef BOOST_STATIC_STRING_DOCS
  2015. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2016. basic_static_string&
  2017. insert(
  2018. size_type index,
  2019. const basic_static_string& str)
  2020. {
  2021. return insert(index, str.data(), str.size());
  2022. }
  2023. #endif
  2024. /** Insert into the string.
  2025. Inserts a string, obtained by `str.substr(index_str, count)`
  2026. at the position `index`.
  2027. @par Exception Safety
  2028. Strong guarantee.
  2029. @note The insertion is done unchecked when
  2030. the capacity of `str` differs from that of the
  2031. string the function is called on.
  2032. @note All references, pointers, or iterators
  2033. referring to contained elements are invalidated. Any
  2034. past-the-end iterators are also invalidated.
  2035. @tparam M The size of the input string.
  2036. @return `*this`
  2037. @param index The index to insert at.
  2038. @param str The string from which to insert.
  2039. @param index_str The index in `str` to start inserting from.
  2040. @param count The number of characters to insert.
  2041. The default argument for this parameter is @ref npos.
  2042. @throw std::length_error `size() + str.substr(index_str, count).size() > max_size()`
  2043. @throw std::out_of_range `index > size()`
  2044. @throw std::out_of_range `index_str > str.size()`
  2045. */
  2046. template<std::size_t M>
  2047. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2048. basic_static_string&
  2049. insert(
  2050. size_type index,
  2051. const basic_static_string<M, CharT, Traits>& str,
  2052. size_type index_str,
  2053. size_type count = npos)
  2054. {
  2055. return insert_unchecked(index, str.data() + index_str, str.capped_length(index_str, count));
  2056. }
  2057. #ifndef BOOST_STATIC_STRING_DOCS
  2058. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2059. basic_static_string&
  2060. insert(
  2061. size_type index,
  2062. const basic_static_string& str,
  2063. size_type index_str,
  2064. size_type count = npos)
  2065. {
  2066. return insert(index, str.data() + index_str, str.capped_length(index_str, count));
  2067. }
  2068. #endif
  2069. /** Insert into the string.
  2070. Inserts the character `ch` before the character pointed by `pos`.
  2071. @par Precondition
  2072. `pos` shall be vaild within `{data(), data() + size()}`
  2073. @par Exception Safety
  2074. Strong guarantee.
  2075. @note All references, pointers, or iterators
  2076. referring to contained elements are invalidated. Any
  2077. past-the-end iterators are also invalidated.
  2078. @return An iterator which refers to the first inserted character
  2079. or `pos` if no characters were inserted
  2080. @param pos The index to insert at.
  2081. @param ch The character to insert.
  2082. @throw std::length_error `size() + 1 > max_size()`
  2083. */
  2084. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2085. iterator
  2086. insert(
  2087. const_iterator pos,
  2088. value_type ch)
  2089. {
  2090. return insert(pos, 1, ch);
  2091. }
  2092. /** Insert into the string.
  2093. Inserts `count` copies of `ch` before the character pointed by `pos`.
  2094. @par Precondition
  2095. `pos` shall be valid within `{data(), data() + size()}`
  2096. @par Exception Safety
  2097. Strong guarantee.
  2098. @note All references, pointers, or iterators
  2099. referring to contained elements are invalidated. Any
  2100. past-the-end iterators are also invalidated.
  2101. @return An iterator which refers to the first inserted character
  2102. or `pos` if no characters were inserted
  2103. @param pos The position to insert at.
  2104. @param count The number of characters to insert.
  2105. @param ch The character to insert.
  2106. @throw std::length_error `size() + count > max_size()`
  2107. */
  2108. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2109. iterator
  2110. insert(
  2111. const_iterator pos,
  2112. size_type count,
  2113. value_type ch);
  2114. /** Insert into the string.
  2115. Inserts characters from the range `{first, last)` before the
  2116. character pointed to by `pos`.
  2117. @par Precondition
  2118. `pos` shall be valid within `{data(), data() + size()}`,
  2119. `{first, last)` shall be a valid range
  2120. @par Exception Safety
  2121. Strong guarantee.
  2122. @note All references, pointers, or iterators
  2123. referring to contained elements are invalidated. Any
  2124. past-the-end iterators are also invalidated.
  2125. @tparam InputIterator The type of the iterators.
  2126. @par Constraints
  2127. `InputIterator` satisfies __InputIterator__ and does not
  2128. satisfy __ForwardIterator__.
  2129. @return An iterator which refers to the first inserted character
  2130. or `pos` if no characters were inserted
  2131. @param pos The position to insert at.
  2132. @param first An iterator representing the first character to insert.
  2133. @param last An iterator representing one past the last character to insert.
  2134. @throw std::length_error `size() + insert_count > max_size()`
  2135. */
  2136. template<typename InputIterator>
  2137. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2138. #ifdef BOOST_STATIC_STRING_DOCS
  2139. iterator
  2140. #else
  2141. typename std::enable_if<
  2142. detail::is_input_iterator<
  2143. InputIterator>::value &&
  2144. !detail::is_forward_iterator<
  2145. InputIterator>::value, iterator>::type
  2146. #endif
  2147. insert(
  2148. const_iterator pos,
  2149. InputIterator first,
  2150. InputIterator last);
  2151. #ifndef BOOST_STATIC_STRING_DOCS
  2152. template<typename ForwardIterator>
  2153. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2154. typename std::enable_if<
  2155. detail::is_forward_iterator<
  2156. ForwardIterator>::value,
  2157. iterator>::type
  2158. insert(
  2159. const_iterator pos,
  2160. ForwardIterator first,
  2161. ForwardIterator last);
  2162. #endif
  2163. /** Insert into the string.
  2164. Inserts characters from `ilist` before `pos`.
  2165. @par Precondition
  2166. `pos` shall be valid within `{data(), data() + size()}`
  2167. @par Exception Safety
  2168. Strong guarantee.
  2169. @note All references, pointers, or iterators
  2170. referring to contained elements are invalidated. Any
  2171. past-the-end iterators are also invalidated.
  2172. @return An iterator which refers to the first inserted character
  2173. or `pos` if no characters were inserted
  2174. @param pos The position to insert at.
  2175. @param ilist The initializer list from which to insert.
  2176. @throw std::length_error `size() + ilist.size() > max_size()`
  2177. */
  2178. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2179. iterator
  2180. insert(
  2181. const_iterator pos,
  2182. std::initializer_list<value_type> ilist)
  2183. {
  2184. return insert_unchecked(pos, ilist.begin(), ilist.size());
  2185. }
  2186. /** Insert into the string.
  2187. Constructs a temporary `string_view_type` object `sv` from `t` and
  2188. inserts `{sv.begin(), sv.end())` at `index`.
  2189. @par Precondition
  2190. `index` shall be valid within `{data(), data() + size()}`
  2191. @par Exception Safety
  2192. Strong guarantee.
  2193. @note All references, pointers, or iterators
  2194. referring to contained elements are invalidated. Any
  2195. past-the-end iterators are also invalidated.
  2196. @return `*this`
  2197. @tparam T The type of the object to convert.
  2198. @par Constraints
  2199. `std::is_convertible<const T&, string_view>::value &&
  2200. !std::is_convertible<const T&, const CharT*>::value &&
  2201. !std::is_convertible<const T&, const basic_static_string&>::value`.
  2202. @param index The index to insert at.
  2203. @param t The string to insert from.
  2204. @throw std::length_error `size() + sv.size() > max_size()`
  2205. @throw std::out_of_range `index > size()`
  2206. */
  2207. template<typename T
  2208. #ifndef BOOST_STATIC_STRING_DOCS
  2209. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  2210. #endif
  2211. >
  2212. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2213. basic_static_string&
  2214. insert(
  2215. size_type index,
  2216. const T& t)
  2217. {
  2218. detail::common_string_view_type<T, CharT, Traits> sv = t;
  2219. return insert(index, sv.data(), sv.size());
  2220. }
  2221. /** Insert into the string.
  2222. Constructs a temporary `string_view_type` object `sv` from `t`
  2223. and inserts `sv.substr(index_str, count)` at `index`.
  2224. @par Exception Safety
  2225. Strong guarantee.
  2226. @note All references, pointers, or iterators
  2227. referring to contained elements are invalidated. Any
  2228. past-the-end iterators are also invalidated.
  2229. @tparam T The type of the object to convert.
  2230. @par Constraints
  2231. `std::is_convertible<const T&, string_view>::value &&
  2232. !std::is_convertible<const T&, const_pointer>::value &&
  2233. !std::is_convertible<const T&, const basic_static_string&>::value`.
  2234. @return `*this`
  2235. @param index The index to insert at.
  2236. @param t The string to insert from.
  2237. @param index_str The index in the temporary `string_view_type` object
  2238. to start the substring from.
  2239. @param count The number of characters to insert.
  2240. @throw std::length_error `size() + sv.size() > max_size()`
  2241. @throw std::out_of_range `index > size()`
  2242. @throw std::out_of_range `index_str > sv.size()`
  2243. */
  2244. template<typename T
  2245. #ifndef BOOST_STATIC_STRING_DOCS
  2246. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  2247. #endif
  2248. >
  2249. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2250. basic_static_string&
  2251. insert(
  2252. size_type index,
  2253. const T& t,
  2254. size_type index_str,
  2255. size_type count = npos)
  2256. {
  2257. detail::common_string_view_type<T, CharT, Traits> sv(t);
  2258. if ( index_str > sv.size() )
  2259. detail::throw_exception<std::out_of_range>("index_str > t.size()");
  2260. return insert(index, sv.data() + index_str, (std::min)(sv.size() - index_str, count));
  2261. }
  2262. /** Erase from the string.
  2263. Erases `num` characters from the string, starting at `index`.
  2264. `num` is determined as the smaller of `count` and `size() - index`.
  2265. @par Exception Safety
  2266. Strong guarantee.
  2267. @note All references, pointers, or iterators
  2268. referring to contained elements are invalidated. Any
  2269. past-the-end iterators are also invalidated.
  2270. @return `*this`
  2271. @param index The index to erase at.
  2272. The default argument for this parameter is `0`.
  2273. @param count The number of characters to erase.
  2274. The default argument for this parameter is @ref npos.
  2275. @throw std::out_of_range `index > size()`
  2276. */
  2277. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2278. basic_static_string&
  2279. erase(
  2280. size_type index = 0,
  2281. size_type count = npos)
  2282. {
  2283. erase(data() + index, data() + index + capped_length(index, count));
  2284. return *this;
  2285. }
  2286. /** Erase from the string.
  2287. Erases the character at `pos`.
  2288. @par Preconditions
  2289. `pos` shall be valid within `{data(), data() + size()}`
  2290. @par Exception Safety
  2291. Strong guarantee.
  2292. @note All references, pointers, or iterators
  2293. referring to contained elements are invalidated. Any
  2294. past-the-end iterators are also invalidated.
  2295. @return An iterator referring to character immediately following
  2296. the erased character, or @ref end() if one does not exist.
  2297. @param pos An iterator referring to the character to erase.
  2298. */
  2299. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2300. iterator
  2301. erase(const_iterator pos)
  2302. {
  2303. BOOST_STATIC_STRING_ASSERT(!empty());
  2304. return erase(pos, pos + 1);
  2305. }
  2306. /** Erase from the string.
  2307. Erases the characters in the range `{first, last)`.
  2308. @par Precondition
  2309. `{first, last}` shall be valid within `{data(), data() + size()}`
  2310. @par Exception Safety
  2311. Strong guarantee.
  2312. @note All references, pointers, or iterators
  2313. referring to contained elements are invalidated. Any
  2314. past-the-end iterators are also invalidated.
  2315. @return An iterator referring to the character `last`
  2316. previously referred to, or @ref end() if one does not exist.
  2317. @param first An iterator referring to the first character to erase.
  2318. @param last An iterator past the last character to erase.
  2319. */
  2320. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2321. iterator
  2322. erase(
  2323. const_iterator first,
  2324. const_iterator last);
  2325. /** Append a character.
  2326. Appends a character to the end of the string.
  2327. @par Exception Safety
  2328. Strong guarantee.
  2329. @param ch The character to append.
  2330. @throw std::length_error `size() >= max_size()`
  2331. */
  2332. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2333. void
  2334. push_back(value_type ch);
  2335. /** Remove the last character.
  2336. Removes a character from the end of the string.
  2337. @par Precondition
  2338. `not empty()`
  2339. */
  2340. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2341. void
  2342. pop_back() noexcept
  2343. {
  2344. BOOST_STATIC_STRING_ASSERT(!empty());
  2345. this->set_size(size() - 1);
  2346. term();
  2347. }
  2348. /** Append to the string.
  2349. Appends `count` copies of `ch` to the end of the string.
  2350. @par Exception Safety
  2351. Strong guarantee.
  2352. @return `*this`
  2353. @param count The number of characters to append.
  2354. @param ch The character to append.
  2355. @throw std::length_error `size() + count > max_size()`
  2356. */
  2357. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2358. basic_static_string&
  2359. append(
  2360. size_type count,
  2361. value_type ch);
  2362. /** Append to the string.
  2363. Appends `s` to the end of the string.
  2364. @par Exception Safety
  2365. Strong guarantee.
  2366. @tparam M The size of the string to append.
  2367. @return `*this`
  2368. @param s The string to append.
  2369. @throw std::length_error `size() + s.size() > max_size()`
  2370. */
  2371. template<std::size_t M>
  2372. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2373. basic_static_string&
  2374. append(
  2375. const basic_static_string<M, CharT, Traits>& s)
  2376. {
  2377. return append(s.data(), s.size());
  2378. }
  2379. /** Append to the string.
  2380. Appends the substring `sub` to the end of the string,
  2381. where `sub` is `s.substr(pos, count)`.
  2382. @par Exception Safety
  2383. Strong guarantee.
  2384. @tparam M The size of the string to append.
  2385. @return `*this`
  2386. @param s The string to append.
  2387. @param pos The index at which to begin the substring.
  2388. @param count The size of the substring. The default
  2389. argument for this parameter is @ref npos.
  2390. @throw std::length_error `size() + sub.size() > max_size()`
  2391. @throw std::out_of_range `pos > s.size()`
  2392. */
  2393. template<std::size_t M>
  2394. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2395. basic_static_string&
  2396. append(
  2397. const basic_static_string<M, CharT, Traits>& s,
  2398. size_type pos,
  2399. size_type count = npos)
  2400. {
  2401. return append(s.data() + pos, s.capped_length(pos, count));
  2402. }
  2403. /** Append to the string.
  2404. Appends `count` characters from the string pointed
  2405. to by `s` to the end of the string.
  2406. @par Exception Safety
  2407. Strong guarantee.
  2408. @note The string can contain null characters.
  2409. @return `*this`
  2410. @param s The string to append.
  2411. @param count The number of characters to append.
  2412. @throw std::length_error `size() + count > max_size()`
  2413. */
  2414. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2415. basic_static_string&
  2416. append(
  2417. const_pointer s,
  2418. size_type count);
  2419. /** Append to the string.
  2420. Appends `count` characters from the string pointed
  2421. to by `s` to the end of the string, where `count`
  2422. is `traits_type::length(s)`.
  2423. @par Exception Safety
  2424. Strong guarantee.
  2425. @return `*this`
  2426. @param s The string to append.
  2427. @throw std::length_error `size() + count > max_size()`
  2428. */
  2429. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2430. basic_static_string&
  2431. append(const_pointer s)
  2432. {
  2433. return append(s, traits_type::length(s));
  2434. }
  2435. // KRYSTIAN TODO: change exception safety
  2436. /** Append to the string.
  2437. Appends characters from the range `{first, last)`
  2438. to the end of the string.
  2439. @par Precondition
  2440. `{first, last)` shall be a valid range
  2441. @par Exception Safety
  2442. Strong guarantee.
  2443. @tparam InputIterator The type of the iterators.
  2444. @par Constraints
  2445. `InputIterator` satisfies __InputIterator__.
  2446. @return `*this`
  2447. @param first An iterator referring to the
  2448. first character to append.
  2449. @param last An iterator past the end of
  2450. last character to append.
  2451. @throw std::length_error `size() + std::distance(first, last) > max_size()`
  2452. */
  2453. template<typename InputIterator>
  2454. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2455. #ifdef BOOST_STATIC_STRING_DOCS
  2456. basic_static_string&
  2457. #else
  2458. typename std::enable_if<
  2459. detail::is_input_iterator<InputIterator>::value,
  2460. basic_static_string&>::type
  2461. #endif
  2462. append(
  2463. InputIterator first,
  2464. InputIterator last)
  2465. {
  2466. this->set_size(size() + read_back(true, first, last));
  2467. return term();
  2468. }
  2469. /** Append to the string.
  2470. Appends the characters from `ilist` to the
  2471. end of the string.
  2472. @par Exception Safety
  2473. Strong guarantee.
  2474. @return `*this`
  2475. @param ilist The initializer list to append.
  2476. @throw std::length_error `size() + ilist.size() > max_size()`
  2477. */
  2478. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2479. basic_static_string&
  2480. append(
  2481. std::initializer_list<value_type> ilist)
  2482. {
  2483. return append(ilist.begin(), ilist.size());
  2484. }
  2485. /** Append to the string.
  2486. Appends `sv` to the end of the string,
  2487. where `sv` is `string_view_type(t)`.
  2488. @par Exception Safety
  2489. Strong guarantee.
  2490. @tparam T The type of the object to convert.
  2491. @par Constraints
  2492. @code
  2493. std::is_convertible<T const&, string_view>::value &&
  2494. !std::is_convertible<T const&, char const*>::value &&
  2495. !std::is_convertible<const T&, const basic_static_string&>::value
  2496. @endcode
  2497. @return `*this`
  2498. @param t The string to append.
  2499. @throw std::length_error `size() + sv.size() > max_size()`
  2500. */
  2501. template<typename T
  2502. #ifndef BOOST_STATIC_STRING_DOCS
  2503. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  2504. #endif
  2505. >
  2506. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2507. basic_static_string&
  2508. append(const T& t)
  2509. {
  2510. detail::common_string_view_type<T, CharT, Traits> sv = t;
  2511. return append(sv.data(), sv.size());
  2512. }
  2513. /** Append to the string.
  2514. Appends the substring `sv` to the end of the string,
  2515. where `sv` is `string_view_type(t).substr(pos, count)`.
  2516. @par Exception Safety
  2517. Strong guarantee.
  2518. @tparam T The type of the object to convert.
  2519. @par Constraints
  2520. @code
  2521. std::is_convertible<T const&, string_view>::value &&
  2522. !std::is_convertible<T const&, char const*>::value &&
  2523. !std::is_convertible<const T&, const basic_static_string&>::value
  2524. @endcode
  2525. @return `*this`
  2526. @param t The object to append.
  2527. @param pos The index at which to begin the substring.
  2528. @param count The size of the substring. The default
  2529. argument for this parameter is @ref npos.
  2530. @throw std::length_error `size() + sv.size() > max_size()`
  2531. */
  2532. template<typename T
  2533. #ifndef BOOST_STATIC_STRING_DOCS
  2534. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  2535. #endif
  2536. >
  2537. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2538. basic_static_string&
  2539. append(
  2540. const T& t,
  2541. size_type pos,
  2542. size_type count = npos)
  2543. {
  2544. detail::common_string_view_type<T, CharT, Traits> sv = t;
  2545. if ( pos > sv.size() )
  2546. detail::throw_exception<std::out_of_range>("pos > t.size()");
  2547. return append(sv.data() + pos, (std::min)(sv.size() - pos, count));
  2548. }
  2549. /** Append to the string.
  2550. Appends `s` to the end of the string.
  2551. @par Exception Safety
  2552. Strong guarantee.
  2553. @tparam M The size of the string to append.
  2554. @return `*this`
  2555. @param s The string to append.
  2556. @throw std::length_error `size() + s.size() > max_size()`
  2557. */
  2558. template<std::size_t M>
  2559. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2560. basic_static_string&
  2561. operator+=(
  2562. const basic_static_string<M, CharT, Traits>& s)
  2563. {
  2564. return append(s);
  2565. }
  2566. /** Append to the string.
  2567. Appends a character to the end of the string.
  2568. @par Exception Safety
  2569. Strong guarantee.
  2570. @param ch The character to append.
  2571. @throw std::length_error `size() >= max_size()`
  2572. */
  2573. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2574. basic_static_string&
  2575. operator+=(value_type ch)
  2576. {
  2577. push_back(ch);
  2578. return *this;
  2579. }
  2580. /** Append to the string.
  2581. Appends `count` characters from the string pointed
  2582. to by `s` to the end of the string, where `count`
  2583. is `traits_type::length(s)`.
  2584. @par Exception Safety
  2585. Strong guarantee.
  2586. @return `*this`
  2587. @param s The string to append.
  2588. @throw std::length_error `size() + count > max_size()`
  2589. */
  2590. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2591. basic_static_string&
  2592. operator+=(const_pointer s)
  2593. {
  2594. return append(s);
  2595. }
  2596. /** Append to the string.
  2597. Appends the characters from `ilist` to the
  2598. end of the string.
  2599. @par Exception Safety
  2600. Strong guarantee.
  2601. @return `*this`
  2602. @param ilist The initializer list to append.
  2603. @throw std::length_error `size() + ilist.size() > max_size()`
  2604. */
  2605. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2606. basic_static_string&
  2607. operator+=(
  2608. std::initializer_list<value_type> ilist)
  2609. {
  2610. return append(ilist);
  2611. }
  2612. /** Append to the string.
  2613. Appends `sv` to the end of the string,
  2614. where `sv` is `string_view_type(t)`.
  2615. @par Exception Safety
  2616. Strong guarantee.
  2617. @tparam T The type of the object to convert.
  2618. @par Constraints
  2619. @code
  2620. std::is_convertible<T const&, string_view>::value &&
  2621. !std::is_convertible<T const&, char const*>::value &&
  2622. !std::is_convertible<const T&, const basic_static_string&>::value
  2623. @endcode
  2624. @return `*this`
  2625. @param t The string to append.
  2626. @throw std::length_error `size() + sv.size() > max_size()`
  2627. */
  2628. template<typename T
  2629. #ifndef BOOST_STATIC_STRING_DOCS
  2630. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  2631. #endif
  2632. >
  2633. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2634. basic_static_string&
  2635. operator+=(const T& t)
  2636. {
  2637. return append(t);
  2638. }
  2639. /** Compare a string with the string.
  2640. Let `comp` be `traits_type::compare(data(), s.data(), std::min(size(), s.size())`.
  2641. If `comp != 0`, then the result is `comp`. Otherwise, the result is
  2642. `0` if `size() == s.size()`, `-1` if `size() < s.size()`, and `1`
  2643. otherwise.
  2644. @par Complexity
  2645. Linear.
  2646. @return The result of lexicographically comparing `s` and the string.
  2647. @tparam M The size of the string to compare with.
  2648. @param s The string to compare.
  2649. */
  2650. template<std::size_t M>
  2651. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2652. int
  2653. compare(
  2654. const basic_static_string<M, CharT, Traits>& s) const noexcept
  2655. {
  2656. return detail::lexicographical_compare<CharT, Traits>(
  2657. data(), size(), s.data(), s.size());
  2658. }
  2659. /** Compare a string with the string.
  2660. Let `sub` be `substr(pos1, count1)` and `comp` be
  2661. `traits_type::compare(sub.data(), s.data(), std::min(sub.size(), s.size())`.
  2662. If `comp != 0`, then the result is `comp`. Otherwise, the result is
  2663. `0` if `sub.size() == s.size()`, `-1` if `sub.size() < s.size()`, and `1`
  2664. otherwise.
  2665. @par Complexity
  2666. Linear.
  2667. @par Exception Safety
  2668. Strong guarantee.
  2669. @return The result of lexicographically comparing `sub` and `s`.
  2670. @tparam M The size of the string to compare with.
  2671. @param pos1 The index at which to begin the substring.
  2672. @param count1 The size of the substring.
  2673. @param s The string to compare.
  2674. @throw std::out_of_range `pos1 > size()`
  2675. */
  2676. template<std::size_t M>
  2677. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2678. int
  2679. compare(
  2680. size_type pos1,
  2681. size_type count1,
  2682. const basic_static_string<M, CharT, Traits>& s) const
  2683. {
  2684. return detail::lexicographical_compare<CharT, Traits>(
  2685. data() + pos1, capped_length(pos1, count1), s.data(), s.size());
  2686. }
  2687. /** Compare a string with the string.
  2688. Let `sub1` be `substr(pos1, count1)`, `sub2` be
  2689. `s.substr(pos2, count2)`, and `comp` be
  2690. `traits_type::compare(sub1.data(), sub2.data(), std::min(sub1.size(), sub2.size())`.
  2691. If `comp != 0`, then the result is `comp`. Otherwise, the result is
  2692. `0` if `sub1.size() == sub2.size()`, `-1` if `sub1.size() < sub2.size()`, and `1`
  2693. otherwise.
  2694. @par Complexity
  2695. Linear.
  2696. @par Exception Safety
  2697. Strong guarantee.
  2698. @return The result of lexicographically comparing `sub1` and `sub2`.
  2699. @param pos1 The index at which to begin the substring.
  2700. @param count1 The size of the substring.
  2701. @param s The string to compare.
  2702. @param pos2 The index at which to begin the substring to compare.
  2703. @param count2 The size of the substring to compare.
  2704. @throw std::out_of_range `pos1 > size()`
  2705. @throw std::out_of_range `pos2 > s.size()`
  2706. */
  2707. template<std::size_t M>
  2708. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2709. int
  2710. compare(
  2711. size_type pos1,
  2712. size_type count1,
  2713. const basic_static_string<M, CharT, Traits>& s,
  2714. size_type pos2,
  2715. size_type count2 = npos) const
  2716. {
  2717. return detail::lexicographical_compare<CharT, Traits>(
  2718. data() + pos1, capped_length(pos1, count1),
  2719. s.data() + pos2, s.capped_length(pos2, count2));
  2720. }
  2721. /** Compare a string with the string.
  2722. Let `len` be `traits_type::length(s)` and `comp` be
  2723. `traits_type::compare(data(), s, std::min(size(), len)`.
  2724. If `comp != 0`, then the result is `comp`. Otherwise, the result is
  2725. `0` if `size() == len`, `-1` if `size() < len`, and `1`
  2726. otherwise.
  2727. @par Complexity
  2728. Linear.
  2729. @return The result of lexicographically comparing `s` and the string.
  2730. @param s The string to compare.
  2731. */
  2732. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2733. int
  2734. compare(const_pointer s) const noexcept
  2735. {
  2736. return detail::lexicographical_compare<CharT, Traits>(
  2737. data(), size(), s, traits_type::length(s));
  2738. }
  2739. /** Compare a string with the string.
  2740. Let `sub` be `substr(pos1, count1)`, `len` be
  2741. `traits_type::length(s)`, and `comp` be
  2742. `traits_type::compare(sub.data(), s, std::min(size(), len)`.
  2743. If `comp != 0`, then the result is `comp`. Otherwise, the result is
  2744. `0` if `sub.size() == len`, `-1` if `sub.size() < len`, and `1`
  2745. otherwise.
  2746. @par Complexity
  2747. Linear.
  2748. @par Exception Safety
  2749. Strong guarantee.
  2750. @return The result of lexicographically comparing `s` and `sub`.
  2751. @param pos1 The index at which to begin the substring.
  2752. @param count1 The size of the substring.
  2753. @param s The string to compare.
  2754. @throw std::out_of_range `pos1 > size()`
  2755. */
  2756. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2757. int
  2758. compare(
  2759. size_type pos1,
  2760. size_type count1,
  2761. const_pointer s) const
  2762. {
  2763. return detail::lexicographical_compare<CharT, Traits>(
  2764. data() + pos1, capped_length(pos1, count1), s, traits_type::length(s));
  2765. }
  2766. /** Compare a string with the string.
  2767. Let `sub` be `substr(pos1, count1)`, and `comp` be
  2768. `traits_type::compare(sub.data(), s, std::min(size(), count2)`.
  2769. If `comp != 0`, then the result is `comp`. Otherwise, the result is
  2770. `0` if `sub.size() == count2`, `-1` if `sub.size() < count2`, and `1`
  2771. otherwise.
  2772. @par Complexity
  2773. Linear.
  2774. @par Exception Safety
  2775. Strong guarantee.
  2776. @return The result of lexicographically comparing `s` and `sub`.
  2777. @param pos1 The index at which to begin the substring.
  2778. @param count1 The size of the substring.
  2779. @param s The string to compare.
  2780. @param count2 The length of the string to compare.
  2781. @throw std::out_of_range `pos1 > size()`
  2782. */
  2783. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2784. int
  2785. compare(
  2786. size_type pos1,
  2787. size_type count1,
  2788. const_pointer s,
  2789. size_type count2) const
  2790. {
  2791. return detail::lexicographical_compare<CharT, Traits>(
  2792. data() + pos1, capped_length(pos1, count1), s, count2);
  2793. }
  2794. /** Compare a string with the string.
  2795. Let `s` be `string_view_type(t)` and `comp` be
  2796. `traits_type::compare(data(), s.data(), std::min(size(), s.size())`.
  2797. If `comp != 0`, then the result is `comp`. Otherwise, the result is
  2798. `0` if `size() == s.size()`, `-1` if `size() < s.size()`, and `1`
  2799. otherwise.
  2800. @par Complexity
  2801. Linear.
  2802. @par Exception Safety
  2803. Strong guarantee.
  2804. @tparam T The type of the object to convert.
  2805. @par Constraints
  2806. @code
  2807. std::is_convertible<const T&, string_view>::value &&
  2808. !std::is_convertible<const T&, const_pointer>::value &&
  2809. !std::is_convertible<const T&, const basic_static_string&>::value.
  2810. @endcode
  2811. @return The result of lexicographically comparing `s` and the string.
  2812. @param t The string to compare.
  2813. */
  2814. template<typename T
  2815. #ifndef BOOST_STATIC_STRING_DOCS
  2816. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  2817. #endif
  2818. >
  2819. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2820. int
  2821. compare(const T& t) const noexcept
  2822. {
  2823. detail::common_string_view_type<T, CharT, Traits> sv = t;
  2824. return detail::lexicographical_compare<CharT, Traits>(
  2825. data(), size(), sv.data(), sv.size());
  2826. }
  2827. /** Compare a string with the string.
  2828. Let `s` be `string_view_type(t)`, `sub` be
  2829. `substr(pos1, count1)`, and `comp` be
  2830. `traits_type::compare(sub.data(), s.data(), std::min(sub.size(), s.size())`.
  2831. If `comp != 0`, then the result is `comp`. Otherwise, the result is
  2832. `0` if `sub.size() == s.size()`, `-1` if `sub.size() < s.size()`, and `1`
  2833. otherwise.
  2834. @par Complexity
  2835. Linear.
  2836. @par Exception Safety
  2837. Strong guarantee.
  2838. @tparam T The type of the object to convert.
  2839. @par Constraints
  2840. @code
  2841. std::is_convertible<const T&, string_view>::value &&
  2842. !std::is_convertible<const T&, const_pointer>::value &&
  2843. !std::is_convertible<const T&, const basic_static_string&>::value.
  2844. @endcode
  2845. @return The result of lexicographically comparing `s` and `sub`.
  2846. @param pos1 The index at which to begin the substring.
  2847. @param count1 The length of the substring.
  2848. @param t The string to compare.
  2849. */
  2850. template<typename T
  2851. #ifndef BOOST_STATIC_STRING_DOCS
  2852. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  2853. #endif
  2854. >
  2855. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2856. int
  2857. compare(
  2858. size_type pos1,
  2859. size_type count1,
  2860. const T& t) const
  2861. {
  2862. detail::common_string_view_type<T, CharT, Traits> sv = t;
  2863. return detail::lexicographical_compare<CharT, Traits>(
  2864. data() + pos1, capped_length(pos1, count1), sv.data(), sv.size());
  2865. }
  2866. /** Compare a string with the string.
  2867. Let `sub1` be `substr(pos1, count1)`, `sub2` be
  2868. `string_view_type(t).substr(pos2, count2)`, and `comp` be
  2869. `traits_type::compare(sub1.data(), sub2.data(), std::min(sub1.size(), sub2.size())`.
  2870. If `comp != 0`, then the result is `comp`. Otherwise, the result is
  2871. `0` if `sub1.size() == sub2.size()`, `-1` if `sub1.size() < sub2.size()`, and `1`
  2872. otherwise.
  2873. @par Complexity
  2874. Linear.
  2875. @par Exception Safety
  2876. Strong guarantee.
  2877. @tparam T The type of the object to convert.
  2878. @par Constraints
  2879. @code
  2880. std::is_convertible<const T&, string_view>::value &&
  2881. !std::is_convertible<const T&, const_pointer>::value &&
  2882. !std::is_convertible<const T&, const basic_static_string&>::value.
  2883. @endcode
  2884. @return The result of lexicographically comparing `sub1` and `sub2`.
  2885. @param pos1 The index at which to begin the substring in the string.
  2886. @param count1 The length of the substring in the string.
  2887. @param t The string to compare.
  2888. @param pos2 The index at which to begin the substring in the string view.
  2889. @param count2 The length of the substring in the string view.
  2890. */
  2891. template<typename T
  2892. #ifndef BOOST_STATIC_STRING_DOCS
  2893. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  2894. #endif
  2895. >
  2896. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2897. int
  2898. compare(
  2899. size_type pos1,
  2900. size_type count1,
  2901. const T& t,
  2902. size_type pos2,
  2903. size_type count2 = npos) const
  2904. {
  2905. detail::common_string_view_type<T, CharT, Traits> sv = t;
  2906. if ( pos2 > sv.size())
  2907. detail::throw_exception<std::out_of_range>("pos2 > sv.size()");
  2908. return compare(
  2909. pos1, count1, sv.data() + pos2,
  2910. (std::min)(sv.size() - pos2, count2));
  2911. }
  2912. /** Return a substring.
  2913. Returns a substring of the string.
  2914. @par Exception Safety
  2915. Strong guarantee.
  2916. @return A string object containing the characters
  2917. `{data() + pos, std::min(count, size() - pos))`.
  2918. @param pos The index to being the substring at. The
  2919. default argument for this parameter is `0`.
  2920. @param count The length of the substring. The default argument
  2921. for this parameter is @ref npos.
  2922. @throw std::out_of_range `pos > size()`
  2923. */
  2924. #ifndef BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR
  2925. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2926. #endif
  2927. basic_static_string
  2928. substr(
  2929. size_type pos = 0,
  2930. size_type count = npos) const
  2931. {
  2932. return basic_static_string(
  2933. data() + pos, capped_length(pos, count));
  2934. }
  2935. #ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
  2936. /** Return a string view of a substring.
  2937. Returns a view of a substring.
  2938. @par Exception Safety
  2939. Strong guarantee.
  2940. @return A `string_view_type` object referring
  2941. to `{data() + pos, std::min(count, size() - pos))`.
  2942. @param pos The index to being the substring at. The
  2943. default argument for this parameter is `0`.
  2944. @param count The length of the substring. The default argument
  2945. for this parameter is @ref npos.
  2946. @throw std::out_of_range `pos > size()`
  2947. */
  2948. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2949. string_view_type
  2950. subview(
  2951. size_type pos = 0,
  2952. size_type count = npos) const
  2953. {
  2954. return string_view_type(
  2955. data() + pos, capped_length(pos, count));
  2956. }
  2957. #endif
  2958. /** Copy a substring to another string.
  2959. Copies `std::min(count, size() - pos)` characters starting at
  2960. index `pos` to the string pointed to by `dest`.
  2961. @note The resulting string is not null terminated.
  2962. @return The number of characters copied.
  2963. @param count The number of characters to copy.
  2964. @param dest The string to copy to.
  2965. @param pos The index to begin copying from. The
  2966. default argument for this parameter is `0`.
  2967. @throw std::out_of_range `pos > max_size()`
  2968. */
  2969. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2970. size_type
  2971. copy(
  2972. pointer dest,
  2973. size_type count,
  2974. size_type pos = 0) const
  2975. {
  2976. const auto num_copied = capped_length(pos, count);
  2977. traits_type::copy(dest, data() + pos, num_copied);
  2978. return num_copied;
  2979. }
  2980. /** Change the size of the string.
  2981. Resizes the string to contain `n` characters. If
  2982. `n > size()`, characters with the value `CharT()` are
  2983. appended. Otherwise, `size()` is reduced to `n`.
  2984. @param n The size to resize the string to.
  2985. @throw std::out_of_range `n > max_size()`
  2986. */
  2987. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  2988. void
  2989. resize(size_type n)
  2990. {
  2991. resize(n, value_type());
  2992. }
  2993. /** Change the size of the string.
  2994. Resizes the string to contain `n` characters. If
  2995. `n > size()`, copies of `c` are
  2996. appended. Otherwise, `size()` is reduced to `n`.
  2997. @param n The size to resize the string to.
  2998. @param c The characters to append if the size
  2999. increases.
  3000. @throw std::out_of_range `n > max_size()`
  3001. */
  3002. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3003. void
  3004. resize(
  3005. size_type n,
  3006. value_type c);
  3007. /**
  3008. Resize the string and overwrite its contents.
  3009. Resizes the string to contain `n` characters, and uses the
  3010. provided function object `op` to overwrite the string contents.
  3011. The function object is called with two arguments: a pointer to
  3012. the string internal buffer, and the size of the string. The
  3013. function object shall return the number of characters written to
  3014. the buffer, which shall be less than or equal to `n`. The string
  3015. size is set to the value returned by the function object.
  3016. @par Exception Safety
  3017. Strong guarantee. However, if an exception is thrown by
  3018. `std::move(op)(p, count)`, the behavior is undefined.
  3019. @throw std::length_error `n > max_size()`
  3020. */
  3021. template<typename Operation>
  3022. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3023. void
  3024. resize_and_overwrite(
  3025. size_type n,
  3026. Operation op);
  3027. /** Swap two strings.
  3028. Swaps the contents of the string and `s`.
  3029. @par Exception Safety
  3030. Strong guarantee.
  3031. @note
  3032. All references, pointers, or iterators
  3033. referring to contained elements are invalidated. Any
  3034. past-the-end iterators are also invalidated.
  3035. @param s The string to swap with.
  3036. */
  3037. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3038. void
  3039. swap(basic_static_string& s) noexcept;
  3040. /** Swap two strings.
  3041. Swaps the contents of the string and `s`.
  3042. @par Exception Safety
  3043. Strong guarantee.
  3044. @note
  3045. All references, pointers, or iterators
  3046. referring to contained elements are invalidated. Any
  3047. past-the-end iterators are also invalidated.
  3048. @tparam M The size of the string to swap with.
  3049. @param s The string to swap with.
  3050. @throw std::length_error `s.size() > max_size() || size() > s.max_size()`
  3051. */
  3052. template<std::size_t M>
  3053. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3054. void
  3055. swap(basic_static_string<M, CharT, Traits>& s);
  3056. /** Replace a part of the string.
  3057. Replaces `rcount` characters starting at index `pos1` with those
  3058. of `str`, where `rcount` is `std::min(n1, size() - pos1)`.
  3059. @par Exception Safety
  3060. Strong guarantee.
  3061. @note The replacement is done unchecked when
  3062. the capacity of `str` differs from that of the
  3063. string the function is called on.
  3064. All references, pointers, or iterators
  3065. referring to contained elements are invalidated. Any
  3066. past-the-end iterators are also invalidated.
  3067. @tparam M The size of the input string.
  3068. @return `*this`
  3069. @param pos1 The index to replace at.
  3070. @param n1 The number of characters to replace.
  3071. @param str The string to replace with.
  3072. @throw std::length_error `size() + (str.size() - rcount) > max_size()`
  3073. @throw std::out_of_range `pos1 > size()`
  3074. */
  3075. template<size_t M>
  3076. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3077. basic_static_string&
  3078. replace(
  3079. size_type pos1,
  3080. size_type n1,
  3081. const basic_static_string<M, CharT, Traits>& str)
  3082. {
  3083. return replace_unchecked(pos1, n1, str.data(), str.size());
  3084. }
  3085. #ifndef BOOST_STATIC_STRING_DOCS
  3086. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3087. basic_static_string&
  3088. replace(
  3089. size_type pos1,
  3090. size_type n1,
  3091. const basic_static_string& str)
  3092. {
  3093. return replace(pos1, n1, str.data(), str.size());
  3094. }
  3095. #endif
  3096. /** Replace a part of the string.
  3097. Replaces `rcount` characters starting at index `pos1` with those of
  3098. `str.subview(pos2, n2)`, where `rcount` is `std::min(n1, size() - pos1)`.
  3099. @par Exception Safety
  3100. Strong guarantee.
  3101. @note The replacement is done unchecked when
  3102. the capacity of `str` differs from that of the
  3103. string the function is called on.
  3104. All references, pointers, or iterators
  3105. referring to contained elements are invalidated. Any
  3106. past-the-end iterators are also invalidated.
  3107. @return `*this`
  3108. @param pos1 The index to replace at.
  3109. @param n1 The number of characters to replace.
  3110. @param str The string to replace with.
  3111. @param pos2 The index to begin the substring.
  3112. @param n2 The length of the substring.
  3113. The default argument for this parameter is @ref npos.
  3114. @throw std::length_error `size() + (std::min(str.size(), n2) - rcount) > max_size()`
  3115. @throw std::out_of_range `pos1 > size()`
  3116. @throw std::out_of_range `pos2 > str.size()`
  3117. */
  3118. template<std::size_t M>
  3119. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3120. basic_static_string&
  3121. replace(
  3122. size_type pos1,
  3123. size_type n1,
  3124. const basic_static_string<M, CharT, Traits>& str,
  3125. size_type pos2,
  3126. size_type n2 = npos)
  3127. {
  3128. return replace_unchecked(pos1, n1, str.data() + pos2, str.capped_length(pos2, n2));
  3129. }
  3130. #ifndef BOOST_STATIC_STRING_DOCS
  3131. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3132. basic_static_string&
  3133. replace(
  3134. size_type pos1,
  3135. size_type n1,
  3136. const basic_static_string& str,
  3137. size_type pos2,
  3138. size_type n2 = npos)
  3139. {
  3140. return replace(pos1, n1, str.data() + pos2, str.capped_length(pos2, n2));
  3141. }
  3142. #endif
  3143. /** Replace a part of the string.
  3144. Constructs a temporary `string_view_type` object `sv` from `t`, and
  3145. replaces `rcount` characters starting at index `pos1` with those
  3146. of `sv`, where `rcount` is `std::min(n1, size() - pos1)`.
  3147. @par Exception Safety
  3148. Strong guarantee.
  3149. @note All references, pointers, or iterators
  3150. referring to contained elements are invalidated. Any
  3151. past-the-end iterators are also invalidated.
  3152. @tparam T The type of the object to convert.
  3153. @par Constraints
  3154. `std::is_convertible<const T&, string_view>::value &&
  3155. !std::is_convertible<const T&, const CharT*>::value &&
  3156. !std::is_convertible<const T&, const basic_static_string&>::value`.
  3157. @return `*this`
  3158. @param pos1 The index to replace at.
  3159. @param n1 The number of characters to replace.
  3160. @param t The object to replace with.
  3161. @throw std::length_error `size() + (sv.size() - rcount) > max_size()`
  3162. @throw std::out_of_range `pos1 > size()`
  3163. */
  3164. template<typename T
  3165. #ifndef BOOST_STATIC_STRING_DOCS
  3166. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  3167. #endif
  3168. >
  3169. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3170. basic_static_string&
  3171. replace(
  3172. size_type pos1,
  3173. size_type n1,
  3174. const T& t)
  3175. {
  3176. detail::common_string_view_type<T, CharT, Traits> sv = t;
  3177. return replace(pos1, n1, sv.data(), sv.size());
  3178. }
  3179. /** Replace a part of the string.
  3180. Constructs a temporary `string_view_type` object `sv` from `t`, and
  3181. replaces `rcount` characters starting at index `pos1` with those
  3182. of `sv.substr(pos2, n2)`, where `rcount` is `std::min(n1, size() - pos)`.
  3183. @par Exception Safety
  3184. Strong guarantee.
  3185. @note All references, pointers, or iterators
  3186. referring to contained elements are invalidated. Any
  3187. past-the-end iterators are also invalidated.
  3188. @tparam T The type of the object to convert.
  3189. @par Constraints
  3190. `std::is_convertible<const T&, string_view>::value &&
  3191. !std::is_convertible<const T&, const CharT*>::value &&
  3192. !std::is_convertible<const T&, const basic_static_string&>::value`.
  3193. @return `*this`
  3194. @param pos1 The index to replace at.
  3195. @param n1 The number of characters to replace.
  3196. @param t The object to replace with.
  3197. @param pos2 The index to begin the substring.
  3198. @param n2 The length of the substring.
  3199. The default argument for this parameter is @ref npos.
  3200. @throw std::length_error `size() + (std::min(n2, sv.size()) - rcount) > max_size()`
  3201. @throw std::out_of_range `pos1 > size()`
  3202. @throw std::out_of_range `pos2 > sv.size()`
  3203. */
  3204. template<typename T
  3205. #ifndef BOOST_STATIC_STRING_DOCS
  3206. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  3207. #endif
  3208. >
  3209. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3210. basic_static_string&
  3211. replace(
  3212. size_type pos1,
  3213. size_type n1,
  3214. const T& t,
  3215. size_type pos2,
  3216. size_type n2 = npos)
  3217. {
  3218. detail::common_string_view_type<T, CharT, Traits> sv = t;
  3219. if ( pos2 > sv.size())
  3220. detail::throw_exception<std::out_of_range>("pos2 > t.size()");
  3221. return replace(
  3222. pos1, n1, sv.data() + pos2,
  3223. (std::min)(sv.size() - pos2, n2));
  3224. }
  3225. /** Replace a part of the string.
  3226. Replaces `rcount` characters starting at index `pos` with those of
  3227. `{s, s + n2)`, where `rcount` is `std::min(n1, size() - pos)`.
  3228. @par Exception Safety
  3229. Strong guarantee.
  3230. @note All references, pointers, or iterators
  3231. referring to contained elements are invalidated. Any
  3232. past-the-end iterators are also invalidated.
  3233. @return `*this`
  3234. @param pos The index to replace at.
  3235. @param n1 The number of characters to replace.
  3236. @param s The string to replace with.
  3237. @param n2 The length of the string to replace with.
  3238. @throw std::length_error `size() + (n2 - rcount) > max_size()`
  3239. @throw std::out_of_range `pos > size()`
  3240. */
  3241. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3242. basic_static_string&
  3243. replace(
  3244. size_type pos,
  3245. size_type n1,
  3246. const_pointer s,
  3247. size_type n2)
  3248. {
  3249. return replace(data() + pos, data() + pos + capped_length(pos, n1), s, n2);
  3250. }
  3251. /** Replace a part of the string.
  3252. Replaces `rcount` characters starting at index `pos` with those of
  3253. `{s, s + len)`, where the length of the string `len` is `traits_type::length(s)` and `rcount`
  3254. is `std::min(n1, size() - pos)`.
  3255. @par Exception Safety
  3256. Strong guarantee.
  3257. @note All references, pointers, or iterators
  3258. referring to contained elements are invalidated. Any
  3259. past-the-end iterators are also invalidated.
  3260. @return `*this`
  3261. @param pos The index to replace at.
  3262. @param n1 The number of characters to replace.
  3263. @param s The string to replace with.
  3264. @throw std::length_error `size() + (len - rcount) > max_size()`
  3265. @throw std::out_of_range `pos > size()`
  3266. */
  3267. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3268. basic_static_string&
  3269. replace(
  3270. size_type pos,
  3271. size_type n1,
  3272. const_pointer s)
  3273. {
  3274. return replace(pos, n1, s, traits_type::length(s));
  3275. }
  3276. /** Replace a part of the string.
  3277. Replaces `rcount` characters starting at index `pos` with `n2` copies
  3278. of `c`, where `rcount` is `std::min(n1, size() - pos)`.
  3279. @par Exception Safety
  3280. Strong guarantee.
  3281. @note All references, pointers, or iterators
  3282. referring to contained elements are invalidated. Any
  3283. past-the-end iterators are also invalidated.
  3284. @return `*this`
  3285. @param pos The index to replace at.
  3286. @param n1 The number of characters to replace.
  3287. @param n2 The number of characters to replace with.
  3288. @param c The character to replace with.
  3289. @throw std::length_error `size() + (n2 - rcount) > max_size()`
  3290. @throw std::out_of_range `pos > size()`
  3291. */
  3292. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3293. basic_static_string&
  3294. replace(
  3295. size_type pos,
  3296. size_type n1,
  3297. size_type n2,
  3298. value_type c)
  3299. {
  3300. return replace(data() + pos, data() + pos + capped_length(pos, n1), n2, c);
  3301. }
  3302. /** Replace a part of the string.
  3303. Replaces the characters in the range `{i1, i2)`
  3304. with those of `str`.
  3305. @par Precondition
  3306. `{i1, i2)` is a valid range.
  3307. @par Exception Safety
  3308. Strong guarantee.
  3309. @note The replacement is done unchecked when
  3310. the capacity of `str` differs from that of the
  3311. string the function is called on.
  3312. All references, pointers, or iterators
  3313. referring to contained elements are invalidated. Any
  3314. past-the-end iterators are also invalidated.
  3315. @tparam M The size of the input string.
  3316. @return `*this`
  3317. @param i1 An iterator referring to the first character to replace.
  3318. @param i2 An iterator referring past the end of
  3319. the last character to replace.
  3320. @param str The string to replace with.
  3321. @throw std::length_error `size() + (str.size() - std::distance(i1, i2)) > max_size()`
  3322. */
  3323. template<std::size_t M>
  3324. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3325. basic_static_string&
  3326. replace(
  3327. const_iterator i1,
  3328. const_iterator i2,
  3329. const basic_static_string<M, CharT, Traits>& str)
  3330. {
  3331. return replace_unchecked(i1, i2, str.data(), str.size());
  3332. }
  3333. #ifndef BOOST_STATIC_STRING_DOCS
  3334. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3335. basic_static_string&
  3336. replace(
  3337. const_iterator i1,
  3338. const_iterator i2,
  3339. const basic_static_string& str)
  3340. {
  3341. return replace(i1, i2, str.data(), str.size());
  3342. }
  3343. #endif
  3344. /** Replace a part of the string.
  3345. Constructs a temporary `string_view_type` object `sv` from `t`, and
  3346. replaces the characters in the range `{i1, i2)` with those
  3347. of `sv`.
  3348. @par Precondition
  3349. `{i1, i2)` is a valid range.
  3350. @par Exception Safety
  3351. Strong guarantee.
  3352. @note All references, pointers, or iterators
  3353. referring to contained elements are invalidated. Any
  3354. past-the-end iterators are also invalidated.
  3355. @tparam T The type of the object to convert.
  3356. @par Constraints
  3357. `std::is_convertible<const T&, string_view>::value &&
  3358. !std::is_convertible<const T&, const CharT*>::value &&
  3359. !std::is_convertible<const T&, const basic_static_string&>::value`.
  3360. @return `*this`
  3361. @param i1 An iterator referring to the first character to replace.
  3362. @param i2 An iterator referring past the end of
  3363. the last character to replace.
  3364. @param t The object to replace with.
  3365. @throw std::length_error `size() + (sv.size() - std::distance(i1, i2)) > max_size()`
  3366. */
  3367. template<typename T
  3368. #ifndef BOOST_STATIC_STRING_DOCS
  3369. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  3370. #endif
  3371. >
  3372. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3373. basic_static_string&
  3374. replace(
  3375. const_iterator i1,
  3376. const_iterator i2,
  3377. const T& t)
  3378. {
  3379. detail::common_string_view_type<T, CharT, Traits> sv = t;
  3380. return replace(i1, i2, sv.data(), sv.data() + sv.size());
  3381. }
  3382. /** Replace a part of the string.
  3383. Replaces the characters in the range `{i1, i2)` with those of
  3384. `{s, s + n)`.
  3385. @par Precondition
  3386. `{i1, i2)` is a valid range.
  3387. @par Exception Safety
  3388. Strong guarantee.
  3389. @note All references, pointers, or iterators
  3390. referring to contained elements are invalidated. Any
  3391. past-the-end iterators are also invalidated.
  3392. @return `*this`
  3393. @param i1 An iterator referring to the first character to replace.
  3394. @param i2 An iterator referring past the end of
  3395. the last character to replace.
  3396. @param s The string to replace with.
  3397. @param n The length of the string to replace with.
  3398. @throw std::length_error `size() + (n - std::distance(i1, i2)) > max_size()`
  3399. */
  3400. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3401. basic_static_string&
  3402. replace(
  3403. const_iterator i1,
  3404. const_iterator i2,
  3405. const_pointer s,
  3406. size_type n)
  3407. {
  3408. return replace(i1, i2, s, s + n);
  3409. }
  3410. /** Replace a part of the string.
  3411. Replaces the characters in the range `{i1, i2)` with those of
  3412. `{s, s + len)`, where the length of the string `len` is `traits_type::length(s)`.
  3413. @par Precondition
  3414. `{i1, i2)` shall be a valid range.
  3415. @par Exception Safety
  3416. Strong guarantee.
  3417. @note All references, pointers, or iterators
  3418. referring to contained elements are invalidated. Any
  3419. past-the-end iterators are also invalidated.
  3420. @return `*this`
  3421. @param i1 An iterator referring to the first character to replace.
  3422. @param i2 An iterator referring past the end of
  3423. the last character to replace.
  3424. @param s The string to replace with.
  3425. @throw std::length_error `size() + (len - std::distance(i1, i2)) > max_size()`
  3426. */
  3427. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3428. basic_static_string&
  3429. replace(
  3430. const_iterator i1,
  3431. const_iterator i2,
  3432. const_pointer s)
  3433. {
  3434. return replace(i1, i2, s, traits_type::length(s));
  3435. }
  3436. /** Replace a part of the string.
  3437. Replaces the characters in the range `{i1, i2)` with
  3438. `n` copies of `c`.
  3439. @par Precondition
  3440. `{i1, i2)` is a valid range.
  3441. @par Exception Safety
  3442. Strong guarantee.
  3443. @note All references, pointers, or iterators
  3444. referring to contained elements are invalidated. Any
  3445. past-the-end iterators are also invalidated.
  3446. @return `*this`
  3447. @param i1 An iterator referring to the first character to replace.
  3448. @param i2 An iterator past the end of
  3449. the last character to replace.
  3450. @param n The number of characters to replace with.
  3451. @param c The character to replace with.
  3452. @throw std::length_error `size() + (n - std::distance(i1, i2)) > max_size()`
  3453. */
  3454. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3455. basic_static_string&
  3456. replace(
  3457. const_iterator i1,
  3458. const_iterator i2,
  3459. size_type n,
  3460. value_type c);
  3461. /** Replace a part of the string.
  3462. Replaces the characters in the range `{i1, i2)`
  3463. with those of `{j1, j2)`.
  3464. @par Precondition
  3465. `{i1, i2)` is a valid range.
  3466. `{j1, j2)` is a valid range.
  3467. @par Exception Safety
  3468. Strong guarantee.
  3469. @note All references, pointers, or iterators
  3470. referring to contained elements are invalidated. Any
  3471. past-the-end iterators are also invalidated.
  3472. @tparam InputIterator The type of the iterators.
  3473. @par Constraints
  3474. `InputIterator` satisfies __InputIterator__ and does not
  3475. satisfy __ForwardIterator__.
  3476. @return `*this`
  3477. @param i1 An iterator referring to the first character to replace.
  3478. @param i2 An iterator referring past the end of
  3479. the last character to replace.
  3480. @param j1 An iterator referring to the first character to replace with.
  3481. @param j2 An iterator referring past the end of
  3482. the last character to replace with.
  3483. @throw std::length_error `size() + (inserted - std::distance(i1, i2)) > max_size()`
  3484. */
  3485. template<typename InputIterator>
  3486. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3487. #ifdef BOOST_STATIC_STRING_DOCS
  3488. basic_static_string&
  3489. #else
  3490. typename std::enable_if<
  3491. detail::is_input_iterator<
  3492. InputIterator>::value &&
  3493. !detail::is_forward_iterator<
  3494. InputIterator>::value,
  3495. basic_static_string<N, CharT, Traits>&>::type
  3496. #endif
  3497. replace(
  3498. const_iterator i1,
  3499. const_iterator i2,
  3500. InputIterator j1,
  3501. InputIterator j2);
  3502. #ifndef BOOST_STATIC_STRING_DOCS
  3503. template<typename ForwardIterator>
  3504. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3505. typename std::enable_if<
  3506. detail::is_forward_iterator<
  3507. ForwardIterator>::value,
  3508. basic_static_string<N, CharT, Traits>&>::type
  3509. replace(
  3510. const_iterator i1,
  3511. const_iterator i2,
  3512. ForwardIterator j1,
  3513. ForwardIterator j2);
  3514. #endif
  3515. /** Replace a part of the string.
  3516. Replaces the characters in the range `{i1, i2)`
  3517. with those of contained in the initializer list `il`.
  3518. @par Precondition
  3519. `{i1, i2)` is a valid range.
  3520. @par Exception Safety
  3521. Strong guarantee.
  3522. @note All references, pointers, or iterators
  3523. referring to contained elements are invalidated. Any
  3524. past-the-end iterators are also invalidated.
  3525. @return `*this`
  3526. @param i1 An iterator referring to the first character to replace.
  3527. @param i2 An iterator past the end of
  3528. the last character to replace.
  3529. @param il The initializer list to replace with.
  3530. @throw std::length_error `size() + (il.size() - std::distance(i1, i2)) > max_size()`
  3531. */
  3532. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3533. basic_static_string&
  3534. replace(
  3535. const_iterator i1,
  3536. const_iterator i2,
  3537. std::initializer_list<value_type> il)
  3538. {
  3539. return replace_unchecked(i1, i2, il.begin(), il.size());
  3540. }
  3541. //--------------------------------------------------------------------------
  3542. //
  3543. // Search
  3544. //
  3545. //--------------------------------------------------------------------------
  3546. /** Find the first occurrence of a string within the string.
  3547. Constructs a temporary `string_view_type` object `sv` from `t`, and finds
  3548. the first occurrence of `sv` within the string starting at the index `pos`.
  3549. @par Complexity
  3550. Linear.
  3551. @note An empty string is always found.
  3552. @tparam T The type of the object to convert.
  3553. @par Constraints
  3554. `std::is_convertible<const T&, string_view>::value &&
  3555. !std::is_convertible<const T&, const CharT*>::value &&
  3556. !std::is_convertible<const T&, const basic_static_string&>::value`.
  3557. @return The lowest index `idx` greater than or equal to `pos`
  3558. where each element of `{sv.begin(), sv.end())` is equal to
  3559. that of `{begin() + idx, begin() + idx + count)` if one exists,
  3560. and @ref npos otherwise.
  3561. @param t The string to search for.
  3562. @param pos The index to start searching at. The default argument
  3563. for this parameter is `0`.
  3564. */
  3565. template<typename T
  3566. #ifndef BOOST_STATIC_STRING_DOCS
  3567. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  3568. #endif
  3569. >
  3570. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3571. size_type
  3572. find(
  3573. const T& t,
  3574. size_type pos = 0) const
  3575. #ifdef BOOST_STATIC_STRING_DOCS
  3576. noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
  3577. #else
  3578. noexcept(detail::is_nothrow_convertible<const T&, detail::common_string_view_type<T, CharT, Traits>>::value)
  3579. #endif
  3580. {
  3581. detail::common_string_view_type<T, CharT, Traits> sv = t;
  3582. return find(sv.data(), pos, sv.size());
  3583. }
  3584. /** Find the first occurrence of a string within the string.
  3585. Finds the first occurrence of `str` within the
  3586. string starting at the index `pos`.
  3587. @par Complexity
  3588. Linear.
  3589. @return The lowest index `idx` greater than or equal to `pos`
  3590. where each element of `str` is equal to that of
  3591. `{begin() + idx, begin() + idx + str.size())`
  3592. if one exists, and @ref npos otherwise.
  3593. @param str The string to search for.
  3594. @param pos The index to start searching at. The default argument for
  3595. this parameter is `0`.
  3596. */
  3597. template<std::size_t M>
  3598. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3599. size_type
  3600. find(
  3601. const basic_static_string<M, CharT, Traits>& str,
  3602. size_type pos = 0) const noexcept
  3603. {
  3604. return find(str.data(), pos, str.size());
  3605. }
  3606. /** Find the first occurrence of a string within the string.
  3607. Finds the first occurrence of the string pointed to
  3608. by `s` within the string starting at the index `pos`.
  3609. @par Complexity
  3610. Linear.
  3611. @note An empty string is always found.
  3612. @return The lowest index `idx` greater than or equal to `pos`
  3613. where each element of `{s, s + n)` is equal to that of
  3614. `{begin() + idx, begin() + idx + n)` if one exists,
  3615. and @ref npos otherwise.
  3616. @param s The string to search for.
  3617. @param pos The index to start searching at.
  3618. @param n The length of the string to search for.
  3619. */
  3620. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3621. size_type
  3622. find(
  3623. const_pointer s,
  3624. size_type pos,
  3625. size_type n) const noexcept;
  3626. /** Find the first occurrence of a string within the string.
  3627. Finds the first occurrence of the string pointed to by `s`
  3628. of length `count` within the string starting at the index `pos`,
  3629. where `count` is `traits_type::length(s)`.
  3630. @par Complexity
  3631. Linear.
  3632. @note An empty string is always found.
  3633. @return The lowest index `idx` greater than or equal to `pos`
  3634. where each element of `{s, s + count)` is equal to that of
  3635. `{begin() + idx, begin() + idx + count)` if one exists,
  3636. and @ref npos otherwise.
  3637. @param s The string to search for.
  3638. @param pos The index to start searching at. The default argument
  3639. for this parameter is `0`.
  3640. */
  3641. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3642. size_type
  3643. find(
  3644. const_pointer s,
  3645. size_type pos = 0) const noexcept
  3646. {
  3647. return find(s, pos, traits_type::length(s));
  3648. }
  3649. /** Find the first occurrence of a character within the string.
  3650. Finds the first occurrence of `c` within the string
  3651. starting at the index `pos`.
  3652. @par Complexity
  3653. Linear.
  3654. @return The index corrosponding to the first occurrence of `c` within
  3655. `{begin() + pos, end())` if it exists, and @ref npos otherwise.
  3656. @param c The character to search for.
  3657. @param pos The index to start searching at. The default argument
  3658. for this parameter is `0`.
  3659. */
  3660. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3661. size_type
  3662. find(
  3663. value_type c,
  3664. size_type pos = 0) const noexcept
  3665. {
  3666. return find(&c, pos, 1);
  3667. }
  3668. /** Find the last occurrence of a string within the string.
  3669. Constructs a temporary `string_view_type` object `sv` from `t`, and finds
  3670. the last occurrence of `sv` within the string starting before or at
  3671. the index `pos`.
  3672. @par Complexity
  3673. Linear.
  3674. @tparam T The type of the object to convert.
  3675. @par Constraints
  3676. `std::is_convertible<const T&, string_view>::value &&
  3677. !std::is_convertible<const T&, const CharT*>::value &&
  3678. !std::is_convertible<const T&, const basic_static_string&>::value`.
  3679. @return The highest index `idx` less than or equal to `pos`
  3680. where each element of `{sv.begin(), sv.end())` is equal to
  3681. that of `{begin() + idx, begin() + idx + count)` if one exists,
  3682. and @ref npos otherwise.
  3683. @param t The string to search for.
  3684. @param pos The index to start searching at. The default argument
  3685. for this parameter is @ref npos.
  3686. */
  3687. template<typename T
  3688. #ifndef BOOST_STATIC_STRING_DOCS
  3689. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  3690. #endif
  3691. >
  3692. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3693. size_type
  3694. rfind(
  3695. const T& t,
  3696. size_type pos = npos) const
  3697. #ifdef BOOST_STATIC_STRING_DOCS
  3698. noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
  3699. #else
  3700. noexcept(detail::is_nothrow_convertible<const T&, detail::common_string_view_type<T, CharT, Traits>>::value)
  3701. #endif
  3702. {
  3703. detail::common_string_view_type<T, CharT, Traits> sv = t;
  3704. return rfind(sv.data(), pos, sv.size());
  3705. }
  3706. /** Find the last occurrence of a string within the string.
  3707. Finds the last occurrence of `str` within the string
  3708. starting before or at the index `pos`.
  3709. @par Complexity
  3710. Linear.
  3711. @return The highest index `idx` less than or equal to `pos`
  3712. where each element of `str` is equal to that
  3713. of `{begin() + idx, begin() + idx + str.size())`
  3714. if one exists, and @ref npos otherwise.
  3715. @param str The string to search for.
  3716. @param pos The index to start searching at. The default argument for
  3717. this parameter is @ref npos.
  3718. */
  3719. template<std::size_t M>
  3720. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3721. size_type
  3722. rfind(
  3723. const basic_static_string<M, CharT, Traits>& str,
  3724. size_type pos = npos) const noexcept
  3725. {
  3726. return rfind(str.data(), pos, str.size());
  3727. }
  3728. /** Find the last occurrence of a string within the string.
  3729. Finds the last occurrence of the string pointed to
  3730. by `s` within the string starting before or at
  3731. the index `pos`.
  3732. @par Complexity
  3733. Linear.
  3734. @return The highest index `idx` less than or equal to `pos`
  3735. where each element of `{s, s + n)` is equal to that of
  3736. `{begin() + idx, begin() + idx + n)` if one exists,
  3737. and @ref npos otherwise.
  3738. @param s The string to search for.
  3739. @param pos The index to start searching at.
  3740. @param n The length of the string to search for.
  3741. */
  3742. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3743. size_type
  3744. rfind(
  3745. const_pointer s,
  3746. size_type pos,
  3747. size_type n) const noexcept;
  3748. /** Find the last occurrence of a string within the string.
  3749. Finds the last occurrence of the string pointed to by `s`
  3750. of length `count` within the string starting before or at the
  3751. index `pos`, where `count` is `traits_type::length(s)`.
  3752. @par Complexity
  3753. Linear.
  3754. @return The highest index `idx` less than or equal to `pos`
  3755. where each element of `{s, s + count)` is equal to that of
  3756. `{begin() + idx, begin() + idx + count)` if one exists,
  3757. and @ref npos otherwise.
  3758. @param s The string to search for.
  3759. @param pos The index to stop searching at. The default argument
  3760. for this parameter is @ref npos.
  3761. */
  3762. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3763. size_type
  3764. rfind(
  3765. const_pointer s,
  3766. size_type pos = npos) const noexcept
  3767. {
  3768. return rfind(s, pos, traits_type::length(s));
  3769. }
  3770. /** Find the last occurrence of a character within the string.
  3771. Finds the last occurrence of `c` within the string
  3772. starting before or at the index `pos`.
  3773. @par Complexity
  3774. Linear.
  3775. @return The index corrosponding to the last occurrence of `c` within
  3776. `{begin(), begin() + pos}` if it exists, and @ref npos otherwise.
  3777. @param c The character to search for.
  3778. @param pos The index to stop searching at. The default argument
  3779. for this parameter is @ref npos.
  3780. */
  3781. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3782. size_type
  3783. rfind(
  3784. value_type c,
  3785. size_type pos = npos) const noexcept
  3786. {
  3787. return rfind(&c, pos, 1);
  3788. }
  3789. /** Find the first occurrence of any of the characters within the string.
  3790. Constructs a temporary `string_view_type` object `sv` from `t`, and finds
  3791. the first occurrence of any of the characters in `sv`
  3792. within the string starting at the index `pos`.
  3793. @par Complexity
  3794. Linear.
  3795. @tparam T The type of the object to convert.
  3796. @par Constraints
  3797. `std::is_convertible<const T&, string_view>::value &&
  3798. !std::is_convertible<const T&, const CharT*>::value &&
  3799. !std::is_convertible<const T&, const basic_static_string&>::value`.
  3800. @return The index corrosponding to the first occurrence of
  3801. any of the characters in `{sv.begin(), sv.end())` within
  3802. `{begin() + pos, end())` if it exists, and @ref npos otherwise.
  3803. @param t The characters to search for.
  3804. @param pos The index to start searching at. The default argument
  3805. for this parameter is `0`.
  3806. */
  3807. template<typename T
  3808. #ifndef BOOST_STATIC_STRING_DOCS
  3809. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  3810. #endif
  3811. >
  3812. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3813. size_type
  3814. find_first_of(
  3815. const T& t,
  3816. size_type pos = 0) const
  3817. #ifdef BOOST_STATIC_STRING_DOCS
  3818. noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
  3819. #else
  3820. noexcept(detail::is_nothrow_convertible<const T&, detail::common_string_view_type<T, CharT, Traits>>::value)
  3821. #endif
  3822. {
  3823. detail::common_string_view_type<T, CharT, Traits> sv = t;
  3824. return find_first_of(sv.data(), pos, sv.size());
  3825. }
  3826. /** Find the first occurrence of any of the characters within the string.
  3827. Finds the first occurrence of any of the characters within `str` within the
  3828. string starting at the index `pos`.
  3829. @par Complexity
  3830. Linear.
  3831. @return The index corrosponding to the first occurrence of any of the characters
  3832. of `str` within `{begin() + pos, end())` if it exists, and @ref npos otherwise.
  3833. @param str The characters to search for.
  3834. @param pos The index to start searching at. The default argument for
  3835. this parameter is `0`.
  3836. */
  3837. template<std::size_t M>
  3838. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3839. size_type
  3840. find_first_of(
  3841. const basic_static_string<M, CharT, Traits>& str,
  3842. size_type pos = 0) const noexcept
  3843. {
  3844. return find_first_of(str.data(), pos, str.size());
  3845. }
  3846. /** Find the first occurrence of any of the characters within the string.
  3847. Finds the first occurrence of any of the characters within the string pointed to
  3848. by `s` within the string starting at the index `pos`.
  3849. @par Complexity
  3850. Linear.
  3851. @return The index corrosponding to the first occurrence
  3852. of any of the characters in `{s, s + n)` within `{begin() + pos, end())`
  3853. if it exists, and @ref npos otherwise.
  3854. @param s The characters to search for.
  3855. @param pos The index to start searching at.
  3856. @param n The length of the string to search for.
  3857. */
  3858. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3859. size_type
  3860. find_first_of(
  3861. const_pointer s,
  3862. size_type pos,
  3863. size_type n) const noexcept;
  3864. /** Find the first occurrence of any of the characters within the string.
  3865. Finds the first occurrence of the any of the characters within string
  3866. pointed to by `s` of length `count` within the string starting at the
  3867. index `pos`, where `count` is `traits_type::length(s)`.
  3868. @par Complexity
  3869. Linear.
  3870. @return The index corrosponding to the first occurrence of any of
  3871. the characters in `{s, s + count)` within
  3872. `{begin() + pos, end())` if it exists, and @ref npos otherwise.
  3873. @param s The characters to search for.
  3874. @param pos The index to start searching at. The default argument
  3875. for this parameter is `0`.
  3876. */
  3877. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3878. size_type
  3879. find_first_of(
  3880. const_pointer s,
  3881. size_type pos = 0) const noexcept
  3882. {
  3883. return find_first_of(s, pos, traits_type::length(s));
  3884. }
  3885. /** Find the first occurrence of a character within the string.
  3886. Finds the first occurrence of `c` within the string
  3887. starting at the index `pos`.
  3888. @par Complexity
  3889. Linear.
  3890. @return The index corrosponding to the first occurrence of `c` within
  3891. `{begin() + pos, end())` if it exists, and @ref npos otherwise.
  3892. @param c The character to search for.
  3893. @param pos The index to start searching at. The default argument
  3894. for this parameter is `0`.
  3895. */
  3896. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3897. size_type
  3898. find_first_of(
  3899. value_type c,
  3900. size_type pos = 0) const noexcept
  3901. {
  3902. return find_first_of(&c, pos, 1);
  3903. }
  3904. /** Find the last occurrence of any of the characters within the string.
  3905. Constructs a temporary `string_view_type` object `sv` from `t`, and finds
  3906. the last occurrence of any of the characters in `sv`
  3907. within the string before or at the index `pos`.
  3908. @par Complexity
  3909. Linear.
  3910. @tparam T The type of the object to convert.
  3911. @par Constraints
  3912. `std::is_convertible<const T&, string_view>::value &&
  3913. !std::is_convertible<const T&, const CharT*>::value &&
  3914. !std::is_convertible<const T&, const basic_static_string&>::value`.
  3915. @return The index corrosponding to the last occurrence of
  3916. any of the characters in `{sv.begin(), sv.end())` within
  3917. `{begin(), begin() + pos}` if it exists, and @ref npos otherwise.
  3918. @param t The characters to search for.
  3919. @param pos The index to stop searching at. The default argument
  3920. for this parameter is @ref npos.
  3921. */
  3922. template<typename T
  3923. #ifndef BOOST_STATIC_STRING_DOCS
  3924. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  3925. #endif
  3926. >
  3927. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3928. size_type
  3929. find_last_of(
  3930. const T& t,
  3931. size_type pos = npos) const
  3932. #ifdef BOOST_STATIC_STRING_DOCS
  3933. noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
  3934. #else
  3935. noexcept(detail::is_nothrow_convertible<const T&, detail::common_string_view_type<T, CharT, Traits>>::value)
  3936. #endif
  3937. {
  3938. detail::common_string_view_type<T, CharT, Traits> sv = t;
  3939. return find_last_of(sv.data(), pos, sv.size());
  3940. }
  3941. /** Find the last occurrence of any of the characters within the string.
  3942. Finds the last occurrence of any of the characters within `str` within the
  3943. string starting before or at the index `pos`.
  3944. @par Complexity
  3945. Linear.
  3946. @return The index corrosponding to the last occurrence of any of the characters
  3947. of `str` within `{begin(), begin() + pos}` if it exists, and @ref npos otherwise.
  3948. @param str The characters to search for.
  3949. @param pos The index to stop searching at. The default argument for
  3950. this parameter is @ref npos.
  3951. */
  3952. template<std::size_t M>
  3953. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3954. size_type
  3955. find_last_of(
  3956. const basic_static_string<M, CharT, Traits>& str,
  3957. size_type pos = npos) const noexcept
  3958. {
  3959. return find_last_of(str.data(), pos, str.size());
  3960. }
  3961. /** Find the last occurrence of any of the characters within the string.
  3962. Finds the last occurrence of any of the characters within the string pointed to
  3963. by `s` within the string before or at the index `pos`.
  3964. @par Complexity
  3965. Linear.
  3966. @return The index corrosponding to the last occurrence
  3967. of any of the characters in `{s, s + n)` within `{begin(), begin() + pos}`
  3968. if it exists, and @ref npos otherwise.
  3969. @param s The characters to search for.
  3970. @param pos The index to stop searching at.
  3971. @param n The length of the string to search for.
  3972. */
  3973. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3974. size_type
  3975. find_last_of(
  3976. const_pointer s,
  3977. size_type pos,
  3978. size_type n) const noexcept;
  3979. /** Find the last occurrence of any of the characters within the string.
  3980. Finds the last occurrence of any of the characters within the string pointed to
  3981. by `s` of length `count` within the string before or at the index `pos`,
  3982. where `count` is `traits_type::length(s)`.
  3983. @par Complexity
  3984. Linear.
  3985. @return The index corrosponding to the last occurrence
  3986. of any of the characters in `{s, s + count)` within `{begin(), begin() + pos}`
  3987. if it exists, and @ref npos otherwise.
  3988. @param s The characters to search for.
  3989. @param pos The index to stop searching at. The default argument for
  3990. this parameter is @ref npos.
  3991. */
  3992. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  3993. size_type
  3994. find_last_of(
  3995. const_pointer s,
  3996. size_type pos = npos) const noexcept
  3997. {
  3998. return find_last_of(s, pos, traits_type::length(s));
  3999. }
  4000. /** Find the last occurrence of a character within the string.
  4001. Finds the last occurrence of `c` within the string
  4002. before or at the index `pos`.
  4003. @par Complexity
  4004. Linear.
  4005. @return The index corrosponding to the last occurrence of `c` within
  4006. `{begin(), begin() + pos}` if it exists, and @ref npos otherwise.
  4007. @param c The character to search for.
  4008. @param pos The index to stop searching at. The default argument
  4009. for this parameter is @ref npos.
  4010. */
  4011. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4012. size_type
  4013. find_last_of(
  4014. value_type c,
  4015. size_type pos = npos) const noexcept
  4016. {
  4017. return find_last_of(&c, pos, 1);
  4018. }
  4019. /** Find the first occurrence of a character not within the string.
  4020. Constructs a temporary `string_view_type` object `sv` from `t`, and finds
  4021. the first character that is not within `sv`, starting at the index `pos`.
  4022. @par Complexity
  4023. Linear.
  4024. @tparam T The type of the object to convert.
  4025. @par Constraints
  4026. `std::is_convertible<const T&, string_view>::value &&
  4027. !std::is_convertible<const T&, const CharT*>::value &&
  4028. !std::is_convertible<const T&, const basic_static_string&>::value`.
  4029. @return The index corrosponding to the first occurrence of
  4030. a character that is not in `{sv.begin(), sv.end())` within
  4031. `{begin() + pos, end())` if it exists, and @ref npos otherwise.
  4032. @param t The characters to ignore.
  4033. @param pos The index to start searching at. The default argument
  4034. for this parameter is `0`.
  4035. */
  4036. template<typename T
  4037. #ifndef BOOST_STATIC_STRING_DOCS
  4038. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4039. #endif
  4040. >
  4041. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4042. size_type
  4043. find_first_not_of(
  4044. const T& t,
  4045. size_type pos = 0) const
  4046. #ifdef BOOST_STATIC_STRING_DOCS
  4047. noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
  4048. #else
  4049. noexcept(detail::is_nothrow_convertible<const T&, detail::common_string_view_type<T, CharT, Traits>>::value)
  4050. #endif
  4051. {
  4052. detail::common_string_view_type<T, CharT, Traits> sv = t;
  4053. return find_first_not_of(sv.data(), pos, sv.size());
  4054. }
  4055. /** Find the first occurrence of any of the characters not within the string.
  4056. Finds the first occurrence of a character that is not within `str`
  4057. within the string starting at the index `pos`.
  4058. @par Complexity
  4059. Linear.
  4060. @return The index corrosponding to the first character of `{begin() + pos, end())`
  4061. that is not within `str` if it exists, and @ref npos otherwise.
  4062. @param str The characters to ignore.
  4063. @param pos The index to start searching at. The default argument for
  4064. this parameter is `0`.
  4065. */
  4066. template<std::size_t M>
  4067. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4068. size_type
  4069. find_first_not_of(
  4070. const basic_static_string<M, CharT, Traits>& str,
  4071. size_type pos = 0) const noexcept
  4072. {
  4073. return find_first_not_of(str.data(), pos, str.size());
  4074. }
  4075. /** Find the first occurrence of any of the characters not within the string.
  4076. Finds the first occurrence of a character that is not within the string
  4077. pointed to by `s` within the string starting at the index `pos`.
  4078. @par Complexity
  4079. Linear.
  4080. @return The index corrosponding to the first character of `{begin() + pos, end())`
  4081. that is not within `{s, s + n)` if it exists, and @ref npos otherwise.
  4082. @param s The characters to ignore.
  4083. @param pos The index to start searching at. The default argument for
  4084. this parameter is `0`.
  4085. @param n The length of the characters to ignore.
  4086. */
  4087. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4088. size_type
  4089. find_first_not_of(
  4090. const_pointer s,
  4091. size_type pos,
  4092. size_type n) const noexcept;
  4093. /** Find the first occurrence of any of the characters not within the string.
  4094. Finds the first occurrence of a character that is not within the string
  4095. pointed to by `s` of length `count` within the string starting
  4096. at the index `pos`, where `count` is `traits_type::length(s)`.
  4097. @par Complexity
  4098. Linear.
  4099. @return The index corrosponding to the first character of `{begin() + pos, end())`
  4100. that is not within `{s, s + count)` if it exists, and @ref npos otherwise.
  4101. @param s The characters to ignore.
  4102. @param pos The index to start searching at. The default argument for
  4103. this parameter is `0`.
  4104. */
  4105. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4106. size_type
  4107. find_first_not_of(
  4108. const_pointer s,
  4109. size_type pos = 0) const noexcept
  4110. {
  4111. return find_first_not_of(s, pos, traits_type::length(s));
  4112. }
  4113. /** Find the first occurrence of a character not equal to `c`.
  4114. Finds the first occurrence of a character that is not equal
  4115. to `c`.
  4116. @par Complexity
  4117. Linear.
  4118. @return The index corrosponding to the first character of `{begin() + pos, end())`
  4119. that is not equal to `c` if it exists, and @ref npos otherwise.
  4120. @param c The character to ignore.
  4121. @param pos The index to start searching at. The default argument for
  4122. this parameter is `0`.
  4123. */
  4124. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4125. size_type
  4126. find_first_not_of(
  4127. value_type c,
  4128. size_type pos = 0) const noexcept
  4129. {
  4130. return find_first_not_of(&c, pos, 1);
  4131. }
  4132. /** Find the last occurrence of a character not within the string.
  4133. Constructs a temporary `string_view_type` object `sv` from `t`, and finds
  4134. the last character that is not within `sv`, starting at the index `pos`.
  4135. @par Complexity
  4136. Linear.
  4137. @tparam T The type of the object to convert.
  4138. @par Constraints
  4139. `std::is_convertible<const T&, string_view>::value &&
  4140. !std::is_convertible<const T&, const CharT*>::value &&
  4141. !std::is_convertible<const T&, const basic_static_string&>::value`.
  4142. @return The index corrosponding to the last occurrence of
  4143. a character that is not in `{sv.begin(), sv.end())` within
  4144. `{begin(), begin() + pos}` if it exists, and @ref npos otherwise.
  4145. @param t The characters to ignore.
  4146. @param pos The index to start searching at. The default argument
  4147. for this parameter is @ref npos.
  4148. */
  4149. template<typename T
  4150. #ifndef BOOST_STATIC_STRING_DOCS
  4151. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4152. #endif
  4153. >
  4154. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4155. size_type
  4156. find_last_not_of(
  4157. const T& t,
  4158. size_type pos = npos) const
  4159. #ifdef BOOST_STATIC_STRING_DOCS
  4160. noexcept(detail::is_nothrow_convertible<const T&, string_view_type>::value)
  4161. #else
  4162. noexcept(detail::is_nothrow_convertible<const T&, detail::common_string_view_type<T, CharT, Traits>>::value)
  4163. #endif
  4164. {
  4165. detail::common_string_view_type<T, CharT, Traits> sv = t;
  4166. return find_last_not_of(sv.data(), pos, sv.size());
  4167. }
  4168. /** Find the last occurrence of a character not within the string.
  4169. Finds the last occurrence of a character that is not within `str`
  4170. within the string before or at the index `pos`.
  4171. @par Complexity
  4172. Linear.
  4173. @return The index corrosponding to the last character of `{begin(), begin() + pos}`
  4174. that is not within `str` if it exists, and @ref npos otherwise.
  4175. @param str The characters to ignore.
  4176. @param pos The index to stop searching at. The default argument for
  4177. this parameter is @ref npos.
  4178. */
  4179. template<size_t M>
  4180. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4181. size_type
  4182. find_last_not_of(
  4183. const basic_static_string<M, CharT, Traits>& str,
  4184. size_type pos = npos) const noexcept
  4185. {
  4186. return find_last_not_of(str.data(), pos, str.size());
  4187. }
  4188. /** Find the last occurrence of a character not within the string.
  4189. Finds the last occurrence of a character that is not within the
  4190. string pointed to by `s` within the string before or at the index `pos`.
  4191. @par Complexity
  4192. Linear.
  4193. @return The index corrosponding to the last character of `{begin(), begin() + pos}`
  4194. that is not within `{s, s + n)` if it exists, and @ref npos otherwise.
  4195. @param s The characters to ignore.
  4196. @param pos The index to stop searching at. The default argument for
  4197. this parameter is @ref npos.
  4198. @param n The length of the characters to ignore.
  4199. */
  4200. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4201. size_type
  4202. find_last_not_of(
  4203. const_pointer s,
  4204. size_type pos,
  4205. size_type n) const noexcept;
  4206. /** Find the last occurrence of a character not within the string.
  4207. Finds the last occurrence of a character that is not within the
  4208. string pointed to by `s` of length `count` within the string
  4209. before or at the index `pos`, where `count` is `traits_type::length(s)`.
  4210. @par Complexity
  4211. Linear.
  4212. @return The index corrosponding to the last character of `{begin(), begin() + pos}`
  4213. that is not within `{s, s + count)` if it exists, and @ref npos otherwise.
  4214. @param s The characters to ignore.
  4215. @param pos The index to stop searching at. The default argument for
  4216. this parameter is @ref npos.
  4217. */
  4218. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4219. size_type
  4220. find_last_not_of(
  4221. const_pointer s,
  4222. size_type pos = npos) const noexcept
  4223. {
  4224. return find_last_not_of(s, pos, traits_type::length(s));
  4225. }
  4226. /** Find the last occurrence of a character not equal to `c`.
  4227. Finds the last occurrence of a character that is not equal
  4228. to `c` before or at the index `pos`.
  4229. @par Complexity
  4230. Linear.
  4231. @return The index corrosponding to the last character of `{begin(), begin() + pos}`
  4232. that is not equal to `c` if it exists, and @ref npos otherwise.
  4233. @param c The character to ignore.
  4234. @param pos The index to start searching at. The default argument for
  4235. this parameter is @ref npos.
  4236. */
  4237. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4238. size_type
  4239. find_last_not_of(
  4240. value_type c,
  4241. size_type pos = npos) const noexcept
  4242. {
  4243. return find_last_not_of(&c, pos, 1);
  4244. }
  4245. /** Return whether the string begins with a string.
  4246. Returns `true` if the string begins with `s`, and `false` otherwise.
  4247. @par Complexity
  4248. Linear.
  4249. @param t The string view to check for.
  4250. */
  4251. template<typename T
  4252. #ifndef BOOST_STATIC_STRING_DOCS
  4253. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4254. #endif
  4255. >
  4256. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4257. bool
  4258. starts_with(
  4259. T const& t) const noexcept
  4260. {
  4261. detail::common_string_view_type<T, CharT, Traits> sv = t;
  4262. const size_type len = sv.size();
  4263. return size() >= len && !traits_type::compare(data(), sv.data(), len);
  4264. }
  4265. /** Return whether the string begins with a character.
  4266. Returns `true` if the string begins with `c`, and `false` otherwise.
  4267. @par Complexity
  4268. Constant.
  4269. @param c The character to check for.
  4270. */
  4271. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4272. bool
  4273. starts_with(
  4274. value_type c) const noexcept
  4275. {
  4276. return !empty() && traits_type::eq(front(), c);
  4277. }
  4278. /** Return whether the string begins with a string.
  4279. Returns `true` if the string begins with the string
  4280. pointed to be `s` of length `traits_type::length(s)`,
  4281. and `false` otherwise.
  4282. @par Complexity
  4283. Linear.
  4284. @param s The string to check for.
  4285. */
  4286. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4287. bool
  4288. starts_with(
  4289. const_pointer s) const noexcept
  4290. {
  4291. const size_type len = traits_type::length(s);
  4292. return size() >= len && !traits_type::compare(data(), s, len);
  4293. }
  4294. /** Return whether the string ends with a string.
  4295. Returns `true` if the string ends with `s`, and `false` otherwise.
  4296. @par Complexity
  4297. Linear.
  4298. @param t The string view to check for.
  4299. */
  4300. template<typename T
  4301. #ifndef BOOST_STATIC_STRING_DOCS
  4302. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4303. #endif
  4304. >
  4305. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4306. bool
  4307. ends_with(
  4308. T const& t) const noexcept
  4309. {
  4310. detail::common_string_view_type<T, CharT, Traits> sv = t;
  4311. const size_type len = sv.size();
  4312. return size() >= len && !traits_type::compare(data() + (size() - len), sv.data(), len);
  4313. }
  4314. /** Return whether the string ends with a character.
  4315. Returns `true` if the string ends with `c`, and `false` otherwise.
  4316. @par Complexity
  4317. Constant.
  4318. @param c The character to check for.
  4319. */
  4320. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4321. bool
  4322. ends_with(
  4323. value_type c) const noexcept
  4324. {
  4325. return !empty() && traits_type::eq(back(), c);
  4326. }
  4327. /** Return whether the string ends with a string.
  4328. Returns `true` if the string ends with the string
  4329. pointed to be `s` of length `traits_type::length(s)`,
  4330. and `false` otherwise.
  4331. @par Complexity
  4332. Linear.
  4333. @param s The string to check for.
  4334. */
  4335. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4336. bool
  4337. ends_with(
  4338. const_pointer s) const noexcept
  4339. {
  4340. const size_type len = traits_type::length(s);
  4341. return size() >= len && !traits_type::compare(data() + (size() - len), s, len);
  4342. }
  4343. private:
  4344. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4345. basic_static_string&
  4346. term() noexcept
  4347. {
  4348. this->term_impl();
  4349. return *this;
  4350. }
  4351. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4352. basic_static_string&
  4353. assign_char(value_type ch, std::true_type) noexcept
  4354. {
  4355. this->set_size(1);
  4356. traits_type::assign(data()[0], ch);
  4357. return term();
  4358. }
  4359. BOOST_STATIC_STRING_NORETURN
  4360. basic_static_string&
  4361. assign_char(value_type, std::false_type)
  4362. {
  4363. detail::throw_exception<std::length_error>("max_size() == 0");
  4364. // This eliminates any potential warnings
  4365. #ifdef BOOST_STATIC_STRING_NO_NORETURN
  4366. return *this;
  4367. #endif
  4368. }
  4369. // Returns the size of data read from input iterator. Read data begins at data() + size() + 1.
  4370. template<typename InputIterator>
  4371. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4372. size_type
  4373. read_back(
  4374. bool overwrite_null,
  4375. InputIterator first,
  4376. InputIterator last);
  4377. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4378. basic_static_string&
  4379. replace_unchecked(
  4380. size_type pos,
  4381. size_type n1,
  4382. const_pointer s,
  4383. size_type n2)
  4384. {
  4385. if (pos > size())
  4386. detail::throw_exception<std::out_of_range>(
  4387. "pos > size()");
  4388. return replace_unchecked(data() + pos, data() + pos + capped_length(pos, n1), s, n2);
  4389. }
  4390. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4391. basic_static_string&
  4392. replace_unchecked(
  4393. const_iterator i1,
  4394. const_iterator i2,
  4395. const_pointer s,
  4396. size_type n2);
  4397. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4398. basic_static_string&
  4399. insert_unchecked(
  4400. size_type index,
  4401. const_pointer s,
  4402. size_type count)
  4403. {
  4404. if (index > size())
  4405. detail::throw_exception<std::out_of_range>(
  4406. "index > size()");
  4407. insert_unchecked(data() + index, s, count);
  4408. return *this;
  4409. }
  4410. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4411. iterator
  4412. insert_unchecked(
  4413. const_iterator pos,
  4414. const_pointer s,
  4415. size_type count);
  4416. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4417. basic_static_string&
  4418. assign_unchecked(
  4419. const_pointer s,
  4420. size_type count) noexcept
  4421. {
  4422. this->set_size(count);
  4423. traits_type::copy(data(), s, size() + 1);
  4424. return *this;
  4425. }
  4426. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4427. size_type
  4428. capped_length(
  4429. size_type index,
  4430. size_type length) const
  4431. {
  4432. if (index > size())
  4433. detail::throw_exception<std::out_of_range>(
  4434. "index > size()");
  4435. return (std::min)(size() - index, length);
  4436. }
  4437. };
  4438. //------------------------------------------------------------------------------
  4439. //
  4440. // Non-member functions
  4441. //
  4442. //------------------------------------------------------------------------------
  4443. template<
  4444. std::size_t N, std::size_t M,
  4445. typename CharT, typename Traits>
  4446. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4447. inline
  4448. bool
  4449. operator==(
  4450. const basic_static_string<N, CharT, Traits>& lhs,
  4451. const basic_static_string<M, CharT, Traits>& rhs)
  4452. {
  4453. return lhs.compare(rhs) == 0;
  4454. }
  4455. template<
  4456. std::size_t N, std::size_t M,
  4457. typename CharT, typename Traits>
  4458. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4459. inline
  4460. bool
  4461. operator!=(
  4462. const basic_static_string<N, CharT, Traits>& lhs,
  4463. const basic_static_string<M, CharT, Traits>& rhs)
  4464. {
  4465. return lhs.compare(rhs) != 0;
  4466. }
  4467. template<
  4468. std::size_t N, std::size_t M,
  4469. typename CharT, typename Traits>
  4470. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4471. inline
  4472. bool
  4473. operator<(
  4474. const basic_static_string<N, CharT, Traits>& lhs,
  4475. const basic_static_string<M, CharT, Traits>& rhs)
  4476. {
  4477. return lhs.compare(rhs) < 0;
  4478. }
  4479. template<
  4480. std::size_t N, std::size_t M,
  4481. typename CharT, typename Traits>
  4482. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4483. inline
  4484. bool
  4485. operator<=(
  4486. const basic_static_string<N, CharT, Traits>& lhs,
  4487. const basic_static_string<M, CharT, Traits>& rhs)
  4488. {
  4489. return lhs.compare(rhs) <= 0;
  4490. }
  4491. template<
  4492. std::size_t N, std::size_t M,
  4493. typename CharT, typename Traits>
  4494. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4495. inline
  4496. bool
  4497. operator>(
  4498. const basic_static_string<N, CharT, Traits>& lhs,
  4499. const basic_static_string<M, CharT, Traits>& rhs)
  4500. {
  4501. return lhs.compare(rhs) > 0;
  4502. }
  4503. template<
  4504. std::size_t N, std::size_t M,
  4505. typename CharT, typename Traits>
  4506. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4507. inline
  4508. bool
  4509. operator>=(
  4510. const basic_static_string<N, CharT, Traits>& lhs,
  4511. const basic_static_string<M, CharT, Traits>& rhs)
  4512. {
  4513. return lhs.compare(rhs) >= 0;
  4514. }
  4515. template<std::size_t N, typename CharT, typename Traits>
  4516. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4517. inline
  4518. bool
  4519. operator==(
  4520. const CharT* lhs,
  4521. const basic_static_string<N, CharT, Traits>& rhs)
  4522. {
  4523. return detail::lexicographical_compare<CharT, Traits>(
  4524. lhs, Traits::length(lhs),
  4525. rhs.data(), rhs.size()) == 0;
  4526. }
  4527. template<std::size_t N, typename CharT, typename Traits>
  4528. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4529. inline
  4530. bool
  4531. operator==(
  4532. const basic_static_string<N, CharT, Traits>& lhs,
  4533. const CharT* rhs)
  4534. {
  4535. return detail::lexicographical_compare<CharT, Traits>(
  4536. lhs.data(), lhs.size(),
  4537. rhs, Traits::length(rhs)) == 0;
  4538. }
  4539. template<std::size_t N, typename CharT, typename Traits, class T
  4540. #ifndef BOOST_STATIC_STRING_DOCS
  4541. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4542. #endif
  4543. >
  4544. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4545. inline
  4546. bool
  4547. operator==(
  4548. const T& lhs,
  4549. const basic_static_string<N, CharT, Traits>& rhs)
  4550. {
  4551. detail::common_string_view_type<T, CharT, Traits> lhsv = lhs;
  4552. return detail::lexicographical_compare<CharT, Traits>(
  4553. lhsv.data(), lhsv.size(),
  4554. rhs.data(), rhs.size()) == 0;
  4555. }
  4556. template<std::size_t N, typename CharT, typename Traits, class T
  4557. #ifndef BOOST_STATIC_STRING_DOCS
  4558. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4559. #endif
  4560. >
  4561. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4562. inline
  4563. bool
  4564. operator==(
  4565. const basic_static_string<N, CharT, Traits>& lhs,
  4566. const T& rhs)
  4567. {
  4568. detail::common_string_view_type<T, CharT, Traits> rhsv = rhs;
  4569. return detail::lexicographical_compare<CharT, Traits>(
  4570. lhs.data(), lhs.size(),
  4571. rhsv.data(), rhsv.size()) == 0;
  4572. }
  4573. template<std::size_t N, typename CharT, typename Traits>
  4574. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4575. inline
  4576. bool
  4577. operator!=(
  4578. const CharT* lhs,
  4579. const basic_static_string<N, CharT, Traits>& rhs)
  4580. {
  4581. return detail::lexicographical_compare<CharT, Traits>(
  4582. lhs, Traits::length(lhs),
  4583. rhs.data(), rhs.size()) != 0;
  4584. }
  4585. template<std::size_t N, typename CharT, typename Traits>
  4586. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4587. inline
  4588. bool
  4589. operator!=(
  4590. const basic_static_string<N, CharT, Traits>& lhs,
  4591. const CharT* rhs)
  4592. {
  4593. return detail::lexicographical_compare<CharT, Traits>(
  4594. lhs.data(), lhs.size(),
  4595. rhs, Traits::length(rhs)) != 0;
  4596. }
  4597. template<std::size_t N, typename CharT, typename Traits, class T
  4598. #ifndef BOOST_STATIC_STRING_DOCS
  4599. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4600. #endif
  4601. >
  4602. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4603. inline
  4604. bool
  4605. operator!=(
  4606. const T& lhs,
  4607. const basic_static_string<N, CharT, Traits>& rhs)
  4608. {
  4609. detail::common_string_view_type<T, CharT, Traits> lhsv = lhs;
  4610. return detail::lexicographical_compare<CharT, Traits>(
  4611. lhsv.data(), lhsv.size(),
  4612. rhs.data(), rhs.size()) != 0;
  4613. }
  4614. template<std::size_t N, typename CharT, typename Traits, class T
  4615. #ifndef BOOST_STATIC_STRING_DOCS
  4616. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4617. #endif
  4618. >
  4619. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4620. inline
  4621. bool
  4622. operator!=(
  4623. const basic_static_string<N, CharT, Traits>& lhs,
  4624. const T& rhs)
  4625. {
  4626. detail::common_string_view_type<T, CharT, Traits> rhsv = rhs;
  4627. return detail::lexicographical_compare<CharT, Traits>(
  4628. lhs.data(), lhs.size(),
  4629. rhsv.data(), rhsv.size()) != 0;
  4630. }
  4631. template<std::size_t N, typename CharT, typename Traits>
  4632. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4633. inline
  4634. bool
  4635. operator<(
  4636. const CharT* lhs,
  4637. const basic_static_string<N, CharT, Traits>& rhs)
  4638. {
  4639. return detail::lexicographical_compare<CharT, Traits>(
  4640. lhs, Traits::length(lhs),
  4641. rhs.data(), rhs.size()) < 0;
  4642. }
  4643. template<std::size_t N, typename CharT, typename Traits>
  4644. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4645. inline
  4646. bool
  4647. operator<(
  4648. const basic_static_string<N, CharT, Traits>& lhs,
  4649. const CharT* rhs)
  4650. {
  4651. return detail::lexicographical_compare<CharT, Traits>(
  4652. lhs.data(), lhs.size(),
  4653. rhs, Traits::length(rhs)) < 0;
  4654. }
  4655. template<std::size_t N, typename CharT, typename Traits, class T
  4656. #ifndef BOOST_STATIC_STRING_DOCS
  4657. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4658. #endif
  4659. >
  4660. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4661. inline
  4662. bool
  4663. operator<(
  4664. const T& lhs,
  4665. const basic_static_string<N, CharT, Traits>& rhs)
  4666. {
  4667. detail::common_string_view_type<T, CharT, Traits> lhsv = lhs;
  4668. return detail::lexicographical_compare<CharT, Traits>(
  4669. lhsv.data(), lhsv.size(),
  4670. rhs.data(), rhs.size()) < 0;
  4671. }
  4672. template<std::size_t N, typename CharT, typename Traits, class T
  4673. #ifndef BOOST_STATIC_STRING_DOCS
  4674. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4675. #endif
  4676. >
  4677. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4678. inline
  4679. bool
  4680. operator<(
  4681. const basic_static_string<N, CharT, Traits>& lhs,
  4682. const T& rhs)
  4683. {
  4684. detail::common_string_view_type<T, CharT, Traits> rhsv = rhs;
  4685. return detail::lexicographical_compare<CharT, Traits>(
  4686. lhs.data(), lhs.size(),
  4687. rhsv.data(), rhsv.size()) < 0;
  4688. }
  4689. template<std::size_t N, typename CharT, typename Traits>
  4690. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4691. inline
  4692. bool
  4693. operator<=(
  4694. const CharT* lhs,
  4695. const basic_static_string<N, CharT, Traits>& rhs)
  4696. {
  4697. return detail::lexicographical_compare<CharT, Traits>(
  4698. lhs, Traits::length(lhs),
  4699. rhs.data(), rhs.size()) <= 0;
  4700. }
  4701. template<std::size_t N, typename CharT, typename Traits>
  4702. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4703. inline
  4704. bool
  4705. operator<=(
  4706. const basic_static_string<N, CharT, Traits>& lhs,
  4707. const CharT* rhs)
  4708. {
  4709. return detail::lexicographical_compare<CharT, Traits>(
  4710. lhs.data(), lhs.size(),
  4711. rhs, Traits::length(rhs)) <= 0;
  4712. }
  4713. template<std::size_t N, typename CharT, typename Traits, class T
  4714. #ifndef BOOST_STATIC_STRING_DOCS
  4715. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4716. #endif
  4717. >
  4718. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4719. inline
  4720. bool
  4721. operator<=(
  4722. const T& lhs,
  4723. const basic_static_string<N, CharT, Traits>& rhs)
  4724. {
  4725. detail::common_string_view_type<T, CharT, Traits> lhsv = lhs;
  4726. return detail::lexicographical_compare<CharT, Traits>(
  4727. lhsv.data(), lhsv.size(),
  4728. rhs.data(), rhs.size()) <= 0;
  4729. }
  4730. template<std::size_t N, typename CharT, typename Traits, class T
  4731. #ifndef BOOST_STATIC_STRING_DOCS
  4732. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4733. #endif
  4734. >
  4735. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4736. inline
  4737. bool
  4738. operator<=(
  4739. const basic_static_string<N, CharT, Traits>& lhs,
  4740. const T& rhs)
  4741. {
  4742. detail::common_string_view_type<T, CharT, Traits> rhsv = rhs;
  4743. return detail::lexicographical_compare<CharT, Traits>(
  4744. lhs.data(), lhs.size(),
  4745. rhsv.data(), rhsv.size()) <= 0;
  4746. }
  4747. template<std::size_t N, typename CharT, typename Traits>
  4748. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4749. inline
  4750. bool
  4751. operator>(
  4752. const CharT* lhs,
  4753. const basic_static_string<N, CharT, Traits>& rhs)
  4754. {
  4755. return detail::lexicographical_compare<CharT, Traits>(
  4756. lhs, Traits::length(lhs),
  4757. rhs.data(), rhs.size()) > 0;
  4758. }
  4759. template<std::size_t N, typename CharT, typename Traits>
  4760. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4761. inline
  4762. bool
  4763. operator>(
  4764. const basic_static_string<N, CharT, Traits>& lhs,
  4765. const CharT* rhs)
  4766. {
  4767. return detail::lexicographical_compare<CharT, Traits>(
  4768. lhs.data(), lhs.size(),
  4769. rhs, Traits::length(rhs)) > 0;
  4770. }
  4771. template<std::size_t N, typename CharT, typename Traits, class T
  4772. #ifndef BOOST_STATIC_STRING_DOCS
  4773. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4774. #endif
  4775. >
  4776. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4777. inline
  4778. bool
  4779. operator>(
  4780. const T& lhs,
  4781. const basic_static_string<N, CharT, Traits>& rhs)
  4782. {
  4783. detail::common_string_view_type<T, CharT, Traits> lhsv = lhs;
  4784. return detail::lexicographical_compare<CharT, Traits>(
  4785. lhsv.data(), lhsv.size(),
  4786. rhs.data(), rhs.size()) > 0;
  4787. }
  4788. template<std::size_t N, typename CharT, typename Traits, class T
  4789. #ifndef BOOST_STATIC_STRING_DOCS
  4790. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4791. #endif
  4792. >
  4793. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4794. inline
  4795. bool
  4796. operator>(
  4797. const basic_static_string<N, CharT, Traits>& lhs,
  4798. const T& rhs)
  4799. {
  4800. detail::common_string_view_type<T, CharT, Traits> rhsv = rhs;
  4801. return detail::lexicographical_compare<CharT, Traits>(
  4802. lhs.data(), lhs.size(),
  4803. rhsv.data(), rhsv.size()) > 0;
  4804. }
  4805. template<std::size_t N, typename CharT, typename Traits>
  4806. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4807. inline
  4808. bool
  4809. operator>=(
  4810. const CharT* lhs,
  4811. const basic_static_string<N, CharT, Traits>& rhs)
  4812. {
  4813. return detail::lexicographical_compare<CharT, Traits>(
  4814. lhs, Traits::length(lhs),
  4815. rhs.data(), rhs.size()) >= 0;
  4816. }
  4817. template<std::size_t N, typename CharT, typename Traits>
  4818. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4819. inline
  4820. bool
  4821. operator>=(
  4822. const basic_static_string<N, CharT, Traits>& lhs,
  4823. const CharT* rhs)
  4824. {
  4825. return detail::lexicographical_compare<CharT, Traits>(
  4826. lhs.data(), lhs.size(),
  4827. rhs, Traits::length(rhs)) >= 0;
  4828. }
  4829. template<std::size_t N, typename CharT, typename Traits, class T
  4830. #ifndef BOOST_STATIC_STRING_DOCS
  4831. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4832. #endif
  4833. >
  4834. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4835. inline
  4836. bool
  4837. operator>=(
  4838. const T& lhs,
  4839. const basic_static_string<N, CharT, Traits>& rhs)
  4840. {
  4841. detail::common_string_view_type<T, CharT, Traits> lhsv = lhs;
  4842. return detail::lexicographical_compare<CharT, Traits>(
  4843. lhsv.data(), lhsv.size(),
  4844. rhs.data(), rhs.size()) >= 0;
  4845. }
  4846. template<std::size_t N, typename CharT, typename Traits, class T
  4847. #ifndef BOOST_STATIC_STRING_DOCS
  4848. , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
  4849. #endif
  4850. >
  4851. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4852. inline
  4853. bool
  4854. operator>=(
  4855. const basic_static_string<N, CharT, Traits>& lhs,
  4856. const T& rhs)
  4857. {
  4858. detail::common_string_view_type<T, CharT, Traits> rhsv = rhs;
  4859. return detail::lexicographical_compare<CharT, Traits>(
  4860. lhs.data(), lhs.size(),
  4861. rhsv.data(), rhsv.size()) >= 0;
  4862. }
  4863. template<
  4864. std::size_t N, std::size_t M,
  4865. typename CharT, typename Traits>
  4866. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4867. inline
  4868. basic_static_string<N + M, CharT, Traits>
  4869. operator+(
  4870. const basic_static_string<N, CharT, Traits>& lhs,
  4871. const basic_static_string<M, CharT, Traits>& rhs)
  4872. {
  4873. return basic_static_string<N + M, CharT, Traits>(lhs) += rhs;
  4874. }
  4875. template<std::size_t N, typename CharT, typename Traits>
  4876. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4877. inline
  4878. basic_static_string<N + 1, CharT, Traits>
  4879. operator+(
  4880. const basic_static_string<N, CharT, Traits>& lhs,
  4881. CharT rhs)
  4882. {
  4883. return basic_static_string<N + 1, CharT, Traits>(lhs) += rhs;
  4884. }
  4885. template<std::size_t N, typename CharT, typename Traits>
  4886. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4887. inline
  4888. basic_static_string<N + 1, CharT, Traits>
  4889. operator+(
  4890. CharT lhs,
  4891. const basic_static_string<N, CharT, Traits>& rhs)
  4892. {
  4893. // The cast to std::size_t is needed here since 0 is a null pointer constant
  4894. return basic_static_string<N + 1, CharT, Traits>(rhs).insert(
  4895. std::size_t(0), 1, lhs);
  4896. }
  4897. // Add a null terminated character array to a string.
  4898. template<
  4899. std::size_t N, std::size_t M,
  4900. typename CharT, typename Traits>
  4901. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4902. inline
  4903. basic_static_string<N + M, CharT, Traits>
  4904. operator+(
  4905. const basic_static_string<N, CharT, Traits>& lhs,
  4906. const CharT(&rhs)[M])
  4907. {
  4908. return basic_static_string<N + M, CharT, Traits>(lhs).append(+rhs);
  4909. }
  4910. // Add a string to a null terminated character array.
  4911. template<
  4912. std::size_t N, std::size_t M,
  4913. typename CharT, typename Traits>
  4914. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4915. inline
  4916. basic_static_string<N + M, CharT, Traits>
  4917. operator+(
  4918. const CharT(&lhs)[N],
  4919. const basic_static_string<M, CharT, Traits>& rhs)
  4920. {
  4921. // The cast to std::size_t is needed here since 0 is a null pointer constant
  4922. return basic_static_string<N + M, CharT, Traits>(rhs).insert(
  4923. std::size_t(0), +lhs);
  4924. }
  4925. //------------------------------------------------------------------------------
  4926. //
  4927. // erase_if
  4928. //
  4929. //------------------------------------------------------------------------------
  4930. template<
  4931. std::size_t N, typename CharT,
  4932. typename Traits, typename UnaryPredicate>
  4933. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4934. typename
  4935. basic_static_string<N, CharT, Traits>::size_type
  4936. erase_if(
  4937. basic_static_string<N, CharT, Traits>& str,
  4938. UnaryPredicate pred)
  4939. {
  4940. auto first = str.begin();
  4941. for (auto it = first; it != str.end(); ++it)
  4942. if (!pred(*it))
  4943. *first++ = std::move(*it);
  4944. const auto count = str.end() - first;
  4945. str.erase(first, str.end());
  4946. return count;
  4947. }
  4948. //------------------------------------------------------------------------------
  4949. //
  4950. // swap
  4951. //
  4952. //------------------------------------------------------------------------------
  4953. template<std::size_t N, typename CharT, typename Traits>
  4954. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4955. inline
  4956. void
  4957. swap(
  4958. basic_static_string<N, CharT, Traits>& lhs,
  4959. basic_static_string<N, CharT, Traits>& rhs)
  4960. {
  4961. lhs.swap(rhs);
  4962. }
  4963. template<
  4964. std::size_t N, std::size_t M,
  4965. typename CharT, typename Traits>
  4966. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  4967. inline
  4968. void
  4969. swap(
  4970. basic_static_string<N, CharT, Traits>& lhs,
  4971. basic_static_string<M, CharT, Traits>& rhs)
  4972. {
  4973. lhs.swap(rhs);
  4974. }
  4975. //------------------------------------------------------------------------------
  4976. //
  4977. // Input/Output
  4978. //
  4979. //------------------------------------------------------------------------------
  4980. template<std::size_t N, typename CharT, typename Traits>
  4981. inline
  4982. std::basic_ostream<CharT, Traits>&
  4983. operator<<(
  4984. std::basic_ostream<CharT, Traits>& os,
  4985. const basic_static_string<N, CharT, Traits>& s)
  4986. {
  4987. #ifdef BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW
  4988. return os << basic_string_view<CharT, Traits>(s.data(), s.size());
  4989. #else
  4990. for (auto c: s)
  4991. os << c;
  4992. return os;
  4993. #endif
  4994. }
  4995. //------------------------------------------------------------------------------
  4996. //
  4997. // Numeric conversions
  4998. //
  4999. //------------------------------------------------------------------------------
  5000. // Signed overloads have a + 2, one for the missing digit,
  5001. // and one for the sign.
  5002. // Unsigned overloads have a + 1, for the missing digit.
  5003. // Floating point overloads have a +8 (for float), + 8
  5004. // (for double), and +10 for long double (that accounts
  5005. // for the sign of the integral part, the missing digit,
  5006. // the decimal point, the sign of the exponent, the 'e'
  5007. // and up to two, three or five digits of exponent---float
  5008. // uses the same value as double, because we sometimes
  5009. // reuse the conversion from double for floats).
  5010. /// Converts `value` to a `static_string`
  5011. static_string<std::numeric_limits<int>::digits10 + 2>
  5012. inline
  5013. to_static_string(int value) noexcept
  5014. {
  5015. return detail::to_static_string_int_impl<
  5016. std::numeric_limits<int>::digits10 + 2>(value);
  5017. }
  5018. /// Converts `value` to a `static_string`
  5019. static_string<std::numeric_limits<long>::digits10 + 2>
  5020. inline
  5021. to_static_string(long value) noexcept
  5022. {
  5023. return detail::to_static_string_int_impl<
  5024. std::numeric_limits<long>::digits10 + 2>(value);
  5025. }
  5026. /// Converts `value` to a `static_string`
  5027. static_string<std::numeric_limits<long long>::digits10 + 2>
  5028. inline
  5029. to_static_string(long long value) noexcept
  5030. {
  5031. return detail::to_static_string_int_impl<
  5032. std::numeric_limits<long long>::digits10 + 2>(value);
  5033. }
  5034. /// Converts `value` to a `static_string`
  5035. static_string<std::numeric_limits<unsigned int>::digits10 + 1>
  5036. inline
  5037. to_static_string(unsigned int value) noexcept
  5038. {
  5039. return detail::to_static_string_int_impl<
  5040. std::numeric_limits<unsigned int>::digits10 + 1>(value);
  5041. }
  5042. /// Converts `value` to a `static_string`
  5043. static_string<std::numeric_limits<unsigned long>::digits10 + 1>
  5044. inline
  5045. to_static_string(unsigned long value) noexcept
  5046. {
  5047. return detail::to_static_string_int_impl<
  5048. std::numeric_limits<unsigned long>::digits10 + 1>(value);
  5049. }
  5050. /// Converts `value` to a `static_string`
  5051. static_string<std::numeric_limits<unsigned long long>::digits10 + 1>
  5052. inline
  5053. to_static_string(unsigned long long value) noexcept
  5054. {
  5055. return detail::to_static_string_int_impl<
  5056. std::numeric_limits<unsigned long long>::digits10 + 1>(value);
  5057. }
  5058. /// Converts `value` to a `static_string`
  5059. static_string<std::numeric_limits<float>::max_digits10 + 8>
  5060. inline
  5061. to_static_string(float value) noexcept
  5062. {
  5063. return detail::to_static_string_float_impl<
  5064. std::numeric_limits<float>::max_digits10 + 8>(value);
  5065. }
  5066. /// Converts `value` to a `static_string`
  5067. static_string<std::numeric_limits<double>::max_digits10 + 8>
  5068. inline
  5069. to_static_string(double value) noexcept
  5070. {
  5071. return detail::to_static_string_float_impl<
  5072. std::numeric_limits<double>::max_digits10 + 8>(value);
  5073. }
  5074. /// Converts `value` to a `static_string`
  5075. static_string<std::numeric_limits<long double>::max_digits10 + 10>
  5076. inline
  5077. to_static_string(long double value) noexcept
  5078. {
  5079. return detail::to_static_string_float_impl<
  5080. std::numeric_limits<long double>::max_digits10 + 10>(value);
  5081. }
  5082. #ifdef BOOST_STATIC_STRING_HAS_WCHAR
  5083. /// Converts `value` to a `static_wstring`
  5084. static_wstring<std::numeric_limits<int>::digits10 + 2>
  5085. inline
  5086. to_static_wstring(int value) noexcept
  5087. {
  5088. return detail::to_static_wstring_int_impl<
  5089. std::numeric_limits<int>::digits10 + 2>(value);
  5090. }
  5091. /// Converts `value` to a `static_wstring`
  5092. static_wstring<std::numeric_limits<long>::digits10 + 2>
  5093. inline
  5094. to_static_wstring(long value) noexcept
  5095. {
  5096. return detail::to_static_wstring_int_impl<
  5097. std::numeric_limits<long>::digits10 + 2>(value);
  5098. }
  5099. /// Converts `value` to a `static_wstring`
  5100. static_wstring<std::numeric_limits<long long>::digits10 + 2>
  5101. inline
  5102. to_static_wstring(long long value) noexcept
  5103. {
  5104. return detail::to_static_wstring_int_impl<
  5105. std::numeric_limits<long long>::digits10 + 2>(value);
  5106. }
  5107. /// Converts `value` to a `static_wstring`
  5108. static_wstring<std::numeric_limits<unsigned int>::digits10 + 1>
  5109. inline
  5110. to_static_wstring(unsigned int value) noexcept
  5111. {
  5112. return detail::to_static_wstring_int_impl<
  5113. std::numeric_limits<unsigned int>::digits10 + 1>(value);
  5114. }
  5115. /// Converts `value` to a `static_wstring`
  5116. static_wstring<std::numeric_limits<unsigned long>::digits10 + 1>
  5117. inline
  5118. to_static_wstring(unsigned long value) noexcept
  5119. {
  5120. return detail::to_static_wstring_int_impl<
  5121. std::numeric_limits<unsigned long>::digits10 + 1>(value);
  5122. }
  5123. /// Converts `value` to a `static_wstring`
  5124. static_wstring<std::numeric_limits<unsigned long long>::digits10 + 1>
  5125. inline
  5126. to_static_wstring(unsigned long long value) noexcept
  5127. {
  5128. return detail::to_static_wstring_int_impl<
  5129. std::numeric_limits<unsigned long long>::digits10 + 1>(value);
  5130. }
  5131. /// Converts `value` to a `static_wstring`
  5132. static_wstring<std::numeric_limits<float>::max_digits10 + 8>
  5133. inline
  5134. to_static_wstring(float value) noexcept
  5135. {
  5136. return detail::to_static_wstring_float_impl<
  5137. std::numeric_limits<float>::max_digits10 + 8>(value);
  5138. }
  5139. /// Converts `value` to a `static_wstring`
  5140. static_wstring<std::numeric_limits<double>::max_digits10 + 8>
  5141. inline
  5142. to_static_wstring(double value) noexcept
  5143. {
  5144. return detail::to_static_wstring_float_impl<
  5145. std::numeric_limits<double>::max_digits10 + 8>(value);
  5146. }
  5147. /// Converts `value` to a `static_wstring`
  5148. static_wstring<std::numeric_limits<long double>::max_digits10 + 10>
  5149. inline
  5150. to_static_wstring(long double value) noexcept
  5151. {
  5152. return detail::to_static_wstring_float_impl<
  5153. std::numeric_limits<long double>::max_digits10 + 10>(value);
  5154. }
  5155. #endif
  5156. //------------------------------------------------------------------------------
  5157. //
  5158. // Deduction Guides
  5159. //
  5160. //------------------------------------------------------------------------------
  5161. #ifdef BOOST_STATIC_STRING_USE_DEDUCT
  5162. template<std::size_t N, typename CharT>
  5163. basic_static_string(const CharT(&)[N]) ->
  5164. basic_static_string<N, CharT, std::char_traits<CharT>>;
  5165. #endif
  5166. //------------------------------------------------------------------------------
  5167. //
  5168. // Hashing
  5169. //
  5170. //------------------------------------------------------------------------------
  5171. #ifndef BOOST_STATIC_STRING_STANDALONE
  5172. /// hash_value overload for Boost.Container_Hash
  5173. template <std::size_t N,
  5174. typename CharT,
  5175. typename Traits>
  5176. std::size_t
  5177. hash_value(
  5178. const basic_static_string<N, CharT, Traits>& str)
  5179. {
  5180. return boost::hash_range(str.begin(), str.end());
  5181. }
  5182. #endif
  5183. } // static_strings
  5184. //------------------------------------------------------------------------------
  5185. //
  5186. // using Declarations
  5187. //
  5188. //------------------------------------------------------------------------------
  5189. using static_strings::static_string;
  5190. #ifdef BOOST_STATIC_STRING_HAS_WCHAR
  5191. using static_strings::static_wstring;
  5192. #endif
  5193. using static_strings::static_u16string;
  5194. using static_strings::static_u32string;
  5195. } // boost
  5196. /// std::hash partial specialization for basic_static_string
  5197. namespace std {
  5198. template<std::size_t N, typename CharT, typename Traits>
  5199. struct hash<
  5200. #ifdef BOOST_STATIC_STRING_DOCS
  5201. basic_static_string
  5202. #else
  5203. boost::static_strings::basic_static_string<N, CharT, Traits>
  5204. #endif
  5205. >
  5206. {
  5207. std::size_t
  5208. operator()(
  5209. const boost::static_strings::basic_static_string<N, CharT, Traits>& str) const noexcept
  5210. {
  5211. #if !defined(BOOST_STATIC_STRING_STANDALONE)
  5212. return boost::hash_range(str.begin(), str.end());
  5213. #elif defined(BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW)
  5214. using view_type = typename
  5215. boost::static_strings::basic_string_view<CharT, Traits>;
  5216. return std::hash<view_type>()(view_type(str.data(), str.size()));
  5217. #else
  5218. std::size_t seed = 0;
  5219. for (CharT const& c : str)
  5220. {
  5221. #if BOOST_STATIC_STRING_ARCH == 64
  5222. seed += 0x9e3779b9 + std::hash<CharT>()( c );
  5223. std::size_t const m = (std::size_t(0xe9846af) << 32) + 0x9b1a615d;
  5224. seed ^= seed >> 32;
  5225. seed *= m;
  5226. seed ^= seed >> 32;
  5227. seed *= m;
  5228. seed ^= seed >> 28;
  5229. #elif BOOST_STATIC_STRING_ARCH == 32
  5230. seed += 0x9e3779b9 + std::hash<CharT>()( c );
  5231. std::size_t const m1 = 0x21f0aaad;
  5232. std::size_t const m2 = 0x735a2d97;
  5233. seed ^= seed >> 16;
  5234. seed *= m1;
  5235. seed ^= seed >> 15;
  5236. seed *= m2;
  5237. seed ^= seed >> 15;
  5238. #endif
  5239. }
  5240. return seed;
  5241. #endif
  5242. }
  5243. };
  5244. } // std
  5245. //--------------------------------------------------------------------------
  5246. //
  5247. // Implementation
  5248. //
  5249. //--------------------------------------------------------------------------
  5250. #ifndef BOOST_STATIC_STRING_DOCS
  5251. namespace boost {
  5252. namespace static_strings {
  5253. template<std::size_t N, typename CharT, typename Traits>
  5254. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5255. auto
  5256. basic_static_string<N, CharT, Traits>::
  5257. assign(
  5258. size_type count,
  5259. value_type ch) ->
  5260. basic_static_string&
  5261. {
  5262. if (count > max_size())
  5263. detail::throw_exception<std::length_error>(
  5264. "count > max_size()");
  5265. this->set_size(count);
  5266. traits_type::assign(data(), size(), ch);
  5267. return term();
  5268. }
  5269. template<std::size_t N, typename CharT, typename Traits>
  5270. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5271. auto
  5272. basic_static_string<N, CharT, Traits>::
  5273. assign(
  5274. const_pointer s,
  5275. size_type count) ->
  5276. basic_static_string&
  5277. {
  5278. if (count > max_size())
  5279. detail::throw_exception<std::length_error>(
  5280. "count > max_size()");
  5281. this->set_size(count);
  5282. traits_type::move(data(), s, size());
  5283. return term();
  5284. }
  5285. template<std::size_t N, typename CharT, typename Traits>
  5286. template<typename InputIterator>
  5287. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5288. auto
  5289. basic_static_string<N, CharT, Traits>::
  5290. assign(
  5291. InputIterator first,
  5292. InputIterator last) ->
  5293. typename std::enable_if<
  5294. detail::is_input_iterator<InputIterator>::value,
  5295. basic_static_string&>::type
  5296. {
  5297. auto ptr = data();
  5298. for (std::size_t i = 0; first != last; ++first, ++ptr, ++i)
  5299. {
  5300. if (i >= max_size())
  5301. {
  5302. this->set_size(i);
  5303. term();
  5304. detail::throw_exception<std::length_error>("n > max_size()");
  5305. }
  5306. traits_type::assign(*ptr, *first);
  5307. }
  5308. this->set_size(ptr - data());
  5309. return term();
  5310. }
  5311. template<std::size_t N, typename CharT, typename Traits>
  5312. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5313. auto
  5314. basic_static_string<N, CharT, Traits>::
  5315. insert(
  5316. const_iterator pos,
  5317. size_type count,
  5318. value_type ch) ->
  5319. iterator
  5320. {
  5321. const auto curr_size = size();
  5322. const auto curr_data = data();
  5323. if (count > max_size() - curr_size)
  5324. detail::throw_exception<std::length_error>(
  5325. "count > max_size() - curr_size");
  5326. const auto index = pos - curr_data;
  5327. traits_type::move(&curr_data[index + count], &curr_data[index], curr_size - index + 1);
  5328. traits_type::assign(&curr_data[index], count, ch);
  5329. this->set_size(curr_size + count);
  5330. return &curr_data[index];
  5331. }
  5332. template<std::size_t N, typename CharT, typename Traits>
  5333. template<typename ForwardIterator>
  5334. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5335. auto
  5336. basic_static_string<N, CharT, Traits>::
  5337. insert(
  5338. const_iterator pos,
  5339. ForwardIterator first,
  5340. ForwardIterator last) ->
  5341. typename std::enable_if<
  5342. detail::is_forward_iterator<
  5343. ForwardIterator>::value, iterator>::type
  5344. {
  5345. // input
  5346. const std::size_t count = detail::distance(first, last);
  5347. const auto first_addr = &*first;
  5348. const auto last_addr = first_addr + count;
  5349. // output
  5350. const auto curr_size = size();
  5351. const auto curr_data = data();
  5352. const std::size_t index = pos - curr_data;
  5353. auto dest = &curr_data[index];
  5354. if (count > max_size() - curr_size)
  5355. detail::throw_exception<std::length_error>(
  5356. "count > max_size() - curr_size");
  5357. traits_type::move(dest + count, dest, curr_size - index + 1);
  5358. const bool inside = detail::ptr_in_range(curr_data, curr_data + curr_size, first_addr);
  5359. if (!inside || last_addr <= pos)
  5360. {
  5361. detail::copy_with_traits<Traits>(first, last, dest);
  5362. }
  5363. else /* if (inside) */
  5364. {
  5365. const size_type offset = first_addr - curr_data;
  5366. if (offset < index)
  5367. {
  5368. const size_type diff = index - offset;
  5369. traits_type::copy(dest, &curr_data[offset], diff);
  5370. traits_type::copy(&curr_data[index + diff], dest + count, count - diff);
  5371. }
  5372. else
  5373. {
  5374. auto src = &curr_data[offset + count];
  5375. traits_type::copy(dest, src, count);
  5376. }
  5377. }
  5378. this->set_size(curr_size + count);
  5379. return curr_data + index;
  5380. }
  5381. template<std::size_t N, typename CharT, typename Traits>
  5382. template<typename InputIterator>
  5383. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5384. auto
  5385. basic_static_string<N, CharT, Traits>::
  5386. insert(
  5387. const_iterator pos,
  5388. InputIterator first,
  5389. InputIterator last) ->
  5390. typename std::enable_if<
  5391. detail::is_input_iterator<
  5392. InputIterator>::value &&
  5393. !detail::is_forward_iterator<
  5394. InputIterator>::value, iterator>::type
  5395. {
  5396. const auto curr_size = size();
  5397. const auto curr_data = data();
  5398. const auto count = read_back(false, first, last);
  5399. const std::size_t index = pos - curr_data;
  5400. std::rotate(&curr_data[index], &curr_data[curr_size + 1], &curr_data[curr_size + count + 1]);
  5401. this->set_size(curr_size + count);
  5402. return curr_data + index;
  5403. }
  5404. template<std::size_t N, typename CharT, typename Traits>
  5405. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5406. auto
  5407. basic_static_string<N, CharT, Traits>::
  5408. erase(
  5409. const_iterator first,
  5410. const_iterator last) ->
  5411. iterator
  5412. {
  5413. const auto curr_data = data();
  5414. const std::size_t index = first - curr_data;
  5415. traits_type::move(&curr_data[index], last, (end() - last) + 1);
  5416. this->set_size(size() - std::size_t(last - first));
  5417. return curr_data + index;
  5418. }
  5419. template<std::size_t N, typename CharT, typename Traits>
  5420. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5421. void
  5422. basic_static_string<N, CharT, Traits>::
  5423. push_back(
  5424. value_type ch)
  5425. {
  5426. const auto curr_size = size();
  5427. if (curr_size >= max_size())
  5428. detail::throw_exception<std::length_error>(
  5429. "curr_size >= max_size()");
  5430. traits_type::assign(data()[curr_size], ch);
  5431. this->set_size(curr_size + 1);
  5432. term();
  5433. }
  5434. template<std::size_t N, typename CharT, typename Traits>
  5435. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5436. auto
  5437. basic_static_string<N, CharT, Traits>::
  5438. append(
  5439. size_type count,
  5440. value_type ch) ->
  5441. basic_static_string&
  5442. {
  5443. const auto curr_size = size();
  5444. if (count > max_size() - curr_size)
  5445. detail::throw_exception<std::length_error>(
  5446. "count > max_size() - size()");
  5447. traits_type::assign(end(), count, ch);
  5448. this->set_size(curr_size + count);
  5449. return term();
  5450. }
  5451. template<std::size_t N, typename CharT, typename Traits>
  5452. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5453. auto
  5454. basic_static_string<N, CharT, Traits>::
  5455. append(
  5456. const_pointer s,
  5457. size_type count) ->
  5458. basic_static_string&
  5459. {
  5460. const auto curr_size = size();
  5461. if (count > max_size() - curr_size)
  5462. detail::throw_exception<std::length_error>(
  5463. "count > max_size() - size()");
  5464. traits_type::copy(end(), s, count);
  5465. this->set_size(curr_size + count);
  5466. return term();
  5467. }
  5468. template<std::size_t N, typename CharT, typename Traits>
  5469. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5470. void
  5471. basic_static_string<N, CharT, Traits>::
  5472. resize(size_type n, value_type c)
  5473. {
  5474. if (n > max_size())
  5475. detail::throw_exception<std::length_error>(
  5476. "n > max_size()");
  5477. const auto curr_size = size();
  5478. if(n > curr_size)
  5479. traits_type::assign(data() + curr_size, n - curr_size, c);
  5480. this->set_size(n);
  5481. term();
  5482. }
  5483. template<std::size_t N, typename CharT, typename Traits>
  5484. template<typename Operation>
  5485. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5486. void
  5487. basic_static_string<N, CharT, Traits>::
  5488. resize_and_overwrite(
  5489. size_type n,
  5490. Operation op)
  5491. {
  5492. if (n > max_size()) {
  5493. detail::throw_exception<std::length_error>("n > max_size() in resize_and_overwrite()");
  5494. }
  5495. CharT* p = data();
  5496. const auto new_size = std::move(op)(p, n);
  5497. BOOST_STATIC_STRING_ASSERT(new_size >= 0 && size_type(new_size) <= n);
  5498. this->set_size(size_type(new_size));
  5499. term();
  5500. }
  5501. template<std::size_t N, typename CharT, typename Traits>
  5502. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5503. void
  5504. basic_static_string<N, CharT, Traits>::
  5505. swap(basic_static_string& s) noexcept
  5506. {
  5507. const auto curr_size = size();
  5508. basic_static_string tmp(s);
  5509. s.set_size(curr_size);
  5510. traits_type::copy(&s.data()[0], data(), curr_size + 1);
  5511. this->set_size(tmp.size());
  5512. traits_type::copy(data(), tmp.data(), size() + 1);
  5513. }
  5514. template<std::size_t N, typename CharT, typename Traits>
  5515. template<std::size_t M>
  5516. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5517. void
  5518. basic_static_string<N, CharT, Traits>::
  5519. swap(basic_static_string<M, CharT, Traits>& s)
  5520. {
  5521. const auto curr_size = size();
  5522. if (curr_size > s.max_size())
  5523. detail::throw_exception<std::length_error>(
  5524. "curr_size > s.max_size()");
  5525. if (s.size() > max_size())
  5526. detail::throw_exception<std::length_error>(
  5527. "s.size() > max_size()");
  5528. basic_static_string tmp(s);
  5529. s.set_size(curr_size);
  5530. traits_type::copy(&s.data()[0], data(), curr_size + 1);
  5531. this->set_size(tmp.size());
  5532. traits_type::copy(data(), &tmp.data()[0], size() + 1);
  5533. }
  5534. template<std::size_t N, typename CharT, typename Traits>
  5535. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5536. auto
  5537. basic_static_string<N, CharT, Traits>::
  5538. replace(
  5539. const_iterator i1,
  5540. const_iterator i2,
  5541. size_type n,
  5542. value_type c) ->
  5543. basic_static_string<N, CharT, Traits>&
  5544. {
  5545. const auto curr_size = size();
  5546. const auto curr_data = data();
  5547. const std::size_t n1 = i2 - i1;
  5548. if (n > max_size() || curr_size - n1 >= max_size() - n)
  5549. detail::throw_exception<std::length_error>(
  5550. "replaced string exceeds max_size()");
  5551. const auto pos = i1 - curr_data;
  5552. traits_type::move(&curr_data[pos + n], i2, (end() - i2) + 1);
  5553. traits_type::assign(&curr_data[pos], n, c);
  5554. this->set_size((curr_size - n1) + n);
  5555. return *this;
  5556. }
  5557. template<std::size_t N, typename CharT, typename Traits>
  5558. template<typename ForwardIterator>
  5559. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5560. auto
  5561. basic_static_string<N, CharT, Traits>::
  5562. replace(
  5563. const_iterator i1,
  5564. const_iterator i2,
  5565. ForwardIterator j1,
  5566. ForwardIterator j2) ->
  5567. typename std::enable_if<
  5568. detail::is_forward_iterator<ForwardIterator>::value,
  5569. basic_static_string<N, CharT, Traits>&>::type
  5570. {
  5571. const auto curr_size = size();
  5572. const auto curr_data = data();
  5573. const auto first_addr = &*j1;
  5574. const std::size_t n1 = i2 - i1;
  5575. const std::size_t n2 = detail::distance(j1, j2);
  5576. const std::size_t pos = i1 - curr_data;
  5577. if (n2 > max_size() || curr_size - (std::min)(n1, curr_size - pos) >= max_size() - n2)
  5578. detail::throw_exception<std::length_error>(
  5579. "replaced string exceeds max_size()");
  5580. const bool inside = detail::ptr_in_range(curr_data, curr_data + curr_size, first_addr);
  5581. if (inside && first_addr == i1 && n1 == n2)
  5582. return *this;
  5583. // Short circuit evaluation ensures that the pointer arithmetic is valid
  5584. if (!inside || (inside && (first_addr + n2 <= i1)))
  5585. {
  5586. // source outside
  5587. traits_type::move(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
  5588. detail::copy_with_traits<Traits>(j1, j2, &curr_data[pos]);
  5589. }
  5590. else
  5591. {
  5592. // source inside
  5593. const size_type offset = first_addr - curr_data;
  5594. if (n2 >= n1)
  5595. {
  5596. // grow/unchanged
  5597. const size_type diff = offset <= pos + n1 ? (std::min)((pos + n1) - offset, n2) : 0;
  5598. // shift all right of splice point by n2 - n1 to the right
  5599. traits_type::move(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
  5600. // copy all before splice point
  5601. traits_type::move(&curr_data[pos], &curr_data[offset], diff);
  5602. // copy all after splice point
  5603. traits_type::move(&curr_data[pos + diff], &curr_data[(offset - n1) + n2 + diff], n2 - diff);
  5604. }
  5605. else
  5606. {
  5607. // shrink
  5608. // copy all elements into place
  5609. traits_type::move(&curr_data[pos], &curr_data[offset], n2);
  5610. // shift all elements after splice point left
  5611. traits_type::move(&curr_data[pos + n2], &curr_data[pos + n1], curr_size - pos - n1 + 1);
  5612. }
  5613. }
  5614. this->set_size((curr_size - n1) + n2);
  5615. return *this;
  5616. }
  5617. template<std::size_t N, typename CharT, typename Traits>
  5618. template<typename InputIterator>
  5619. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5620. auto
  5621. basic_static_string<N, CharT, Traits>::
  5622. replace(
  5623. const_iterator i1,
  5624. const_iterator i2,
  5625. InputIterator j1,
  5626. InputIterator j2) ->
  5627. typename std::enable_if<
  5628. detail::is_input_iterator<
  5629. InputIterator>::value &&
  5630. !detail::is_forward_iterator<
  5631. InputIterator>::value,
  5632. basic_static_string<N, CharT, Traits>&>::type
  5633. {
  5634. const auto curr_size = size();
  5635. const auto curr_data = data();
  5636. const std::size_t n1 = detail::distance(i1, i2);
  5637. const std::size_t n2 = read_back(false, j1, j2);
  5638. const std::size_t pos = i1 - curr_data;
  5639. // Rotate to the correct order. [i2, end] will now start with the replaced string,
  5640. // continue to the existing string not being replaced, and end with a null terminator
  5641. std::rotate(&curr_data[pos], &curr_data[curr_size + 1], &curr_data[curr_size + n2 + 1]);
  5642. // Move everything from the end of the splice point to the end of the rotated string to
  5643. // the begining of the splice point
  5644. traits_type::move(&curr_data[pos + n2], &curr_data[pos + n2 + n1], ((curr_size - n1) + n2) - pos);
  5645. this->set_size((curr_size - n1) + n2);
  5646. return *this;
  5647. }
  5648. template<std::size_t N, typename CharT, typename Traits>
  5649. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5650. auto
  5651. basic_static_string<N, CharT, Traits>::
  5652. find(
  5653. const_pointer s,
  5654. size_type pos,
  5655. size_type n) const noexcept ->
  5656. size_type
  5657. {
  5658. const auto curr_size = size();
  5659. if (pos > curr_size || n > curr_size - pos)
  5660. return npos;
  5661. if (!n)
  5662. return pos;
  5663. const auto res = detail::search(data() + pos, data() + curr_size, s, s + n, traits_type::eq);
  5664. return res == end() ? npos : detail::distance(data(), res);
  5665. }
  5666. template<std::size_t N, typename CharT, typename Traits>
  5667. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5668. auto
  5669. basic_static_string<N, CharT, Traits>::
  5670. rfind(
  5671. const_pointer s,
  5672. size_type pos,
  5673. size_type n) const noexcept ->
  5674. size_type
  5675. {
  5676. const auto curr_size = size();
  5677. const auto curr_data = data();
  5678. if (curr_size < n)
  5679. return npos;
  5680. if (pos > curr_size - n)
  5681. pos = curr_size - n;
  5682. if (!n)
  5683. return pos;
  5684. for (auto sub = &curr_data[pos]; sub >= curr_data; --sub)
  5685. if (!traits_type::compare(sub, s, n))
  5686. return detail::distance(curr_data, sub);
  5687. return npos;
  5688. }
  5689. template<std::size_t N, typename CharT, typename Traits>
  5690. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5691. auto
  5692. basic_static_string<N, CharT, Traits>::
  5693. find_first_of(
  5694. const_pointer s,
  5695. size_type pos,
  5696. size_type n) const noexcept ->
  5697. size_type
  5698. {
  5699. const auto curr_data = data();
  5700. if (pos >= size() || !n)
  5701. return npos;
  5702. const auto res = detail::find_first_of(&curr_data[pos], &curr_data[size()], s, &s[n], traits_type::eq);
  5703. return res == end() ? npos : detail::distance(curr_data, res);
  5704. }
  5705. template<std::size_t N, typename CharT, typename Traits>
  5706. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5707. auto
  5708. basic_static_string<N, CharT, Traits>::
  5709. find_last_of(
  5710. const_pointer s,
  5711. size_type pos,
  5712. size_type n) const noexcept ->
  5713. size_type
  5714. {
  5715. const auto curr_size = size();
  5716. if (!n)
  5717. return npos;
  5718. if (pos >= curr_size)
  5719. pos = 0;
  5720. else
  5721. pos = curr_size - (pos + 1);
  5722. const auto res = detail::find_first_of(rbegin() + pos, rend(), s, &s[n], traits_type::eq);
  5723. return res == rend() ? npos : curr_size - 1 - detail::distance(rbegin(), res);
  5724. }
  5725. template<std::size_t N, typename CharT, typename Traits>
  5726. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5727. auto
  5728. basic_static_string<N, CharT, Traits>::
  5729. find_first_not_of(
  5730. const_pointer s,
  5731. size_type pos,
  5732. size_type n) const noexcept ->
  5733. size_type
  5734. {
  5735. if (pos >= size())
  5736. return npos;
  5737. if (!n)
  5738. return pos;
  5739. const auto res = detail::find_not_of<Traits>(data() + pos, data() + size(), s, n);
  5740. return res == end() ? npos : detail::distance(data(), res);
  5741. }
  5742. template<std::size_t N, typename CharT, typename Traits>
  5743. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5744. auto
  5745. basic_static_string<N, CharT, Traits>::
  5746. find_last_not_of(
  5747. const_pointer s,
  5748. size_type pos,
  5749. size_type n) const noexcept ->
  5750. size_type
  5751. {
  5752. const auto curr_size = size();
  5753. if (pos >= curr_size)
  5754. pos = curr_size - 1;
  5755. if (!n)
  5756. return pos;
  5757. pos = curr_size - (pos + 1);
  5758. const auto res = detail::find_not_of<Traits>(rbegin() + pos, rend(), s, n);
  5759. return res == rend() ? npos : curr_size - 1 - detail::distance(rbegin(), res);
  5760. }
  5761. template<std::size_t N, typename CharT, typename Traits>
  5762. template<typename InputIterator>
  5763. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5764. auto
  5765. basic_static_string<N, CharT, Traits>::
  5766. read_back(
  5767. bool overwrite_null,
  5768. InputIterator first,
  5769. InputIterator last) ->
  5770. size_type
  5771. {
  5772. const auto curr_data = data();
  5773. auto new_size = size();
  5774. for (; first != last; ++first)
  5775. {
  5776. if (new_size >= max_size())
  5777. {
  5778. // if we overwrote the null terminator,
  5779. // put it back
  5780. if (overwrite_null)
  5781. term();
  5782. detail::throw_exception<std::length_error>(
  5783. "count > max_size() - size()");
  5784. }
  5785. traits_type::assign(curr_data[new_size++ + (!overwrite_null)], *first);
  5786. }
  5787. return new_size - size();
  5788. }
  5789. template<std::size_t N, typename CharT, typename Traits>
  5790. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5791. auto
  5792. basic_static_string<N, CharT, Traits>::
  5793. replace_unchecked(
  5794. const_iterator i1,
  5795. const_iterator i2,
  5796. const_pointer s,
  5797. size_type n2) ->
  5798. basic_static_string&
  5799. {
  5800. const auto curr_data = data();
  5801. const auto curr_size = size();
  5802. const std::size_t pos = i1 - curr_data;
  5803. const std::size_t n1 = i2 - i1;
  5804. if (n2 > max_size() || curr_size - (std::min)(n1, curr_size - pos) >= max_size() - n2)
  5805. detail::throw_exception<std::length_error>(
  5806. "replaced string exceeds max_size()");
  5807. traits_type::move(&curr_data[pos + n2], i2, (end() - i2) + 1);
  5808. traits_type::copy(&curr_data[pos], s, n2);
  5809. this->set_size((curr_size - n1) + n2);
  5810. return *this;
  5811. }
  5812. template<std::size_t N, typename CharT, typename Traits>
  5813. BOOST_STATIC_STRING_CPP14_CONSTEXPR
  5814. auto
  5815. basic_static_string<N, CharT, Traits>::
  5816. insert_unchecked(
  5817. const_iterator pos,
  5818. const_pointer s,
  5819. size_type count) ->
  5820. iterator
  5821. {
  5822. const auto curr_data = data();
  5823. const auto curr_size = size();
  5824. if (count > max_size() - curr_size)
  5825. detail::throw_exception<std::length_error>(
  5826. "count > max_size() - curr_size");
  5827. const std::size_t index = pos - curr_data;
  5828. traits_type::move(&curr_data[index + count], pos, (end() - pos) + 1);
  5829. traits_type::copy(&curr_data[index], s, count);
  5830. this->set_size(curr_size + count);
  5831. return curr_data + index;
  5832. }
  5833. } // static_strings
  5834. } // boost
  5835. #if defined(__GNUC__) && __GNUC__ >= 7
  5836. #pragma GCC diagnostic pop
  5837. #endif
  5838. #if defined(__GNUC__) && __GNUC__ >= 8
  5839. #pragma GCC diagnostic pop
  5840. #endif
  5841. #endif
  5842. #endif