static_string.hpp 182 KB

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