static_string.hpp 167 KB

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