12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="generator" content="Asciidoctor 1.5.8">
- <meta name="author" content="Greg Colvin, Beman Dawes, Peter Dimov, Glen Fernandes">
- <title>Boost.SmartPtr: The Smart Pointer Library</title>
- <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
- <style>
- /* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
- /* Uncomment @import statement below to use as custom stylesheet */
- /*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
- article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
- audio,canvas,video{display:inline-block}
- audio:not([controls]){display:none;height:0}
- script{display:none!important}
- html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
- a{background:transparent}
- a:focus{outline:thin dotted}
- a:active,a:hover{outline:0}
- h1{font-size:2em;margin:.67em 0}
- abbr[title]{border-bottom:1px dotted}
- b,strong{font-weight:bold}
- dfn{font-style:italic}
- hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
- mark{background:#ff0;color:#000}
- code,kbd,pre,samp{font-family:monospace;font-size:1em}
- pre{white-space:pre-wrap}
- q{quotes:"\201C" "\201D" "\2018" "\2019"}
- small{font-size:80%}
- sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
- sup{top:-.5em}
- sub{bottom:-.25em}
- img{border:0}
- svg:not(:root){overflow:hidden}
- figure{margin:0}
- fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
- legend{border:0;padding:0}
- button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
- button,input{line-height:normal}
- button,select{text-transform:none}
- button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
- button[disabled],html input[disabled]{cursor:default}
- input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
- button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
- textarea{overflow:auto;vertical-align:top}
- table{border-collapse:collapse;border-spacing:0}
- *,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
- html,body{font-size:100%}
- body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
- a:hover{cursor:pointer}
- img,object,embed{max-width:100%;height:auto}
- object,embed{height:100%}
- img{-ms-interpolation-mode:bicubic}
- .left{float:left!important}
- .right{float:right!important}
- .text-left{text-align:left!important}
- .text-right{text-align:right!important}
- .text-center{text-align:center!important}
- .text-justify{text-align:justify!important}
- .hide{display:none}
- img,object,svg{display:inline-block;vertical-align:middle}
- textarea{height:auto;min-height:50px}
- select{width:100%}
- .center{margin-left:auto;margin-right:auto}
- .stretch{width:100%}
- .subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
- div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
- a{color:#2156a5;text-decoration:underline;line-height:inherit}
- a:hover,a:focus{color:#1d4b8f}
- a img{border:none}
- p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
- p aside{font-size:.875em;line-height:1.35;font-style:italic}
- h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
- h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
- h1{font-size:2.125em}
- h2{font-size:1.6875em}
- h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
- h4,h5{font-size:1.125em}
- h6{font-size:1em}
- hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
- em,i{font-style:italic;line-height:inherit}
- strong,b{font-weight:bold;line-height:inherit}
- small{font-size:60%;line-height:inherit}
- code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
- ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
- ul,ol{margin-left:1.5em}
- ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
- ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
- ul.square{list-style-type:square}
- ul.circle{list-style-type:circle}
- ul.disc{list-style-type:disc}
- ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
- dl dt{margin-bottom:.3125em;font-weight:bold}
- dl dd{margin-bottom:1.25em}
- abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
- abbr{text-transform:none}
- blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
- blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
- blockquote cite::before{content:"\2014 \0020"}
- blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
- blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
- @media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
- h1{font-size:2.75em}
- h2{font-size:2.3125em}
- h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
- h4{font-size:1.4375em}}
- table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
- table thead,table tfoot{background:#f7f8f7}
- table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
- table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
- table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
- table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
- h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
- h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
- .clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
- .clearfix::after,.float-group::after{clear:both}
- *:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}
- *:not(pre)>code.nobreak{word-wrap:normal}
- *:not(pre)>code.nowrap{white-space:nowrap}
- pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
- em em{font-style:normal}
- strong strong{font-weight:400}
- .keyseq{color:rgba(51,51,51,.8)}
- kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
- .keyseq kbd:first-child{margin-left:0}
- .keyseq kbd:last-child{margin-right:0}
- .menuseq,.menuref{color:#000}
- .menuseq b:not(.caret),.menuref{font-weight:inherit}
- .menuseq{word-spacing:-.02em}
- .menuseq b.caret{font-size:1.25em;line-height:.8}
- .menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
- b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
- b.button::before{content:"[";padding:0 3px 0 2px}
- b.button::after{content:"]";padding:0 2px 0 3px}
- p a>code:hover{color:rgba(0,0,0,.9)}
- #header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
- #header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
- #header::after,#content::after,#footnotes::after,#footer::after{clear:both}
- #content{margin-top:1.25em}
- #content::before{content:none}
- #header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
- #header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
- #header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
- #header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
- #header .details span:first-child{margin-left:-.125em}
- #header .details span.email a{color:rgba(0,0,0,.85)}
- #header .details br{display:none}
- #header .details br+span::before{content:"\00a0\2013\00a0"}
- #header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
- #header .details br+span#revremark::before{content:"\00a0|\00a0"}
- #header #revnumber{text-transform:capitalize}
- #header #revnumber::after{content:"\00a0"}
- #content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
- #toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
- #toc>ul{margin-left:.125em}
- #toc ul.sectlevel0>li>a{font-style:italic}
- #toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
- #toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
- #toc li{line-height:1.3334;margin-top:.3334em}
- #toc a{text-decoration:none}
- #toc a:active{text-decoration:underline}
- #toctitle{color:#7a2518;font-size:1.2em}
- @media screen and (min-width:768px){#toctitle{font-size:1.375em}
- body.toc2{padding-left:15em;padding-right:0}
- #toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
- #toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
- #toc.toc2>ul{font-size:.9em;margin-bottom:0}
- #toc.toc2 ul ul{margin-left:0;padding-left:1em}
- #toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
- body.toc2.toc-right{padding-left:0;padding-right:15em}
- body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
- @media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
- #toc.toc2{width:20em}
- #toc.toc2 #toctitle{font-size:1.375em}
- #toc.toc2>ul{font-size:.95em}
- #toc.toc2 ul ul{padding-left:1.25em}
- body.toc2.toc-right{padding-left:0;padding-right:20em}}
- #content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
- #content #toc>:first-child{margin-top:0}
- #content #toc>:last-child{margin-bottom:0}
- #footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
- #footer-text{color:rgba(255,255,255,.8);line-height:1.44}
- #content{margin-bottom:.625em}
- .sect1{padding-bottom:.625em}
- @media screen and (min-width:768px){#content{margin-bottom:1.25em}
- .sect1{padding-bottom:1.25em}}
- .sect1:last-child{padding-bottom:0}
- .sect1+.sect1{border-top:1px solid #e7e7e9}
- #content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
- #content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
- #content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
- #content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
- #content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
- .audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
- .admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
- table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
- .paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
- table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit}
- .admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
- .admonitionblock>table td.icon{text-align:center;width:80px}
- .admonitionblock>table td.icon img{max-width:none}
- .admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
- .admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6)}
- .admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
- .exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
- .exampleblock>.content>:first-child{margin-top:0}
- .exampleblock>.content>:last-child{margin-bottom:0}
- .sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
- .sidebarblock>:first-child{margin-top:0}
- .sidebarblock>:last-child{margin-bottom:0}
- .sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
- .exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
- .literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
- .sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
- .literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;overflow-x:auto;padding:1em;font-size:.8125em}
- @media screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
- @media screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
- .literalblock pre.nowrap,.literalblock pre.nowrap pre,.listingblock pre.nowrap,.listingblock pre.nowrap pre{white-space:pre;word-wrap:normal}
- .literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
- .listingblock pre.highlightjs{padding:0}
- .listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
- .listingblock pre.prettyprint{border-width:0}
- .listingblock>.content{position:relative}
- .listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
- .listingblock:hover code[data-lang]::before{display:block}
- .listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:#999}
- .listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
- table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
- table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
- table.pyhltable td.code{padding-left:.75em;padding-right:0}
- pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #dddddf}
- pre.pygments .lineno{display:inline-block;margin-right:.25em}
- table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
- .quoteblock{margin:0 1em 1.25em 1.5em;display:table}
- .quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
- .quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
- .quoteblock blockquote{margin:0;padding:0;border:0}
- .quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
- .quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
- .quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
- .verseblock{margin:0 1em 1.25em}
- .verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
- .verseblock pre strong{font-weight:400}
- .verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
- .quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
- .quoteblock .attribution br,.verseblock .attribution br{display:none}
- .quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
- .quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
- .quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
- .quoteblock.abstract{margin:0 1em 1.25em;display:block}
- .quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
- .quoteblock.excerpt,.quoteblock .quoteblock{margin:0 0 1.25em;padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
- .quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
- .quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;text-align:left;margin-right:0}
- table.tableblock{max-width:100%;border-collapse:separate}
- p.tableblock:last-child{margin-bottom:0}
- td.tableblock>.content{margin-bottom:-1.25em}
- table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
- table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}
- table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}
- table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}
- table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px}
- table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0}
- table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}
- table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0}
- table.frame-all{border-width:1px}
- table.frame-sides{border-width:0 1px}
- table.frame-topbot,table.frame-ends{border-width:1px 0}
- table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd){background:#f8f8f7}
- table.stripes-none tr,table.stripes-odd tr:nth-of-type(even){background:none}
- th.halign-left,td.halign-left{text-align:left}
- th.halign-right,td.halign-right{text-align:right}
- th.halign-center,td.halign-center{text-align:center}
- th.valign-top,td.valign-top{vertical-align:top}
- th.valign-bottom,td.valign-bottom{vertical-align:bottom}
- th.valign-middle,td.valign-middle{vertical-align:middle}
- table thead th,table tfoot th{font-weight:bold}
- tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
- tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
- p.tableblock>code:only-child{background:none;padding:0}
- p.tableblock{font-size:1em}
- td>div.verse{white-space:pre}
- ol{margin-left:1.75em}
- ul li ol{margin-left:1.5em}
- dl dd{margin-left:1.125em}
- dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
- ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
- ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
- ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
- ul.unstyled,ol.unstyled{margin-left:0}
- ul.checklist{margin-left:.625em}
- ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
- ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}
- ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
- ul.inline>li{margin-left:1.25em}
- .unstyled dl dt{font-weight:400;font-style:normal}
- ol.arabic{list-style-type:decimal}
- ol.decimal{list-style-type:decimal-leading-zero}
- ol.loweralpha{list-style-type:lower-alpha}
- ol.upperalpha{list-style-type:upper-alpha}
- ol.lowerroman{list-style-type:lower-roman}
- ol.upperroman{list-style-type:upper-roman}
- ol.lowergreek{list-style-type:lower-greek}
- .hdlist>table,.colist>table{border:0;background:none}
- .hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
- td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
- td.hdlist1{font-weight:bold;padding-bottom:1.25em}
- .literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
- .colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
- .colist td:not([class]):first-child img{max-width:none}
- .colist td:not([class]):last-child{padding:.25em 0}
- .thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
- .imageblock.left{margin:.25em .625em 1.25em 0}
- .imageblock.right{margin:.25em 0 1.25em .625em}
- .imageblock>.title{margin-bottom:0}
- .imageblock.thumb,.imageblock.th{border-width:6px}
- .imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
- .image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
- .image.left{margin-right:.625em}
- .image.right{margin-left:.625em}
- a.image{text-decoration:none;display:inline-block}
- a.image object{pointer-events:none}
- sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
- sup.footnote a,sup.footnoteref a{text-decoration:none}
- sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
- #footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
- #footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
- #footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
- #footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
- #footnotes .footnote:last-of-type{margin-bottom:0}
- #content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
- .gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
- .gist .file-data>table td.line-data{width:99%}
- div.unbreakable{page-break-inside:avoid}
- .big{font-size:larger}
- .small{font-size:smaller}
- .underline{text-decoration:underline}
- .overline{text-decoration:overline}
- .line-through{text-decoration:line-through}
- .aqua{color:#00bfbf}
- .aqua-background{background-color:#00fafa}
- .black{color:#000}
- .black-background{background-color:#000}
- .blue{color:#0000bf}
- .blue-background{background-color:#0000fa}
- .fuchsia{color:#bf00bf}
- .fuchsia-background{background-color:#fa00fa}
- .gray{color:#606060}
- .gray-background{background-color:#7d7d7d}
- .green{color:#006000}
- .green-background{background-color:#007d00}
- .lime{color:#00bf00}
- .lime-background{background-color:#00fa00}
- .maroon{color:#600000}
- .maroon-background{background-color:#7d0000}
- .navy{color:#000060}
- .navy-background{background-color:#00007d}
- .olive{color:#606000}
- .olive-background{background-color:#7d7d00}
- .purple{color:#600060}
- .purple-background{background-color:#7d007d}
- .red{color:#bf0000}
- .red-background{background-color:#fa0000}
- .silver{color:#909090}
- .silver-background{background-color:#bcbcbc}
- .teal{color:#006060}
- .teal-background{background-color:#007d7d}
- .white{color:#bfbfbf}
- .white-background{background-color:#fafafa}
- .yellow{color:#bfbf00}
- .yellow-background{background-color:#fafa00}
- span.icon>.fa{cursor:default}
- a span.icon>.fa{cursor:inherit}
- .admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
- .admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
- .admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
- .admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
- .admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
- .admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
- .conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
- .conum[data-value] *{color:#fff!important}
- .conum[data-value]+b{display:none}
- .conum[data-value]::after{content:attr(data-value)}
- pre .conum[data-value]{position:relative;top:-.125em}
- b.conum *{color:inherit!important}
- .conum:not([data-value]):empty{display:none}
- dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
- h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
- p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
- p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
- p{margin-bottom:1.25rem}
- .sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
- .exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
- .print-only{display:none!important}
- @page{margin:1.25cm .75cm}
- @media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
- html{font-size:80%}
- a{color:inherit!important;text-decoration:underline!important}
- a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
- a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
- abbr[title]::after{content:" (" attr(title) ")"}
- pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
- thead{display:table-header-group}
- svg{max-width:100%}
- p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
- h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
- #toc,.sidebarblock,.exampleblock>.content{background:none!important}
- #toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
- body.book #header{text-align:center}
- body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
- body.book #header .details{border:0!important;display:block;padding:0!important}
- body.book #header .details span:first-child{margin-left:0!important}
- body.book #header .details br{display:block}
- body.book #header .details br+span::before{content:none!important}
- body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
- body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
- .listingblock code[data-lang]::before{display:block}
- #footer{padding:0 .9375em}
- .hide-on-print{display:none!important}
- .print-only{display:block!important}
- .hide-for-print{display:none!important}
- .show-for-print{display:inherit!important}}
- @media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem}
- .sect1{padding:0!important}
- .sect1+.sect1{border:0}
- #footer{background:none}
- #footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
- @media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
- </style>
- </head>
- <body class="article toc2 toc-left">
- <div id="header">
- <h1>Boost.SmartPtr: The Smart Pointer Library</h1>
- <div class="details">
- <span id="author" class="author">Greg Colvin, Beman Dawes, Peter Dimov, Glen Fernandes</span><br>
- </div>
- <div id="toc" class="toc2">
- <div id="toctitle">Table of Contents</div>
- <ul class="sectlevel1">
- <li><a href="#introduction">Introduction</a></li>
- <li><a href="#changelog">Revision History</a>
- <ul class="sectlevel2">
- <li><a href="#changelog_changes_in_1_72_0">Changes in 1.72.0</a></li>
- <li><a href="#changelog_changes_in_1_71_0">Changes in 1.71.0</a></li>
- <li><a href="#changelog_changes_in_1_65_0">Changes in 1.65.0</a></li>
- </ul>
- </li>
- <li><a href="#scoped_ptr">scoped_ptr: Scoped Object Ownership</a>
- <ul class="sectlevel2">
- <li><a href="#scoped_ptr_description">Description</a></li>
- <li><a href="#scoped_ptr_synopsis">Synopsis</a></li>
- <li><a href="#scoped_ptr_members">Members</a></li>
- <li><a href="#scoped_ptr_free_functions">Free Functions</a></li>
- <li><a href="#scoped_ptr_example">Example</a></li>
- <li><a href="#scoped_ptr_rationale">Rationale</a></li>
- <li><a href="#scoped_ptr_handlebody_idiom">Handle/Body Idiom</a></li>
- <li><a href="#scoped_ptr_frequently_asked_questions">Frequently Asked Questions</a></li>
- </ul>
- </li>
- <li><a href="#scoped_array">scoped_array: Scoped Array Ownership</a>
- <ul class="sectlevel2">
- <li><a href="#scoped_array_description">Description</a></li>
- <li><a href="#scoped_array_synopsis">Synopsis</a></li>
- <li><a href="#scoped_array_members">Members</a></li>
- <li><a href="#scoped_array_free_functions">Free Functions</a></li>
- </ul>
- </li>
- <li><a href="#shared_ptr">shared_ptr: Shared Ownership</a>
- <ul class="sectlevel2">
- <li><a href="#shared_ptr_description">Description</a></li>
- <li><a href="#shared_ptr_best_practices">Best Practices</a></li>
- <li><a href="#shared_ptr_synopsis">Synopsis</a></li>
- <li><a href="#shared_ptr_members">Members</a></li>
- <li><a href="#shared_ptr_free_functions">Free Functions</a></li>
- <li><a href="#shared_ptr_example">Example</a></li>
- <li><a href="#shared_ptr_handlebody_idiom">Handle/Body Idiom</a></li>
- <li><a href="#shared_ptr_thread_safety">Thread Safety</a></li>
- <li><a href="#shared_ptr_frequently_asked_questions">Frequently Asked Questions</a></li>
- </ul>
- </li>
- <li><a href="#weak_ptr">weak_ptr: Non-owning Observer</a>
- <ul class="sectlevel2">
- <li><a href="#weak_ptr_description">Description</a></li>
- <li><a href="#weak_ptr_synopsis">Synopsis</a></li>
- <li><a href="#weak_ptr_members">Members</a></li>
- <li><a href="#weak_ptr_free_functions">Free Functions</a></li>
- <li><a href="#weak_ptr_frequently_asked_questions">Frequently Asked Questions</a></li>
- </ul>
- </li>
- <li><a href="#make_shared">make_shared: Creating shared_ptr</a>
- <ul class="sectlevel2">
- <li><a href="#make_shared_description">Description</a></li>
- <li><a href="#make_shared_rationale">Rationale</a></li>
- <li><a href="#make_shared_synopsis">Synopsis</a></li>
- <li><a href="#make_shared_common_requirements">Common Requirements</a></li>
- <li><a href="#make_shared_free_functions">Free Functions</a></li>
- </ul>
- </li>
- <li><a href="#enable_shared_from_this">enable_shared_from_this</a>
- <ul class="sectlevel2">
- <li><a href="#enable_shared_from_this_description">Description</a></li>
- <li><a href="#enable_shared_from_this_example">Example</a></li>
- <li><a href="#enable_shared_from_this_synopsis">Synopsis</a></li>
- <li><a href="#enable_shared_from_this_members">Members</a></li>
- </ul>
- </li>
- <li><a href="#enable_shared_from">enable_shared_from</a>
- <ul class="sectlevel2">
- <li><a href="#enable_shared_from_description">Description</a></li>
- <li><a href="#enable_shared_from_example">Example</a></li>
- <li><a href="#enable_shared_from_synopsis">Synopsis</a></li>
- <li><a href="#enable_shared_from_functions">Functions</a></li>
- </ul>
- </li>
- <li><a href="#make_unique">make_unique: Creating unique_ptr</a>
- <ul class="sectlevel2">
- <li><a href="#make_unique_description">Description</a></li>
- <li><a href="#make_unique_rationale">Rationale</a></li>
- <li><a href="#make_unique_synopsis">Synopsis</a></li>
- <li><a href="#make_unique_free_functions">Free Functions</a></li>
- </ul>
- </li>
- <li><a href="#allocate_unique">allocate_unique: Creating unique_ptr</a>
- <ul class="sectlevel2">
- <li><a href="#allocate_unique_description">Description</a></li>
- <li><a href="#allocate_unique_rationale">Rationale</a></li>
- <li><a href="#allocate_unique_synopsis">Synopsis</a></li>
- <li><a href="#allocate_unique_common_requirements">Common Requirements</a></li>
- <li><a href="#allocate_unique_free_functions">Free Functions</a></li>
- <li><a href="#allocate_unique_deleter">Deleter</a></li>
- </ul>
- </li>
- <li><a href="#intrusive_ptr">intrusive_ptr: Managing Objects with Embedded Counts</a>
- <ul class="sectlevel2">
- <li><a href="#intrusive_ptr_description">Description</a></li>
- <li><a href="#intrusive_ptr_synopsis">Synopsis</a></li>
- <li><a href="#intrusive_ptr_members">Members</a></li>
- <li><a href="#intrusive_ptr_free_functions">Free Functions</a></li>
- </ul>
- </li>
- <li><a href="#intrusive_ref_counter">intrusive_ref_counter</a>
- <ul class="sectlevel2">
- <li><a href="#intrusive_ref_counter_description">Description</a></li>
- <li><a href="#intrusive_ref_counter_synopsis">Synopsis</a></li>
- <li><a href="#intrusive_ref_counter_members">Members</a></li>
- <li><a href="#intrusive_ref_counter_free_functions">Free Functions</a></li>
- </ul>
- </li>
- <li><a href="#local_shared_ptr">local_shared_ptr: Shared Ownership within a Single Thread</a>
- <ul class="sectlevel2">
- <li><a href="#local_shared_ptr_description">Description</a></li>
- <li><a href="#local_shared_ptr_synopsis">Synopsis</a></li>
- <li><a href="#local_shared_ptr_members">Members</a></li>
- <li><a href="#local_shared_ptr_free_functions">Free Functions</a></li>
- </ul>
- </li>
- <li><a href="#make_local_shared">make_local_shared: Creating local_shared_ptr</a>
- <ul class="sectlevel2">
- <li><a href="#make_local_shared_description">Description</a></li>
- <li><a href="#make_local_shared_synopsis">Synopsis</a></li>
- <li><a href="#make_local_shared_description_2">Description</a></li>
- </ul>
- </li>
- <li><a href="#pointer_cast">Generic Pointer Casts</a>
- <ul class="sectlevel2">
- <li><a href="#pointer_cast_description">Description</a></li>
- <li><a href="#pointer_cast_rationale">Rationale</a></li>
- <li><a href="#pointer_cast_synopsis">Synopsis</a></li>
- <li><a href="#pointer_cast_free_functions">Free Functions</a></li>
- <li><a href="#pointer_cast_example">Example</a></li>
- </ul>
- </li>
- <li><a href="#pointer_to_other">pointer_to_other</a>
- <ul class="sectlevel2">
- <li><a href="#pointer_to_other_description">Description</a></li>
- <li><a href="#pointer_to_other_rationale">Rationale</a></li>
- <li><a href="#pointer_to_other_synopsis">Synopsis</a></li>
- <li><a href="#pointer_to_other_example">Example</a></li>
- </ul>
- </li>
- <li><a href="#atomic_shared_ptr">atomic_shared_ptr</a>
- <ul class="sectlevel2">
- <li><a href="#atomic_shared_ptr_description">Description</a></li>
- <li><a href="#atomic_shared_ptr_synopsis">Synopsis</a></li>
- <li><a href="#atomic_shared_ptr_members">Members</a></li>
- </ul>
- </li>
- <li><a href="#techniques">Appendix A: Smart Pointer Programming Techniques</a>
- <ul class="sectlevel2">
- <li><a href="#techniques_incomplete">Using incomplete classes for implementation hiding</a></li>
- <li><a href="#techniques_the_pimpl_idiom">The "Pimpl" idiom</a></li>
- <li><a href="#techniques_using_abstract_classes_for_implementation_hiding">Using abstract classes for implementation hiding</a></li>
- <li><a href="#techniques_preventing_delete_px_get">Preventing <code>delete px.get()</code></a></li>
- <li><a href="#techniques_encapsulating_allocation_details_wrapping_factory_functions">Encapsulating allocation details, wrapping factory functions</a></li>
- <li><a href="#techniques_static">Using a shared_ptr to hold a pointer to a statically allocated object</a></li>
- <li><a href="#techniques_using_a_shared_ptr_to_hold_a_pointer_to_a_com_object">Using a shared_ptr to hold a pointer to a COM Object</a></li>
- <li><a href="#techniques_intrusive">Using a shared_ptr to hold a pointer to an object with an embedded reference count</a></li>
- <li><a href="#techniques_using_a_shared_ptr_to_hold_another_shared_ownership_smart_pointer">Using a shared_ptr to hold another shared ownership smart pointer</a></li>
- <li><a href="#techniques_from_raw">Obtaining a shared_ptr from a raw pointer</a></li>
- <li><a href="#techniques_obtaining_a_shared_ptr_weak_ptr_to_this_in_a_constructor">Obtaining a shared_ptr (weak_ptr) to this in a constructor</a></li>
- <li><a href="#techniques_obtaining_a_shared_ptr_to_this">Obtaining a shared_ptr to this</a></li>
- <li><a href="#techniques_using_shared_ptr_as_a_smart_counted_handle">Using shared_ptr as a smart counted handle</a></li>
- <li><a href="#techniques_using_shared_ptr_to_execute_code_on_block_exit">Using shared_ptr to execute code on block exit</a></li>
- <li><a href="#techniques_using_shared_ptrvoid_to_hold_an_arbitrary_object">Using shared_ptr<void> to hold an arbitrary object</a></li>
- <li><a href="#techniques_associating_arbitrary_data_with_heterogeneous_shared_ptr_instances">Associating arbitrary data with heterogeneous <code>shared_ptr</code> instances</a></li>
- <li><a href="#techniques_using_shared_ptr_as_a_copyconstructible_mutex_lock">Using <code>shared_ptr</code> as a <code>CopyConstructible</code> mutex lock</a></li>
- <li><a href="#techniques_using_shared_ptr_to_wrap_member_function_calls">Using shared_ptr to wrap member function calls</a></li>
- <li><a href="#techniques_delayed_deallocation">Delayed deallocation</a></li>
- <li><a href="#techniques_weak_without_shared">Weak pointers to objects not managed by a shared_ptr</a></li>
- </ul>
- </li>
- <li><a href="#history">Appendix B: History and Acknowledgments</a>
- <ul class="sectlevel2">
- <li><a href="#history_summer_1994">Summer 1994</a></li>
- <li><a href="#history_october_1998">October 1998</a></li>
- <li><a href="#history_may_1999">May 1999</a></li>
- <li><a href="#history_september_1999">September 1999</a></li>
- <li><a href="#history_november_1999">November 1999</a></li>
- <li><a href="#history_may_2001">May 2001</a></li>
- <li><a href="#history_january_2002">January 2002</a></li>
- <li><a href="#history_march_2003">March 2003</a></li>
- <li><a href="#history_july_2007">July 2007</a></li>
- <li><a href="#history_november_2012">November 2012</a></li>
- <li><a href="#history_april_2013">April 2013</a></li>
- <li><a href="#history_february_2014">February 2014</a></li>
- <li><a href="#history_february_2017">February 2017</a></li>
- <li><a href="#history_june_2017">June 2017</a></li>
- <li><a href="#history_august_2019">August 2019</a></li>
- </ul>
- </li>
- <li><a href="#shared_array">Appendix C: shared_array (deprecated)</a>
- <ul class="sectlevel2">
- <li><a href="#shared_array_description">Description</a></li>
- <li><a href="#shared_array_synopsis">Synopsis</a></li>
- <li><a href="#shared_array_members">Members</a></li>
- <li><a href="#shared_array_free_functions">Free Functions</a></li>
- </ul>
- </li>
- <li><a href="#copyright">Appendix D: Copyright and License</a></li>
- </ul>
- </div>
- </div>
- <div id="content">
- <div class="sect1">
- <h2 id="introduction">Introduction</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>Smart pointers are objects which store pointers to dynamically allocated (heap) objects.
- They behave much like built-in C++ pointers except that they automatically delete the object
- pointed to at the appropriate time. Smart pointers are particularly useful in the face of
- exceptions as they ensure proper destruction of dynamically allocated objects. They can also be
- used to keep track of dynamically allocated objects shared by multiple owners.</p>
- </div>
- <div class="paragraph">
- <p>Conceptually, smart pointers are seen as owning the object pointed to, and thus responsible for
- deletion of the object when it is no longer needed. As such, they are examples of the "resource
- acquisition is initialization" idiom described in Bjarne Stroustrup’s "The C++ Programming Language",
- 3rd edition, Section 14.4, Resource Management.</p>
- </div>
- <div class="paragraph">
- <p>This library provides six smart pointer class templates:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p><code><a href="#scoped_ptr">scoped_ptr</a></code>, used to contain ownership of a dynamically allocated object to the current scope;</p>
- </li>
- <li>
- <p><code><a href="#scoped_array">scoped_array</a></code>, which provides scoped ownership for a dynamically allocated array;</p>
- </li>
- <li>
- <p><code><a href="#shared_ptr">shared_ptr</a></code>, a versatile tool for managing shared ownership of an object or array;</p>
- </li>
- <li>
- <p><code><a href="#weak_ptr">weak_ptr</a></code>, a non-owning observer to a shared_ptr-managed object that can be promoted temporarily to shared_ptr;</p>
- </li>
- <li>
- <p><code><a href="#intrusive_ptr">intrusive_ptr</a></code>, a pointer to objects with an embedded reference count;</p>
- </li>
- <li>
- <p><code><a href="#local_shared_ptr">local_shared_ptr</a></code>, providing shared ownership within a single thread.</p>
- </li>
- </ul>
- </div>
- <div class="paragraph">
- <p><code>shared_ptr</code> and <code>weak_ptr</code> are part of the C++ standard since its 2011 iteration.</p>
- </div>
- <div class="paragraph">
- <p>In addition, the library contains the following supporting utility functions and classes:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p><code><a href="#make_shared">make_shared</a></code>, a factory function for creating objects that returns a <code>shared_ptr</code>;</p>
- </li>
- <li>
- <p><code><a href="#make_unique">make_unique</a></code>, a factory function returning <code>std::unique_ptr</code>;</p>
- </li>
- <li>
- <p><code><a href="#allocate_unique">allocate_unique</a></code>, a factory function for creating objects using an allocator that returns a <code>std::unique_ptr</code>;</p>
- </li>
- <li>
- <p><code><a href="#enable_shared_from_this">enable_shared_from_this</a></code>, a helper base class that enables the acquisition of a <code>shared_ptr</code> pointing to <code>this</code>;</p>
- </li>
- <li>
- <p><code><a href="#pointer_to_other">pointer_to_other</a></code>, a helper trait for converting one smart pointer type to another;</p>
- </li>
- <li>
- <p><code><a href="#pointer_cast">static_pointer_cast</a></code> and companions, generic smart pointer casts;</p>
- </li>
- <li>
- <p><code><a href="#intrusive_ref_counter">intrusive_ref_counter</a></code>, a helper base class containing a reference count.</p>
- </li>
- <li>
- <p><code><a href="#atomic_shared_ptr">atomic_shared_ptr</a></code>, a helper class implementing the interface of <code>std::atomic</code> for a value of type <code>shared_ptr</code>.</p>
- </li>
- </ul>
- </div>
- <div class="paragraph">
- <p>As a general rule, the destructor or <code>operator delete</code> for an object managed by pointers in the library
- are not allowed to throw exceptions.</p>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="changelog">Revision History</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="changelog_changes_in_1_72_0">Changes in 1.72.0</h3>
- <div class="ulist">
- <ul>
- <li>
- <p>Added <code>allocate_unique</code></p>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect2">
- <h3 id="changelog_changes_in_1_71_0">Changes in 1.71.0</h3>
- <div class="ulist">
- <ul>
- <li>
- <p>Added aliasing constructors to <code>weak_ptr</code></p>
- </li>
- <li>
- <p>Added <code>weak_ptr<T>::empty()</code></p>
- </li>
- <li>
- <p>Added <code>enable_shared_from</code>, <code>shared_from</code>, and <code>weak_from</code></p>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect2">
- <h3 id="changelog_changes_in_1_65_0">Changes in 1.65.0</h3>
- <div class="ulist">
- <ul>
- <li>
- <p>Added <code>atomic_shared_ptr</code></p>
- </li>
- <li>
- <p>Added <code>local_shared_ptr</code>, <code>make_local_shared</code></p>
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="scoped_ptr">scoped_ptr: Scoped Object Ownership</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="scoped_ptr_description">Description</h3>
- <div class="paragraph">
- <p>The <code>scoped_ptr</code> class template stores a pointer to a dynamically allocated object.
- (Dynamically allocated objects are allocated with the C++ <code>new</code> expression.) The
- object pointed to is guaranteed to be deleted, either on destruction of the <code>scoped_ptr</code>,
- or via an explicit <code>reset</code>. See the <a href="#scoped_ptr_example">example</a>.</p>
- </div>
- <div class="paragraph">
- <p><code>scoped_ptr</code> is a simple solution for simple needs. It supplies a basic "resource acquisition
- is initialization" facility, without shared-ownership or transfer-of-ownership semantics.
- Both its name and enforcement of semantics (by being noncopyable) signal its intent to retain
- ownership solely within the current scope. Because it is noncopyable, it is safer than <code>shared_ptr</code>
- for pointers which should not be copied.</p>
- </div>
- <div class="paragraph">
- <p>Because <code>scoped_ptr</code> is simple, in its usual implementation every operation is as fast as for a
- built-in pointer and it has no more space overhead that a built-in pointer.</p>
- </div>
- <div class="paragraph">
- <p><code>scoped_ptr</code> cannot be used in C++ Standard Library containers. Use <code>shared_ptr</code> or <code>std::unique_ptr</code>
- if you need a smart pointer that can.</p>
- </div>
- <div class="paragraph">
- <p><code>scoped_ptr</code> cannot correctly hold a pointer to a dynamically allocated array. See <code>scoped_array</code> for that usage.</p>
- </div>
- <div class="paragraph">
- <p>The class template is parameterized on <code>T</code>, the type of the object pointed to. Destroying <code>T</code> must not thow exceptions,
- and <code>T</code> must be complete at the point <code>scoped_ptr<T>::~scoped_ptr</code> is instantiated.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="scoped_ptr_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p><code>scoped_ptr</code> is defined in <code><boost/smart_ptr/scoped_ptr.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- template<class T> class scoped_ptr {
- private:
- scoped_ptr(scoped_ptr const&);
- scoped_ptr& operator=(scoped_ptr const&);
- void operator==(scoped_ptr const&) const;
- void operator!=(scoped_ptr const&) const;
- public:
- typedef T element_type;
- explicit scoped_ptr(T * p = 0) noexcept;
- ~scoped_ptr() noexcept;
- void reset(T * p = 0) noexcept;
- T & operator*() const noexcept;
- T * operator->() const noexcept;
- T * get() const noexcept;
- explicit operator bool() const noexcept;
- void swap(scoped_ptr & b) noexcept;
- };
- template<class T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) noexcept;
- template<class T>
- bool operator==( scoped_ptr<T> const & p, std::nullptr_t ) noexcept;
- template<class T>
- bool operator==( std::nullptr_t, scoped_ptr<T> const & p ) noexcept;
- template<class T>
- bool operator!=( scoped_ptr<T> const & p, std::nullptr_t ) noexcept;
- template<class T>
- bool operator!=( std::nullptr_t, scoped_ptr<T> const & p ) noexcept;
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="scoped_ptr_members">Members</h3>
- <div class="sect3">
- <h4 id="scoped_ptr_element_type">element_type</h4>
- <div class="literalblock">
- <div class="content">
- <pre>typedef T element_type;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Provides the type of the stored pointer.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_ptr_constructor">constructor</h4>
- <div class="literalblock">
- <div class="content">
- <pre>explicit scoped_ptr(T * p = 0) noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Constructs a <code>scoped_ptr</code>, storing a copy of <code>p</code>, which must have been allocated via a
- C++ <code>new</code> expression or be 0. <code>T</code> is not required be a complete type.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_ptr_destructor">destructor</h4>
- <div class="literalblock">
- <div class="content">
- <pre>~scoped_ptr() noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Destroys the object pointed to by the stored pointer, if any, as if by using
- <code>delete this->get()</code>. <code>T</code> must be a complete type.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_ptr_reset">reset</h4>
- <div class="literalblock">
- <div class="content">
- <pre>void reset(T * p = 0) noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Deletes the object pointed to by the stored pointer and then stores a copy of
- <code>p</code>, which must have been allocated via a C++ <code>new</code> expression or be 0.</p>
- </div>
- <div class="paragraph">
- <p>Since the previous object needs to be deleted, <code>T</code> must be a complete type.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_ptr_indirection">indirection</h4>
- <div class="literalblock">
- <div class="content">
- <pre>T & operator*() const noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Returns a reference to the object pointed to by the stored pointer. Behavior is undefined if the stored pointer is 0.</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>T * operator->() const noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Returns the stored pointer. Behavior is undefined if the stored pointer is 0.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_ptr_get">get</h4>
- <div class="literalblock">
- <div class="content">
- <pre>T * get() const noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Returns the stored pointer. <code>T</code> need not be a complete type.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_ptr_conversions">conversions</h4>
- <div class="literalblock">
- <div class="content">
- <pre>explicit operator bool () const noexcept; // never throws</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Returns <code>get() != 0</code>.</p>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- On C++03 compilers, the return value is of an unspecified type.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_ptr_swap">swap</h4>
- <div class="literalblock">
- <div class="content">
- <pre>void swap(scoped_ptr & b) noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Exchanges the contents of the two smart pointers. <code>T</code> need not be a complete type.</p>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="scoped_ptr_free_functions">Free Functions</h3>
- <div class="sect3">
- <h4 id="scoped_ptr_swap_2">swap</h4>
- <div class="literalblock">
- <div class="content">
- <pre>template<class T> void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Equivalent to <code>a.swap(b)</code>.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_ptr_comparisons">comparisons</h4>
- <div class="literalblock">
- <div class="content">
- <pre>template<class T> bool operator==( scoped_ptr<T> const & p, std::nullptr_t ) noexcept;</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>template<class T> bool operator==( std::nullptr_t, scoped_ptr<T> const & p ) noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Returns <code>p.get() == nullptr</code>.</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>template<class T> bool operator!=( scoped_ptr<T> const & p, std::nullptr_t ) noexcept;</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>template<class T> bool operator!=( std::nullptr_t, scoped_ptr<T> const & p ) noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Returns <code>p.get() != nullptr</code>.</p>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="scoped_ptr_example">Example</h3>
- <div class="paragraph">
- <p>Here’s an example that uses <code>scoped_ptr</code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>#include <boost/scoped_ptr.hpp>
- #include <iostream>
- struct Shoe { ~Shoe() { std::cout << "Buckle my shoe\n"; } };
- class MyClass {
- boost::scoped_ptr<int> ptr;
- public:
- MyClass() : ptr(new int) { *ptr = 0; }
- int add_one() { return ++*ptr; }
- };
- int main()
- {
- boost::scoped_ptr<Shoe> x(new Shoe);
- MyClass my_instance;
- std::cout << my_instance.add_one() << '\n';
- std::cout << my_instance.add_one() << '\n';
- }</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>The example program produces the beginning of a child’s nursery rhyme:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>1
- 2
- Buckle my shoe</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="scoped_ptr_rationale">Rationale</h3>
- <div class="paragraph">
- <p>The primary reason to use <code>scoped_ptr</code> rather than <code>std::auto_ptr</code> or <code>std::unique_ptr</code> is to let readers of your code
- know that you intend "resource acquisition is initialization" to be applied only for the current scope, and have no intent to transfer ownership.</p>
- </div>
- <div class="paragraph">
- <p>A secondary reason to use <code>scoped_ptr</code> is to prevent a later maintenance programmer from adding a function that transfers
- ownership by returning the <code>auto_ptr</code>, because the maintenance programmer saw <code>auto_ptr</code>, and assumed ownership could safely be transferred.</p>
- </div>
- <div class="paragraph">
- <p>Think of <code>bool</code> vs <code>int</code>. We all know that under the covers <code>bool</code> is usually just an <code>int</code>. Indeed, some argued against including bool in the C++
- standard because of that. But by coding <code>bool</code> rather than <code>int</code>, you tell your readers what your intent is. Same with <code>scoped_ptr</code>; by using it you are signaling intent.</p>
- </div>
- <div class="paragraph">
- <p>It has been suggested that <code>scoped_ptr<T></code> is equivalent to <code>std::auto_ptr<T> const</code>. Ed Brey pointed out, however, that <code>reset</code> will not work on a <code>std::auto_ptr<T> const</code>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="scoped_ptr_handlebody_idiom">Handle/Body Idiom</h3>
- <div class="paragraph">
- <p>One common usage of <code>scoped_ptr</code> is to implement a handle/body (also called pimpl) idiom which avoids exposing the body (implementation) in the header file.</p>
- </div>
- <div class="paragraph">
- <p>The <code><a href="../../example/scoped_ptr_example_test.cpp">scoped_ptr_example_test.cpp</a></code> sample program includes a header file,
- <code><a href="../../example/scoped_ptr_example.hpp">scoped_ptr_example.hpp</a></code>, which uses a <code>scoped_ptr<></code> to an incomplete type to hide the
- implementation. The instantiation of member functions which require a complete type occurs in the <code><a href="../../example/scoped_ptr_example.cpp">scoped_ptr_example.cpp</a></code>
- implementation file.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="scoped_ptr_frequently_asked_questions">Frequently Asked Questions</h3>
- <div class="qlist qanda">
- <ol>
- <li>
- <p><em>Why doesn’t <code>scoped_ptr</code> have a <code>release()</code> member?</em></p>
- <p>When reading source code, it is valuable to be able to draw conclusions about program behavior based on the types being used. If <code>scoped_ptr</code> had a <code>release()</code> member,
- it would become possible to transfer ownership of the held pointer, weakening its role as a way of limiting resource lifetime to a given context. Use <code>std::auto_ptr</code> where
- transfer of ownership is required. (supplied by Dave Abrahams)</p>
- </li>
- </ol>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="scoped_array">scoped_array: Scoped Array Ownership</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="scoped_array_description">Description</h3>
- <div class="paragraph">
- <p>The <code>scoped_array</code> class template stores a pointer to a dynamically allocated array.
- (Dynamically allocated arrays are allocated with the C++ <code>new[]</code> expression.) The array
- pointed to is guaranteed to be deleted, either on destruction of the <code>scoped_array</code>,
- or via an explicit <code>reset</code>.</p>
- </div>
- <div class="paragraph">
- <p>The <code>scoped_array</code> template is a simple solution for simple needs. It supplies a basic
- "resource acquisition is initialization" facility, without shared-ownership or
- transfer-of-ownership semantics. Both its name and enforcement of semantics
- (by being noncopyable) signal its intent to retain ownership solely within the current scope.
- Because it is noncopyable, it is safer than <code>shared_ptr<T[]></code> for pointers which should not be copied.</p>
- </div>
- <div class="paragraph">
- <p>Because <code>scoped_array</code> is so simple, in its usual implementation every operation is as fast as a
- built-in array pointer and it has no more space overhead that a built-in array pointer.</p>
- </div>
- <div class="paragraph">
- <p>It cannot be used in C++ standard library containers. See <code>shared_ptr<T[]></code> if <code>scoped_array</code>
- does not meet your needs.</p>
- </div>
- <div class="paragraph">
- <p>It cannot correctly hold a pointer to a single object. See <code>scoped_ptr</code> for that usage.</p>
- </div>
- <div class="paragraph">
- <p><code>std::vector</code> is an alternative to <code>scoped_array</code> that is a bit heavier duty but far more flexible.
- <code>boost::array</code> is an alternative that does not use dynamic allocation.</p>
- </div>
- <div class="paragraph">
- <p>The class template is parameterized on <code>T</code>, the type of the object pointed to.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="scoped_array_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p><code>scoped_array</code> is defined in <code><boost/smart_ptr/scoped_array.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- template<class T> class scoped_array {
- private:
- scoped_array(scoped_array const &);
- scoped_array & operator=(scoped_array const &);
- void operator==( scoped_array const& ) const;
- void operator!=( scoped_array const& ) const;
- public:
- typedef T element_type;
- explicit scoped_array(T * p = 0) noexcept;
- ~scoped_array() noexcept;
- void reset(T * p = 0) noexcept;
- T & operator[](std::ptrdiff_t i) const noexcept;
- T * get() const noexcept;
- explicit operator bool () const noexcept;
- void swap(scoped_array & b) noexcept;
- };
- template<class T> void swap(scoped_array<T> & a, scoped_array<T> & b) noexcept;
- template<class T>
- bool operator==( scoped_array<T> const & p, std::nullptr_t ) noexcept;
- template<class T>
- bool operator==( std::nullptr_t, scoped_array<T> const & p ) noexcept;
- template<class T>
- bool operator!=( scoped_array<T> const & p, std::nullptr_t ) noexcept;
- template<class T>
- bool operator!=( std::nullptr_t, scoped_array<T> const & p ) noexcept;
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="scoped_array_members">Members</h3>
- <div class="sect3">
- <h4 id="scoped_array_element_type">element_type</h4>
- <div class="literalblock">
- <div class="content">
- <pre>typedef T element_type;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Provides the type of the stored pointer.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_array_constructors">constructors</h4>
- <div class="literalblock">
- <div class="content">
- <pre>explicit scoped_array(T * p = 0) noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Constructs a <code>scoped_array</code>, storing a copy of <code>p</code>, which must have been
- allocated via a C++ <code>new[]</code> expression or be 0. <code>T</code> is not required be a complete type.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_array_destructor">destructor</h4>
- <div class="literalblock">
- <div class="content">
- <pre>~scoped_array() noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Deletes the array pointed to by the stored pointer. Note that <code>delete[]</code> on a pointer with
- a value of 0 is harmless. <code>T</code> must be complete, and <code>delete[]</code> on the stored pointer must
- not throw exceptions.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_array_reset">reset</h4>
- <div class="literalblock">
- <div class="content">
- <pre>void reset(T * p = 0) noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Deletes the array pointed to by the stored pointer and then stores a copy of <code>p</code>,
- which must have been allocated via a C++ <code>new[]</code> expression or be 0. <code>T</code> must be complete,
- and <code>delete[]</code> on the stored pointer must not throw exceptions.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_array_subscripting">subscripting</h4>
- <div class="literalblock">
- <div class="content">
- <pre>T & operator[](std::ptrdiff_t i) const noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Returns a reference to element <code>i</code> of the array pointed to by the stored pointer.
- Behavior is undefined and almost certainly undesirable if the stored pointer is 0,
- or if <code>i</code> is less than 0 or is greater than or equal to the number of elements in
- the array.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_array_get">get</h4>
- <div class="literalblock">
- <div class="content">
- <pre>T * get() const noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Returns the stored pointer. <code>T</code> need not be a complete type.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_array_conversions">conversions</h4>
- <div class="literalblock">
- <div class="content">
- <pre>explicit operator bool () const noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Returns <code>get() != 0</code>.</p>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- On C++03 compilers, the return value is of an unspecified type.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_array_swap">swap</h4>
- <div class="literalblock">
- <div class="content">
- <pre>void swap(scoped_array & b) noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Exchanges the contents of the two smart pointers. <code>T</code> need not be a complete type.</p>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="scoped_array_free_functions">Free Functions</h3>
- <div class="sect3">
- <h4 id="scoped_array_swap_2">swap</h4>
- <div class="literalblock">
- <div class="content">
- <pre>template<class T> void swap(scoped_array<T> & a, scoped_array<T> & b) noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Equivalent to <code>a.swap(b)</code>.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="scoped_array_comparisons">comparisons</h4>
- <div class="literalblock">
- <div class="content">
- <pre>template<class T>
- bool operator==( scoped_array<T> const & p, std::nullptr_t ) noexcept;</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>template<class T>
- bool operator==( std::nullptr_t, scoped_array<T> const & p ) noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Returns <code>p.get() == nullptr</code>.</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>template<class T>
- bool operator!=( scoped_array<T> const & p, std::nullptr_t ) noexcept;</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>template<class T>
- bool operator!=( std::nullptr_t, scoped_array<T> const & p ) noexcept;</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Returns <code>p.get() != nullptr</code>.</p>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="shared_ptr">shared_ptr: Shared Ownership</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="shared_ptr_description">Description</h3>
- <div class="paragraph">
- <p>The <code>shared_ptr</code> class template stores a pointer to a dynamically allocated object, typically with a C++ <code>new</code>-expression.
- The object pointed to is guaranteed to be deleted when the last <code>shared_ptr</code> pointing to it is destroyed or reset.</p>
- </div>
- <div class="listingblock">
- <div class="title">Code Example 1. Using shared_ptr</div>
- <div class="content">
- <pre class="highlight"><code>shared_ptr<X> p1( new X );
- shared_ptr<void> p2( new int(5) );</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p><code>shared_ptr</code> deletes the exact pointer that has been passed at construction time, complete with its original type, regardless
- of the template parameter. In the second example above, when <code>p2</code> is destroyed or reset, it will call <code>delete</code> on the original
- <code>int*</code> that has been passed to the constructor, even though <code>p2</code> itself is of type <code>shared_ptr<void></code> and stores a pointer of
- type <code>void*</code>.</p>
- </div>
- <div class="paragraph">
- <p>Every <code>shared_ptr</code> meets the <code>CopyConstructible</code>, <code>MoveConstructible</code>, <code>CopyAssignable</code> and <code>MoveAssignable</code> requirements of the
- C++ Standard Library, and can be used in standard library containers. Comparison operators are supplied so that <code>shared_ptr</code>
- works with the standard library’s associative containers.</p>
- </div>
- <div class="paragraph">
- <p>Because the implementation uses reference counting, cycles of <code>shared_ptr</code> instances will not be reclaimed. For example, if <code>main()</code>
- holds a <code>shared_ptr</code> to <code>A</code>, which directly or indirectly holds a <code>shared_ptr</code> back to <code>A</code>, <code>A’s use count will be 2. Destruction
- of the original `shared_ptr</code> will leave <code>A</code> dangling with a use count of 1. Use <code><a href="#weak_ptr">weak_ptr</a></code> to "break cycles."</p>
- </div>
- <div class="paragraph">
- <p>The class template is parameterized on <code>T</code>, the type of the object pointed to. <code>shared_ptr</code> and most of its member functions place
- no requirements on <code>T</code>; it is allowed to be an incomplete type, or <code>void</code>. Member functions that do place additional requirements
- (constructors, <code>reset</code>) are explicitly documented below.</p>
- </div>
- <div class="paragraph">
- <p><code>shared_ptr<T></code> can be implicitly converted to <code>shared_ptr<U></code> whenever <code>T*</code> can be implicitly converted to <code>U*</code>. In particular,
- <code>shared_ptr<T></code> is implicitly convertible to <code>shared_ptr<T const></code>, to <code>shared_ptr<U></code> where <code>U</code> is an accessible base of <code>T</code>,
- and to <code>shared_ptr<void></code>.</p>
- </div>
- <div class="paragraph">
- <p><code>shared_ptr</code> is now part of the C++11 Standard, as <code>std::shared_ptr</code>.</p>
- </div>
- <div class="paragraph">
- <p>Starting with Boost release 1.53, <code>shared_ptr</code> can be used to hold a pointer to a dynamically allocated array. This is accomplished
- by using an array type (<code>T[]</code> or <code>T[N]</code>) as the template parameter. There is almost no difference between using an unsized array,
- <code>T[]</code>, and a sized array, <code>T[N]</code>; the latter just enables <code>operator[]</code> to perform a range check on the index.</p>
- </div>
- <div class="listingblock">
- <div class="title">Code Example 2. Using shared_ptr with arrays</div>
- <div class="content">
- <pre class="highlight"><code>shared_ptr<double[1024]> p1( new double[1024] );
- shared_ptr<double[]> p2( new double[n] );</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="shared_ptr_best_practices">Best Practices</h3>
- <div class="paragraph">
- <p>A simple guideline that nearly eliminates the possibility of memory leaks is: always use a named smart pointer variable to hold the result
- of <code>new</code>. Every occurence of the <code>new</code> keyword in the code should have the form:</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>shared_ptr<T> p(new Y);</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>It is, of course, acceptable to use another smart pointer in place of <code>shared_ptr</code> above; having <code>T</code> and <code>Y</code> be the same type, or passing
- arguments to the constructor of <code>Y</code> is also OK.</p>
- </div>
- <div class="paragraph">
- <p>If you observe this guideline, it naturally follows that you will have no explicit <code>delete</code> statements; <code>try</code>/<code>catch</code> constructs will be rare.</p>
- </div>
- <div class="paragraph">
- <p>Avoid using unnamed <code>shared_ptr</code> temporaries to save typing; to see why this is dangerous, consider this example:</p>
- </div>
- <div class="listingblock">
- <div class="title">Code Example 3. Exception-safe and -unsafe use of shared_ptr</div>
- <div class="content">
- <pre class="highlight"><code>void f(shared_ptr<int>, int);
- int g();
- void ok()
- {
- shared_ptr<int> p( new int(2) );
- f( p, g() );
- }
- void bad()
- {
- f( shared_ptr<int>( new int(2) ), g() );
- }</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>The function <code>ok</code> follows the guideline to the letter, whereas <code>bad</code> constructs the temporary <code>shared_ptr</code> in place, admitting the possibility of
- a memory leak. Since function arguments are evaluated in unspecified order, it is possible for <code>new int(2)</code> to be evaluated first, <code>g()</code> second,
- and we may never get to the <code>shared_ptr</code> constructor if <code>g</code> throws an exception. See <a href="http://www.gotw.ca/gotw/056.htm">Herb Sutter’s treatment</a> of
- the issue for more information.</p>
- </div>
- <div class="paragraph">
- <p>The exception safety problem described above may also be eliminated by using the <code><a href="#make_shared">make_shared</a></code> or <code>allocate_shared</code> factory
- functions defined in <code><boost/smart_ptr/make_shared.hpp></code>. These factory functions also provide an efficiency benefit by consolidating allocations.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="shared_ptr_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p><code>shared_ptr</code> is defined in <code><boost/smart_ptr/shared_ptr.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- class bad_weak_ptr: public std::exception;
- template<class T> class weak_ptr;
- template<class T> class shared_ptr {
- public:
- typedef /*see below*/ element_type;
- constexpr shared_ptr() noexcept;
- constexpr shared_ptr(std::nullptr_t) noexcept;
- template<class Y> explicit shared_ptr(Y * p);
- template<class Y, class D> shared_ptr(Y * p, D d);
- template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);
- template<class D> shared_ptr(std::nullptr_t p, D d);
- template<class D, class A> shared_ptr(std::nullptr_t p, D d, A a);
- ~shared_ptr() noexcept;
- shared_ptr(shared_ptr const & r) noexcept;
- template<class Y> shared_ptr(shared_ptr<Y> const & r) noexcept;
- shared_ptr(shared_ptr && r) noexcept;
- template<class Y> shared_ptr(shared_ptr<Y> && r) noexcept;
- template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p) noexcept;
- template<class Y> shared_ptr(shared_ptr<Y> && r, element_type * p) noexcept;
- template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);
- template<class Y> explicit shared_ptr(std::auto_ptr<Y> & r);
- template<class Y> shared_ptr(std::auto_ptr<Y> && r);
- template<class Y, class D> shared_ptr(std::unique_ptr<Y, D> && r);
- shared_ptr & operator=(shared_ptr const & r) noexcept;
- template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r) noexcept;
- shared_ptr & operator=(shared_ptr const && r) noexcept;
- template<class Y> shared_ptr & operator=(shared_ptr<Y> const && r) noexcept;
- template<class Y> shared_ptr & operator=(std::auto_ptr<Y> & r);
- template<class Y> shared_ptr & operator=(std::auto_ptr<Y> && r);
- template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y, D> && r);
- shared_ptr & operator=(std::nullptr_t) noexcept;
- void reset() noexcept;
- template<class Y> void reset(Y * p);
- template<class Y, class D> void reset(Y * p, D d);
- template<class Y, class D, class A> void reset(Y * p, D d, A a);
- template<class Y> void reset(shared_ptr<Y> const & r, element_type * p) noexcept;
- template<class Y> void reset(shared_ptr<Y> && r, element_type * p) noexcept;
- T & operator*() const noexcept; // only valid when T is not an array type
- T * operator->() const noexcept; // only valid when T is not an array type
- // only valid when T is an array type
- element_type & operator[](std::ptrdiff_t i) const noexcept;
- element_type * get() const noexcept;
- bool unique() const noexcept;
- long use_count() const noexcept;
- explicit operator bool() const noexcept;
- void swap(shared_ptr & b) noexcept;
- template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const noexcept;
- template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const noexcept;
- };
- template<class T, class U>
- bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;
- template<class T, class U>
- bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;
- template<class T, class U>
- bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;
- template<class T> bool operator==(shared_ptr<T> const & p, std::nullptr_t) noexcept;
- template<class T> bool operator==(std::nullptr_t, shared_ptr<T> const & p) noexcept;
- template<class T> bool operator!=(shared_ptr<T> const & p, std::nullptr_t) noexcept;
- template<class T> bool operator!=(std::nullptr_t, shared_ptr<T> const & p) noexcept;
- template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b) noexcept;
- template<class T>
- typename shared_ptr<T>::element_type *
- get_pointer(shared_ptr<T> const & p) noexcept;
- template<class T, class U>
- shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r) noexcept;
- template<class T, class U>
- shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r) noexcept;
- template<class T, class U>
- shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r) noexcept;
- template<class T, class U>
- shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U> const & r) noexcept;
- template<class E, class T, class Y>
- std::basic_ostream<E, T> &
- operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p);
- template<class D, class T> D * get_deleter(shared_ptr<T> const & p) noexcept;
- template<class T> bool atomic_is_lock_free( shared_ptr<T> const * p ) noexcept;
- template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p ) noexcept;
- template<class T>
- shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, int ) noexcept;
- template<class T>
- void atomic_store( shared_ptr<T> * p, shared_ptr<T> r ) noexcept;
- template<class T>
- void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, int ) noexcept;
- template<class T>
- shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r ) noexcept;
- template<class T>
- shared_ptr<T> atomic_exchange_explicit(
- shared_ptr<T> * p, shared_ptr<T> r, int ) noexcept;
- template<class T>
- bool atomic_compare_exchange(
- shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w ) noexcept;
- template<class T>
- bool atomic_compare_exchange_explicit(
- shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, int, int ) noexcept;
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="shared_ptr_members">Members</h3>
- <div class="sect3">
- <h4 id="shared_ptr_element_type">element_type</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>typedef ... element_type;</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p><code>element_type</code> is <code>T</code> when <code>T</code> is not an array type, and <code>U</code> when <code>T</code> is <code>U[]</code> or <code>U[N]</code>.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_default_constructor">default constructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>constexpr shared_ptr() noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>constexpr shared_ptr(std::nullptr_t) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs an empty <code>shared_ptr</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>use_count() == 0 && get() == 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_pointer_constructor">pointer constructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> explicit shared_ptr(Y * p);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>Y</code> must be a complete type. The expression <code>delete[] p</code>, when <code>T</code> is an array type, or <code>delete p</code>, when <code>T</code> is not an array type,
- must be well-formed, well-defined, and not throw exceptions. When <code>T</code> is <code>U[N]</code>, <code>Y(*)[N]</code> must be convertible to <code>T*</code>; when <code>T</code> is <code>U[]</code>, <code>Y(*)[]</code>
- must be convertible to <code>T*</code>; otherwise, <code>Y*</code> must be convertible to <code>T*</code>.</p>
- </dd>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>When <code>T</code> is not an array type, constructs a <code>shared_ptr</code> that owns the pointer <code>p</code>. Otherwise, constructs a <code>shared_ptr</code> that owns <code>p</code> and
- a deleter of an unspecified type that calls <code>delete[] p</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>use_count() == 1 && get() == p</code>. If <code>T</code> is not an array type and <code>p</code> is unambiguously convertible to <code>enable_shared_from_this<V>*</code>
- for some <code>V</code>, <code>p->shared_from_this()</code> returns a copy of <code>*this</code>.</p>
- </dd>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p><code>std::bad_alloc</code>, or an implementation-defined exception when a resource other than memory could not be obtained.</p>
- </dd>
- <dt class="hdlist1">Exception safety</dt>
- <dd>
- <p>If an exception is thrown, the constructor calls <code>delete[] p</code>, when <code>T</code> is an array type, or <code>delete p</code>, when <code>T</code> is not an array type.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- <code>p</code> must be a pointer to an object that was allocated via a C++ <code>new</code> expression or be 0. The postcondition that use count is 1 holds even if <code>p</code>
- is 0; invoking <code>delete</code> on a pointer that has a value of 0 is harmless.
- </td>
- </tr>
- </table>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- This constructor is a template in order to remember the actual pointer type passed. The destructor will call delete with the same pointer, complete
- with its original type, even when <code>T</code> does not have a virtual destructor, or is <code>void</code>.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_constructors_taking_a_deleter">constructors taking a deleter</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y, class D> shared_ptr(Y * p, D d);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class D> shared_ptr(std::nullptr_t p, D d);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class D, class A> shared_ptr(std::nullptr_t p, D d, A a);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>D</code> must be <code>CopyConstructible</code>. The copy constructor and destructor of <code>D</code> must not throw. The expression <code>d(p)</code> must be well-formed, well-defined,
- and not throw exceptions. <code>A</code> must be an <code>Allocator</code>, as described in section Allocator Requirements [allocator.requirements] of the C++ Standard.
- When <code>T</code> is <code>U[N]</code>, <code>Y(*)[N]</code> must be convertible to <code>T*</code>; when <code>T</code> is <code>U[]</code>, <code>Y(*)[]</code> must be convertible to <code>T*</code>; otherwise, <code>Y*</code> must be convertible to <code>T*</code>.</p>
- </dd>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs a <code>shared_ptr</code> that owns the pointer <code>p</code> and the deleter <code>d</code>. The constructors taking an allocator a allocate memory using a copy of <code>a</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>use_count() == 1 && get() == p</code>. If <code>T</code> is not an array type and <code>p</code> is unambiguously convertible to <code>enable_shared_from_this<V>*</code> for some <code>V</code>,
- <code>p->shared_from_this()</code> returns a copy of <code>*this</code>.</p>
- </dd>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p><code>std::bad_alloc</code>, or an implementation-defined exception when a resource other than memory could not be obtained.</p>
- </dd>
- <dt class="hdlist1">Exception safety</dt>
- <dd>
- <p>If an exception is thrown, <code>d(p)</code> is called.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- When the the time comes to delete the object pointed to by <code>p</code>, the stored copy of <code>d</code> is invoked with the stored copy of <code>p</code> as an argument.
- </td>
- </tr>
- </table>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- Custom deallocators allow a factory function returning a <code>shared_ptr</code> to insulate the user from its memory allocation strategy. Since the deallocator
- is not part of the type, changing the allocation strategy does not break source or binary compatibility, and does not require a client recompilation. For example,
- a "no-op" deallocator is useful when returning a <code>shared_ptr</code> to a statically allocated object, and other variations allow a <code>shared_ptr</code> to be used as a wrapper
- for another smart pointer, easing interoperability.
- </td>
- </tr>
- </table>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- The requirement that the copy constructor of <code>D</code> does not throw comes from the pass by value. If the copy constructor throws, the pointer would leak.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_copy_and_converting_constructors">copy and converting constructors</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_ptr(shared_ptr const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> shared_ptr(shared_ptr<Y> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>Y*</code> should be convertible to <code>T*</code>.</p>
- </dd>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>If <code>r</code> is empty, constructs an empty <code>shared_ptr</code>; otherwise, constructs a <code>shared_ptr</code> that shares ownership with <code>r</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>get() == r.get() && use_count() == r.use_count()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_move_constructors">move constructors</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_ptr(shared_ptr && r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> shared_ptr(shared_ptr<Y> && r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>Y*</code> should be convertible to <code>T*</code>.</p>
- </dd>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Move-constructs a <code>shared_ptr</code> from <code>r</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>*this</code> contains the old value of <code>r</code>. <code>r</code> is empty and <code>r.get() == 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_aliasing_constructor">aliasing constructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> shared_ptr(shared_ptr<Y> const & r, element_type * p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Copy-constructs a <code>shared_ptr</code> from <code>r</code>, while storing <code>p</code> instead.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>get() == p && use_count() == r.use_count()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_aliasing_move_constructor">aliasing move constructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> shared_ptr(shared_ptr<Y> && r, element_type * p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Move-constructs a <code>shared_ptr</code> from <code>r</code>, while storing <code>p</code> instead.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>get() == p</code> and <code>use_count()</code> equals the old count of <code>r</code>. <code>r</code> is empty and <code>r.get() == 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_weak_ptr_constructor">weak_ptr constructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>Y*</code> should be convertible to <code>T*</code>.</p>
- </dd>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs a <code>shared_ptr</code> that shares ownership with <code>r</code> and stores a copy of the pointer stored in <code>r</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>use_count() == r.use_count()</code>.</p>
- </dd>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p><code>bad_weak_ptr</code> when <code>r.use_count() == 0</code>.</p>
- </dd>
- <dt class="hdlist1">Exception safety</dt>
- <dd>
- <p>If an exception is thrown, the constructor has no effect.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_auto_ptr_constructors">auto_ptr constructors</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> shared_ptr(std::auto_ptr<Y> & r);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> shared_ptr(std::auto_ptr<Y> && r);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>Y*</code> should be convertible to <code>T*</code>.</p>
- </dd>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs a <code>shared_ptr</code>, as if by storing a copy of <code>r.release()</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>use_count() == 1</code>.</p>
- </dd>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p><code>std::bad_alloc</code>, or an implementation-defined exception when a resource other than memory could not be obtained.</p>
- </dd>
- <dt class="hdlist1">Exception safety</dt>
- <dd>
- <p>If an exception is thrown, the constructor has no effect.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_unique_ptr_constructor">unique_ptr constructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y, class D> shared_ptr(std::unique_ptr<Y, D> && r);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>Y*</code> should be convertible to <code>T*</code>.</p>
- </dd>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <div class="ulist">
- <ul>
- <li>
- <p>When <code>r.get() == 0</code>, equivalent to <code>shared_ptr()</code>;</p>
- </li>
- <li>
- <p>When <code>D</code> is not a reference type, equivalent to <code>shared_ptr(r.release(), r.get_deleter())</code>;</p>
- </li>
- <li>
- <p>Otherwise, equivalent to <code>shared_ptr(r.release(), del)</code>, where <code>del</code> is a deleter that stores the reference <code>rd</code> returned
- from <code>r.get_deleter()</code> and <code>del(p)</code> calls <code>rd(p)</code>.</p>
- </li>
- </ul>
- </div>
- </dd>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p><code>std::bad_alloc</code>, or an implementation-defined exception when a resource other than memory could not be obtained.</p>
- </dd>
- <dt class="hdlist1">Exception safety</dt>
- <dd>
- <p>If an exception is thrown, the constructor has no effect.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_destructor">destructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>~shared_ptr() noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <div class="ulist">
- <ul>
- <li>
- <p>If <code>*this</code> is empty, or shares ownership with another <code>shared_ptr</code> instance (<code>use_count() > 1</code>), there are no side effects.</p>
- </li>
- <li>
- <p>Otherwise, if <code>*this</code> owns a pointer <code>p</code> and a deleter <code>d</code>, <code>d(p)</code> is called.</p>
- </li>
- <li>
- <p>Otherwise, <code>*this</code> owns a pointer <code>p</code>, and <code>delete p</code> is called.</p>
- </li>
- </ul>
- </div>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_assignment">assignment</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_ptr & operator=(shared_ptr const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> shared_ptr & operator=(std::auto_ptr<Y> & r);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>shared_ptr(r).swap(*this)</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>*this</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- The use count updates caused by the temporary object construction and destruction are not considered observable side effects,
- and the implementation is free to meet the effects (and the implied guarantees) via different means, without creating a temporary.
- </td>
- </tr>
- </table>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- <div class="paragraph">
- <p>In particular, in the example:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_ptr<int> p(new int);
- shared_ptr<void> q(p);
- p = p;
- q = p;</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>both assignments may be no-ops.</p>
- </div>
- </td>
- </tr>
- </table>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_ptr & operator=(shared_ptr && r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> shared_ptr & operator=(shared_ptr<Y> && r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> shared_ptr & operator=(std::auto_ptr<Y> && r);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y, class D> shared_ptr & operator=(std::unique_ptr<Y, D> && r);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>shared_ptr(std::move(r)).swap(*this)</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>*this</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_ptr & operator=(std::nullptr_t) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>shared_ptr().swap(*this)</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>*this</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_reset">reset</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>void reset() noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>shared_ptr().swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> void reset(Y * p);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>shared_ptr(p).swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y, class D> void reset(Y * p, D d);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>shared_ptr(p, d).swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y, class D, class A> void reset(Y * p, D d, A a);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>shared_ptr(p, d, a).swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> void reset(shared_ptr<Y> const & r, element_type * p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>shared_ptr(r, p).swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> void reset(shared_ptr<Y> && r, element_type * p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>shared_ptr(std::move(r), p).swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_indirection">indirection</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>T & operator*() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>T</code> should not be an array type. The stored pointer must not be 0.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>*get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>T * operator->() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>T</code> should not be an array type. The stored pointer must not be 0.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>element_type & operator[](std::ptrdiff_t i) const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>T</code> should be an array type. The stored pointer must not be 0. <code>i >= 0</code>. If <code>T</code> is <code>U[N]</code>, <code>i < N</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>get()[i]</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_get">get</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>element_type * get() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>The stored pointer.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_unique">unique</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>bool unique() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>use_count() == 1</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_use_count">use_count</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>long use_count() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>The number of <code>shared_ptr</code> objects, <code>*this</code> included, that share ownership with <code>*this</code>, or 0 when <code>*this</code> is empty.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_conversions">conversions</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>explicit operator bool() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>get() != 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- This conversion operator allows <code>shared_ptr</code> objects to be used in boolean contexts, like <code>if(p && p->valid()) {}</code>.
- </td>
- </tr>
- </table>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- The conversion to <code>bool</code> is not merely syntactic sugar. It allows <code>shared_ptr</code> variables to be declared in conditions when using
- <code>dynamic_pointer_cast</code> or <code>weak_ptr::lock</code>.
- </td>
- </tr>
- </table>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- On C++03 compilers, the return value is of an unspecified type.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_swap">swap</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>void swap(shared_ptr & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Exchanges the contents of the two smart pointers.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_owner_before">owner_before</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> bool owner_before(shared_ptr<Y> const & rhs) const noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> bool owner_before(weak_ptr<Y> const & rhs) const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>See the description of <code>operator<</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="shared_ptr_free_functions">Free Functions</h3>
- <div class="sect3">
- <h4 id="shared_ptr_comparison">comparison</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>a.get() == b.get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>a.get() != b.get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> bool operator==(shared_ptr<T> const & p, std::nullptr_t) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> bool operator==(std::nullptr_t, shared_ptr<T> const & p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>p.get() == 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> bool operator!=(shared_ptr<T> const & p, std::nullptr_t) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> bool operator!=(std::nullptr_t, shared_ptr<T> const & p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>p.get() != 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>An unspecified value such that</p>
- <div class="ulist">
- <ul>
- <li>
- <p><code>operator<</code> is a strict weak ordering as described in section [lib.alg.sorting] of the C++ standard;</p>
- </li>
- <li>
- <p>under the equivalence relation defined by <code>operator<</code>, <code>!(a < b) && !(b < a)</code>, two <code>shared_ptr</code> instances
- are equivalent if and only if they share ownership or are both empty.</p>
- </li>
- </ul>
- </div>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- Allows <code>shared_ptr</code> objects to be used as keys in associative containers.
- </td>
- </tr>
- </table>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- The rest of the comparison operators are omitted by design.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_swap_2">swap</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>a.swap(b)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_get_pointer">get_pointer</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- typename shared_ptr<T>::element_type *
- get_pointer(shared_ptr<T> const & p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>p.get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- Provided as an aid to generic programming. Used by <code>mem_fn</code>.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_static_pointer_cast">static_pointer_cast</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p>The expression <code>static_cast<T*>( (U*)0 )</code> must be well-formed.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>shared_ptr<T>( r, static_cast<typename shared_ptr<T>::element_type*>(r.get()) )</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock caution">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Caution</div>
- </td>
- <td class="content">
- The seemingly equivalent expression <code>shared_ptr<T>(static_cast<T*>(r.get()))</code> will eventually
- result in undefined behavior, attempting to delete the same object twice.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_const_pointer_cast">const_pointer_cast</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p>The expression <code>const_cast<T*>( (U*)0 )</code> must be well-formed.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>shared_ptr<T>( r, const_cast<typename shared_ptr<T>::element_type*>(r.get()) )</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_dynamic_pointer_cast">dynamic_pointer_cast</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p>The expression <code>dynamic_cast<T*>( (U*)0 )</code> must be well-formed.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <div class="ulist">
- <ul>
- <li>
- <p>When <code>dynamic_cast<typename shared_ptr<T>::element_type*>(r.get())</code> returns a nonzero value <code>p</code>, <code>shared_ptr<T>(r, p)</code>;</p>
- </li>
- <li>
- <p>Otherwise, <code>shared_ptr<T>()</code>.</p>
- </li>
- </ul>
- </div>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_reinterpret_pointer_cast">reinterpret_pointer_cast</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p>The expression <code>reinterpret_cast<T*>( (U*)0 )</code> must be well-formed.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>shared_ptr<T>( r, reinterpret_cast<typename shared_ptr<T>::element_type*>(r.get()) )</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_operator">operator<<</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class E, class T, class Y>
- std::basic_ostream<E, T> &
- operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p><code>os << p.get();</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>os</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_get_deleter">get_deleter</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class D, class T>
- D * get_deleter(shared_ptr<T> const & p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>If <code>*this</code> owns a deleter <code>d</code> of type (cv-unqualified) <code>D</code>, returns <code>&d</code>; otherwise returns 0.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_ptr_atomic_access">Atomic Access</h4>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- The function in this section are atomic with respect to the first <code>shared_ptr</code> argument,
- identified by <code>*p</code>. Concurrent access to the same <code>shared_ptr</code> instance is not a data race, if
- done exclusively by the functions in this section.
- </td>
- </tr>
- </table>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> bool atomic_is_lock_free( shared_ptr<T> const * p ) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>false</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- This implementation is not lock-free.
- </td>
- </tr>
- </table>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p ) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, int ) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>*p</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- The <code>int</code> argument is the <code>memory_order</code>, but this implementation does not use it, as it’s lock-based
- and therefore always sequentially consistent.
- </td>
- </tr>
- </table>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- void atomic_store( shared_ptr<T> * p, shared_ptr<T> r ) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, int ) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p><code>p->swap(r)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r ) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- shared_ptr<T> atomic_exchange_explicit(
- shared_ptr<T> * p, shared_ptr<T> r, int ) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p><code>p->swap(r)</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>The old value of <code>*p</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- bool atomic_compare_exchange(
- shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w ) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- bool atomic_compare_exchange_explicit(
- shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, int, int ) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>If <code>*p</code> is equivalent to <code>*v</code>, assigns <code>w</code> to <code>*p</code>, otherwise assigns <code>*p</code> to <code>*v</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>true</code> if <code>*p</code> was equivalent to <code>*v</code>, <code>false</code> otherwise.</p>
- </dd>
- <dt class="hdlist1">Remarks</dt>
- <dd>
- <p>Two <code>shared_ptr</code> instances are equivalent if they store the same pointer value and <em>share ownership</em>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="shared_ptr_example">Example</h3>
- <div class="paragraph">
- <p>See <a href="../../example/shared_ptr_example.cpp">shared_ptr_example.cpp</a> for a complete example program. The program builds a
- <code>std::vector</code> and <code>std::set</code> of <code>shared_ptr</code> objects.</p>
- </div>
- <div class="paragraph">
- <p>Note that after the containers have been populated, some of the <code>shared_ptr</code> objects will have a use count of 1 rather than
- a use count of 2, since the set is a <code>std::set</code> rather than a <code>std::multiset</code>, and thus does not contain duplicate entries.
- Furthermore, the use count may be even higher at various times while <code>push_back</code> and <code>insert</code> container operations are performed.
- More complicated yet, the container operations may throw exceptions under a variety of circumstances. Getting the memory management
- and exception handling in this example right without a smart pointer would be a nightmare.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="shared_ptr_handlebody_idiom">Handle/Body Idiom</h3>
- <div class="paragraph">
- <p>One common usage of <code>shared_ptr</code> is to implement a handle/body (also called pimpl) idiom which avoids exposing the body (implementation)
- in the header file.</p>
- </div>
- <div class="paragraph">
- <p>The <a href="../../example/shared_ptr_example2_test.cpp">shared_ptr_example2_test.cpp</a> sample program includes a header file,
- <a href="../../example/shared_ptr_example2.hpp">shared_ptr_example2.hpp</a>, which uses a <code>shared_ptr</code> to an incomplete type to hide the implementation.
- The instantiation of member functions which require a complete type occurs in the <a href="../../example/shared_ptr_example2.cpp">shared_ptr_example2.cpp</a>
- implementation file. Note that there is no need for an explicit destructor. Unlike <code>~scoped_ptr</code>, <code>~shared_ptr</code> does not require that <code>T</code> be a complete type.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="shared_ptr_thread_safety">Thread Safety</h3>
- <div class="paragraph">
- <p><code>shared_ptr</code> objects offer the same level of thread safety as built-in types. A <code>shared_ptr</code> instance can be "read" (accessed using only const operations)
- simultaneously by multiple threads. Different <code>shared_ptr</code> instances can be "written to" (accessed using mutable operations such as <code>operator=</code> or <code>reset</code>)
- simultaneously by multiple threads (even when these instances are copies, and share the same reference count underneath.)</p>
- </div>
- <div class="paragraph">
- <p>Any other simultaneous accesses result in undefined behavior.</p>
- </div>
- <div class="paragraph">
- <p>Examples:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_ptr<int> p(new int(42));</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="title">Code Example 4. Reading a <code>shared_ptr</code> from two threads</div>
- <div class="content">
- <pre class="highlight"><code>// thread A
- shared_ptr<int> p2(p); // reads p
- // thread B
- shared_ptr<int> p3(p); // OK, multiple reads are safe</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="title">Code Example 5. Writing different <code>shared_ptr</code> instances from two threads</div>
- <div class="content">
- <pre class="highlight"><code>// thread A
- p.reset(new int(1912)); // writes p
- // thread B
- p2.reset(); // OK, writes p2</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="title">Code Example 6. Reading and writing a <code>shared_ptr</code> from two threads</div>
- <div class="content">
- <pre class="highlight"><code>// thread A
- p = p3; // reads p3, writes p
- // thread B
- p3.reset(); // writes p3; undefined, simultaneous read/write</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="title">Code Example 7. Reading and destroying a <code>shared_ptr</code> from two threads</div>
- <div class="content">
- <pre class="highlight"><code>// thread A
- p3 = p2; // reads p2, writes p3
- // thread B
- // p2 goes out of scope: undefined, the destructor is considered a "write access"</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="title">Code Example 8. Writing a <code>shared_ptr</code> from two threads</div>
- <div class="content">
- <pre class="highlight"><code>// thread A
- p3.reset(new int(1));
- // thread B
- p3.reset(new int(2)); // undefined, multiple writes</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Starting with Boost release 1.33.0, <code>shared_ptr</code> uses a lock-free implementation on most common platforms.</p>
- </div>
- <div class="paragraph">
- <p>If your program is single-threaded and does not link to any libraries that might have used <code>shared_ptr</code> in its default configuration,
- you can <code>#define</code> the macro <code>BOOST_SP_DISABLE_THREADS</code> on a project-wide basis to switch to ordinary non-atomic reference count updates.</p>
- </div>
- <div class="paragraph">
- <p>(Defining <code>BOOST_SP_DISABLE_THREADS</code> in some, but not all, translation units is technically a violation of the One Definition Rule and
- undefined behavior. Nevertheless, the implementation attempts to do its best to accommodate the request to use non-atomic updates in those
- translation units. No guarantees, though.)</p>
- </div>
- <div class="paragraph">
- <p>You can define the macro <code>BOOST_SP_USE_PTHREADS</code> to turn off the lock-free platform-specific implementation and fall back to the generic
- <code>pthread_mutex_t</code>-based code.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="shared_ptr_frequently_asked_questions">Frequently Asked Questions</h3>
- <div class="qlist qanda">
- <ol>
- <li>
- <p><em>There are several variations of shared pointers, with different tradeoffs; why does the smart pointer library supply only a single implementation? It would be useful to be able to experiment with each type so as to find the most suitable for the job at hand?</em></p>
- <p>An important goal of <code>shared_ptr</code> is to provide a standard shared-ownership pointer. Having a single pointer type is important for stable
- library interfaces, since different shared pointers typically cannot interoperate, i.e. a reference counted pointer (used by library A)
- cannot share ownership with a linked pointer (used by library B.)</p>
- </li>
- <li>
- <p><em>Why doesn’t shared_ptr have template parameters supplying traits or policies to allow extensive user customization?</em></p>
- <p>Parameterization discourages users. The <code>shared_ptr</code> template is carefully crafted to meet common needs without extensive parameterization.</p>
- </li>
- <li>
- <p><em>I am not convinced. Default parameters can be used where appropriate to hide the complexity. Again, why not policies?</em></p>
- <p>Template parameters affect the type. See the answer to the first question above.</p>
- </li>
- <li>
- <p><em>Why doesn’t <code>shared_ptr</code> use a linked list implementation?</em></p>
- <p>A linked list implementation does not offer enough advantages to offset the added cost of an extra pointer. In addition, it is expensive to
- make a linked list implementation thread safe.</p>
- </li>
- <li>
- <p><em>Why doesn’t <code>shared_ptr</code> (or any of the other Boost smart pointers) supply an automatic conversion to T*?</em></p>
- <p>Automatic conversion is believed to be too error prone.</p>
- </li>
- <li>
- <p><em>Why does <code>shared_ptr</code> supply <code>use_count()</code>?</em></p>
- <p>As an aid to writing test cases and debugging displays. One of the progenitors had <code>use_count()</code>, and it was useful in tracking down bugs in
- a complex project that turned out to have cyclic-dependencies.</p>
- </li>
- <li>
- <p><em>Why doesn’t <code>shared_ptr</code> specify complexity requirements?</em></p>
- <p>Because complexity requirements limit implementors and complicate the specification without apparent benefit to <code>shared_ptr</code> users. For example,
- error-checking implementations might become non-conforming if they had to meet stringent complexity requirements.</p>
- </li>
- <li>
- <p><em>Why doesn’t <code>shared_ptr</code> provide a <code>release()</code> function?</em></p>
- <p><code>shared_ptr</code> cannot give away ownership unless it’s <code>unique()</code> because the other copy will still destroy the object.</p>
- <div class="paragraph">
- <p>Consider:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_ptr<int> a(new int);
- shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2
- int * p = a.release();
- // Who owns p now? b will still call delete on it in its destructor.</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Furthermore, the pointer returned by <code>release()</code> would be difficult to deallocate reliably, as the source <code>shared_ptr</code> could have been created with a
- custom deleter, or may have pointed to an object of a different type.</p>
- </div>
- </li>
- <li>
- <p><em>Why is <code>operator->()</code> const, but its return value is a non-const pointer to the element type?</em></p>
- <p>Shallow copy pointers, including raw pointers, typically don’t propagate constness. It makes little sense for them to do so, as you can always obtain a
- non-const pointer from a const one and then proceed to modify the object through it. <code>shared_ptr</code> is "as close to raw pointers as possible but no closer".</p>
- </li>
- </ol>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="weak_ptr">weak_ptr: Non-owning Observer</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="weak_ptr_description">Description</h3>
- <div class="paragraph">
- <p>The <code>weak_ptr</code> class template stores a "weak reference" to an object that’s already managed by a <code>shared_ptr</code>.
- To access the object, a <code>weak_ptr</code> can be converted to a <code>shared_ptr</code> using the <code>shared_ptr</code> constructor taking
- <code>weak_ptr</code>, or the <code>weak_ptr</code> member function <code>lock</code>. When the last <code>shared_ptr</code> to the object goes away and the
- object is deleted, the attempt to obtain a <code>shared_ptr</code> from the <code>weak_ptr</code> instances that refer to the deleted
- object will fail: the constructor will throw an exception of type <code>boost::bad_weak_ptr</code>, and <code>weak_ptr::lock</code> will
- return an empty <code>shared_ptr</code>.</p>
- </div>
- <div class="paragraph">
- <p>Every <code>weak_ptr</code> meets the <code>CopyConstructible</code> and <code>Assignable</code> requirements of the C++ Standard Library, and so
- can be used in standard library containers. Comparison operators are supplied so that <code>weak_ptr</code> works with the standard
- library’s associative containers.</p>
- </div>
- <div class="paragraph">
- <p><code>weak_ptr</code> operations never throw exceptions.</p>
- </div>
- <div class="paragraph">
- <p>The class template is parameterized on <code>T</code>, the type of the object pointed to.</p>
- </div>
- <div class="paragraph">
- <p>Compared to <code>shared_ptr</code>, <code>weak_ptr</code> provides a very limited subset of operations since accessing its stored pointer is
- often dangerous in multithreaded programs, and sometimes unsafe even within a single thread (that is, it may invoke undefined
- behavior.) Pretend for a moment that <code>weak_ptr</code> had a get member function that returned a raw pointer, and consider this innocent
- piece of code:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_ptr<int> p(new int(5));
- weak_ptr<int> q(p);
- // some time later
- if(int * r = q.get())
- {
- // use *r
- }</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Imagine that after the <code>if</code>, but immediately before <code>r</code> is used, another thread executes the statement <code>p.reset()</code>. Now <code>r</code> is a dangling pointer.</p>
- </div>
- <div class="paragraph">
- <p>The solution to this problem is to create a temporary <code>shared_ptr</code> from <code>q</code>:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_ptr<int> p(new int(5));
- weak_ptr<int> q(p);
- // some time later
- if(shared_ptr<int> r = q.lock())
- {
- // use *r
- }</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Now <code>r</code> holds a reference to the object that was pointed by <code>q</code>. Even if <code>p.reset()</code> is executed in another thread, the object will stay alive until
- <code>r</code> goes out of scope or is reset. By obtaining a <code>shared_ptr</code> to the object, we have effectively locked it against destruction.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="weak_ptr_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p><code>weak_ptr</code> is defined in <code><boost/smart_ptr/weak_ptr.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- template<class T> class weak_ptr {
- public:
- typedef /*see below*/ element_type;
- weak_ptr() noexcept;
- template<class Y> weak_ptr(shared_ptr<Y> const & r) noexcept;
- weak_ptr(weak_ptr const & r) noexcept;
- template<class Y> weak_ptr(weak_ptr<Y> const & r) noexcept;
- weak_ptr(weak_ptr && r) noexcept;
- template<class Y> weak_ptr(shared_ptr<Y> const & r, element_type * p) noexcept;
- template<class Y> weak_ptr(weak_ptr<Y> const & r, element_type * p) noexcept;
- template<class Y> weak_ptr(weak_ptr<Y> && r, element_type * p) noexcept;
- ~weak_ptr() noexcept;
- weak_ptr & operator=(weak_ptr const & r) noexcept;
- weak_ptr & operator=(weak_ptr && r) noexcept;
- template<class Y> weak_ptr & operator=(weak_ptr<Y> const & r) noexcept;
- template<class Y> weak_ptr & operator=(shared_ptr<Y> const & r) noexcept;
- long use_count() const noexcept;
- bool expired() const noexcept;
- bool empty() const noexcept;
- shared_ptr<T> lock() const noexcept;
- void reset() noexcept;
- void swap(weak_ptr<T> & b) noexcept;
- template<class Y> bool owner_before( weak_ptr<Y> const & r ) const noexcept;
- template<class Y> bool owner_before( shared_ptr<Y> const & r ) const noexcept;
- };
- template<class T, class U>
- bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) noexcept;
- template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) noexcept;
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="weak_ptr_members">Members</h3>
- <div class="sect3">
- <h4 id="weak_ptr_element_type">element_type</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>typedef ... element_type;</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p><code>element_type</code> is <code>T</code> when <code>T</code> is not an array type, and <code>U</code> when <code>T</code> is <code>U[]</code> or <code>U[N]</code>.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="weak_ptr_constructors">constructors</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>weak_ptr() noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs an empty <code>weak_ptr</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>use_count() == 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> weak_ptr(shared_ptr<Y> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>weak_ptr(weak_ptr const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> weak_ptr(weak_ptr<Y> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>If <code>r</code> is empty, constructs an empty <code>weak_ptr</code>; otherwise, constructs a <code>weak_ptr</code> that shares ownership with <code>r</code> as if by storing a copy of the pointer stored in <code>r</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>use_count() == r.use_count()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>weak_ptr(weak_ptr && r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs a <code>weak_ptr</code> that has the value <code>r</code> held.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>r</code> is empty.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="weak_ptr_aliasing_constructors">aliasing constructors</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> weak_ptr(shared_ptr<Y> const & r, element_type * p) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> weak_ptr(weak_ptr<Y> const & r, element_type * p) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> weak_ptr(weak_ptr<Y> && r, element_type * p) noexcept;</code></pre>
- </div>
- </div>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs a <code>weak_ptr</code> from <code>r</code> as if by using the corresponding converting/copy/move constructor, but stores <code>p</code> instead.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>use_count() == r.use_count()</code>. When <code>!expired()</code>, <code>shared_ptr<T>(*this).get() == p</code>.</p>
- </dd>
- </dl>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- These constructors are an extension, not present in <code>std::weak_ptr</code>.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="weak_ptr_destructor">destructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>~weak_ptr() noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Destroys this <code>weak_ptr</code> but has no effect on the object its stored pointer points to.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="weak_ptr_assignment">assignment</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>weak_ptr & operator=(weak_ptr const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>weak_ptr & operator=(weak_ptr && r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> weak_ptr & operator=(weak_ptr<Y> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> weak_ptr & operator=(shared_ptr<Y> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>weak_ptr(r).swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- The implementation is free to meet the effects (and the implied guarantees) via different means, without creating a temporary.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="weak_ptr_use_count">use_count</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>long use_count() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>0 if <code>*this</code> is empty; otherwise, the number of <code>shared_ptr</code> objects that share ownership with <code>*this</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="weak_ptr_expired">expired</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>bool expired() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>use_count() == 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="weak_ptr_empty">empty</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>bool empty() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>true</code> when <code>*this</code> is empty, <code>false</code> otherwise.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- This function is an extension, not present in <code>std::weak_ptr</code>.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="weak_ptr_lock">lock</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_ptr<T> lock() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>expired()? shared_ptr<T>(): shared_ptr<T>(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="weak_ptr_reset">reset</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>void reset() noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>weak_ptr().swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="weak_ptr_swap">swap</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>void swap(weak_ptr & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Exchanges the contents of the two smart pointers.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> bool owner_before( weak_ptr<Y> const & r ) const noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> bool owner_before( shared_ptr<Y> const & r ) const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>See the description of <code>operator<</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="weak_ptr_free_functions">Free Functions</h3>
- <div class="sect3">
- <h4 id="weak_ptr_comparison">comparison</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>An unspecified value such that</p>
- <div class="ulist">
- <ul>
- <li>
- <p><code>operator<</code> is a strict weak ordering as described in section [lib.alg.sorting] of the C++ standard;</p>
- </li>
- <li>
- <p>under the equivalence relation defined by <code>operator<</code>, <code>!(a < b) && !(b < a)</code>, two <code>weak_ptr</code> instances
- are equivalent if and only if they share ownership or are both empty.</p>
- </li>
- </ul>
- </div>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- Allows <code>weak_ptr</code> objects to be used as keys in associative containers.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="weak_ptr_swap_2">swap</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>a.swap(b)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="weak_ptr_frequently_asked_questions">Frequently Asked Questions</h3>
- <div class="qlist qanda">
- <ol>
- <li>
- <p><em>Can an object create a weak_ptr to itself in its constructor?</em></p>
- <p>No. A <code>weak_ptr</code> can only be created from a <code>shared_ptr</code>, and at object construction time no
- <code>shared_ptr</code> to the object exists yet. Even if you could create a temporary <code>shared_ptr</code> to <code>this</code>,
- it would go out of scope at the end of the constructor, and all <code>weak_ptr</code> instances would instantly expire.</p>
- <div class="paragraph">
- <p>The solution is to make the constructor private, and supply a factory function that returns a <code>shared_ptr</code>:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>class X
- {
- private:
- X();
- public:
- static shared_ptr<X> create()
- {
- shared_ptr<X> px(new X);
- // create weak pointers from px here
- return px;
- }
- };</code></pre>
- </div>
- </div>
- </li>
- </ol>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="make_shared">make_shared: Creating shared_ptr</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="make_shared_description">Description</h3>
- <div class="paragraph">
- <p>The function templates <code>make_shared</code> and <code>allocate_shared</code> provide convenient,
- safe and efficient ways to create <code>shared_ptr</code> objects.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="make_shared_rationale">Rationale</h3>
- <div class="paragraph">
- <p>Consistent use of <code>shared_ptr</code> can eliminate the need to use an explicit
- <code>delete</code>, but alone it provides no support in avoiding explicit <code>new</code>. There
- were repeated requests from users for a factory function that creates an
- object of a given type and returns a <code>shared_ptr</code> to it. Besides convenience
- and style, such a function is also exception safe and considerably faster
- because it can use a single allocation for both the object and its
- corresponding control block, eliminating a significant portion of
- <code>shared_ptr</code> construction overhead. This eliminates one of the major
- efficiency complaints about <code>shared_ptr</code>.</p>
- </div>
- <div class="paragraph">
- <p>The family of overloaded function templates, <code>make_shared</code> and
- <code>allocate_shared</code>, were provided to address this need. <code>make_shared</code> uses the
- global <code>operator new</code> to allocate memory, whereas <code>allocate_shared</code> uses an
- user-supplied allocator, allowing finer control.</p>
- </div>
- <div class="paragraph">
- <p>The rationale for choosing the name <code>make_shared</code> is that the expression
- <code>make_shared<Widget>()</code> can be read aloud and conveys the intended meaning.</p>
- </div>
- <div class="paragraph">
- <p>Originally the Boost function templates <code>allocate_shared</code> and <code>make_shared</code>
- were provided for scalar objects only. There was a need to have efficient
- allocation of array objects. One criticism of class template <code>shared_array</code>
- was always the lack of a utility like <code>make_shared</code> that uses only a single
- allocation. When <code>shared_ptr</code> was enhanced to support array types, additional
- overloads of <code>allocate_shared</code> and <code>make_shared</code> were provided for array
- types.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="make_shared_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p><code>make_shared</code> and <code>allocate_shared</code> are defined in
- <code><boost/smart_ptr/make_shared.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- <code>// T is not an array</code>
- template<class T, class... Args>
- shared_ptr<T> make_shared(Args&&... args);
- template<class T, class A, class... Args>
- shared_ptr<T> allocate_shared(const A& a, Args&&... args);
- <code>// T is an array of unknown bounds</code>
- template<class T>
- shared_ptr<T> make_shared(std::size_t n);
- template<class T, class A>
- shared_ptr<T> allocate_shared(const A& a, std::size_t n);
- <code>// T is an array of known bounds</code>
- template<class T>
- shared_ptr<T> make_shared();
- template<class T, class A>
- shared_ptr<T> allocate_shared(const A& a);
- <code>// T is an array of unknown bounds</code>
- template<class T> shared_ptr<T>
- make_shared(std::size_t n, const remove_extent_t<T>& v);
- template<class T, class A> shared_ptr<T>
- allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v);
- <code>// T is an array of known bounds</code>
- template<class T>
- shared_ptr<T> make_shared(const remove_extent_t<T>& v);
- template<class T, class A>
- shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v);
- <code>// T is not an array of unknown bounds</code>
- template<class T>
- shared_ptr<T> make_shared_noinit();
- template<class T, class A>
- shared_ptr<T> allocate_shared_noinit(const A& a);
- <code>// T is an array of unknown bounds</code>
- template<class T>
- shared_ptr<T> make_shared_noinit(std::size_t n);
- template<class T, class A>
- shared_ptr<T> allocate_shared_noinit(const A& a, std::size_t n);
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="make_shared_common_requirements">Common Requirements</h3>
- <div class="paragraph">
- <p>The common requirements that apply to all <code>make_shared</code> and <code>allocate_shared</code>
- overloads, unless specified otherwise, are described below.</p>
- </div>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>A</code> shall be an <em>allocator</em>. The copy constructor and destructor
- of <code>A</code> shall not throw exceptions.</p>
- </dd>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Allocates memory for an object of type <code>T</code> or <code>n</code> objects of <code>U</code>
- (if <code>T</code> is an array type of the form <code>U[]</code> and <code>n</code> is determined by
- arguments, as specified by the concrete overload). The object is initialized
- from arguments as specified by the concrete overload. Uses a rebound copy of
- <code>a</code> (for an unspecified <code>value_type</code>) to allocate memory. If an exception is
- thrown, the functions have no effect.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>shared_ptr</code> instance that stores and owns the address of the
- newly constructed object.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>r.get() != 0</code> and <code>r.use_count() == 1</code>, where <code>r</code>
- is the return value.</p>
- </dd>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p><code>std::bad_alloc</code>, an exception thrown from <code>A::allocate</code>, or from the
- initialization of the object.</p>
- </dd>
- <dt class="hdlist1">Remarks</dt>
- <dd>
- <div class="ulist">
- <ul>
- <li>
- <p>Performs no more than one memory allocation. This provides efficiency
- equivalent to an intrusive smart pointer.</p>
- </li>
- <li>
- <p>When an object of an array type is specified to be initialized to a value of
- the same type <code>v</code>, this shall be interpreted to mean that each array element
- of the object is initialized to the corresponding element from <code>v</code>.</p>
- </li>
- <li>
- <p>When an object of an array type is specified to be value-initialized, this
- shall be interpreted to mean that each array element of the object is
- value-initialized.</p>
- </li>
- <li>
- <p>When a (sub)object of non-array type <code>U</code> is specified to be initialized to
- a value <code>v</code>, or constructed from <code>args...</code>, <code>make_shared</code> shall perform
- this initialization via the expression <code>::new(p) U(expr)</code> (where
- <code><em>expr</em></code> is <code>v</code> or <code>std::forward<Args>(args)...)</code> respectively) and <code>p</code>
- has type <code>void*</code> and points to storage suitable to hold an object of type
- <code>U</code>.</p>
- </li>
- <li>
- <p>When a (sub)object of non-array type <code>U</code> is specified to be initialized to
- a value <code>v</code>, or constructed from <code>args...</code>, <code>allocate_shared</code> shall
- perform this initialization via the expression
- <code>std::allocator_traits<A2>::construct(a2, p, expr)</code> (where
- <code><em>expr</em></code> is <code>v</code> or <code>std::forward<Args>(args)...)</code> respectively), <code>p</code>
- points to storage suitable to hold an object of type <code>U</code>, and <code>a2</code> of
- type <code>A2</code> is a potentially rebound copy of <code>a</code>.</p>
- </li>
- <li>
- <p>When a (sub)object of non-array type <code>U</code> is specified to be
- default-initialized, <code>make_shared_noinit</code> and <code>allocate_shared_noinit</code> shall
- perform this initialization via the expression <code>::new(p) U</code>, where
- <code>p</code> has type <code>void*</code> and points to storage suitable to hold an object of
- type <code>U</code>.</p>
- </li>
- <li>
- <p>When a (sub)object of non-array type <code>U</code> is specified to be
- value-initialized, <code>make_shared</code> shall perform this initialization via the
- expression <code>::new(p) U()</code>, where <code>p</code> has type <code>void*</code> and points to
- storage suitable to hold an object of type <code>U</code>.</p>
- </li>
- <li>
- <p>When a (sub)object of non-array type <code>U</code> is specified to be
- value-initialized, <code>allocate_shared</code> shall perform this initialization via the
- expression <code>std::allocator_traits<A2>::construct(a2, p)</code>, where
- <code>p</code> points to storage suitable to hold an object of type <code>U</code> and <code>a2</code> of
- type <code>A2</code> is a potentially rebound copy of <code>a</code>.</p>
- </li>
- <li>
- <p>Array elements are initialized in ascending order of their addresses.</p>
- </li>
- <li>
- <p>When the lifetime of the object managed by the return value ends, or when
- the initialization of an array element throws an exception, the initialized
- elements should be destroyed in the reverse order of their construction.</p>
- </li>
- </ul>
- </div>
- </dd>
- </dl>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- These functions will typically allocate more memory than the total size
- of the element objects to allow for internal bookkeeping structures such as
- the reference counts.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect2">
- <h3 id="make_shared_free_functions">Free Functions</h3>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class... Args>
- shared_ptr<T> make_shared(Args&&... args);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A, class... Args>
- shared_ptr<T> allocate_shared(const A& a, Args&&... args);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is not an array.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>shared_ptr</code> to an object of type <code>T</code>, constructed from
- <code>args...</code>.</p>
- </dd>
- <dt class="hdlist1">Examples</dt>
- </dl>
- </div>
- </li>
- <li>
- <p><code>auto p = make_shared<int>();</code></p>
- </li>
- <li>
- <p><code>auto p = make_shared<std::vector<int> >(16, 1);</code></p>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- shared_ptr<T> make_shared(std::size_t n);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A>
- shared_ptr<T> allocate_shared(const A& a, std::size_t n);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is an array of unknown bounds.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>shared_ptr</code> to a sequence of <code>n</code> value-initialized objects of
- type <code>remove_extent_t<T></code>.</p>
- </dd>
- <dt class="hdlist1">Examples</dt>
- </dl>
- </div>
- </li>
- <li>
- <p><code>auto p = make_shared<double[]>(1024);</code></p>
- </li>
- <li>
- <p><code>auto p = make_shared<double[][2][2]>(6);</code></p>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- shared_ptr<T> make_shared();</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A>
- shared_ptr<T> allocate_shared(const A& a);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is an array of known bounds.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>shared_ptr</code> to a sequence of <code>extent_v<T></code> value-initialized
- objects of type <code>remove_extent_t<T></code>.</p>
- </dd>
- <dt class="hdlist1">Examples</dt>
- </dl>
- </div>
- </li>
- <li>
- <p><code>auto p = make_shared<double[1024]>();</code></p>
- </li>
- <li>
- <p><code>auto p = make_shared<double[6][2][2]>();</code></p>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> shared_ptr<T>
- make_shared(std::size_t n, const remove_extent_t<T>& v);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A> shared_ptr<T>
- allocate_shared(const A& a, std::size_t n, const remove_extent_t<T>& v);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is an array of unknown bounds.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>shared_ptr</code> to a sequence of <code>n</code> objects of type
- <code>remove_extent_t<T></code>, each initialized to <code>v</code>.</p>
- </dd>
- <dt class="hdlist1">Examples</dt>
- </dl>
- </div>
- </li>
- <li>
- <p><code>auto p = make_shared<double[]>(1024, 1.0);</code></p>
- </li>
- <li>
- <p><code>auto p = make_shared<double[][2]>(6, {1.0, 0.0});</code></p>
- </li>
- <li>
- <p><code>auto p = make_shared<std::vector<int>[]>(4, {1, 2});</code></p>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- shared_ptr<T> make_shared(const remove_extent_t<T>& v);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A>
- shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& v);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is an array of known bounds.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>shared_ptr</code> to a sequence of <code>extent_v<T></code> objects of type
- <code>remove_extent_t<T></code>, each initialized to <code>v</code>.</p>
- </dd>
- <dt class="hdlist1">Examples</dt>
- </dl>
- </div>
- </li>
- <li>
- <p><code>auto p = make_shared<double[1024]>(1.0);</code></p>
- </li>
- <li>
- <p><code>auto p = make_shared<double[6][2]>({1.0, 0.0});</code></p>
- </li>
- <li>
- <p><code>auto p = make_shared<std::vector<int>[4]>({1, 2});</code></p>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- shared_ptr<T> make_shared_noinit();</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A>
- shared_ptr<T> allocate_shared_noinit(const A& a);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is not an array, or is an array of known bounds.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>shared_ptr</code> to a default-initialized object of type <code>T</code>, or a
- sequence of <code>extent_v<T></code> default-initialized objects of type
- <code>remove_extent_t<T></code>, respectively.</p>
- </dd>
- <dt class="hdlist1">Example</dt>
- <dd>
- <p><code>auto p = make_shared_noinit<double[1024]>();</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- shared_ptr<T> make_shared_noinit(std::size_t n);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A>
- shared_ptr<T> allocate_shared_noinit(const A& a, std::size_t n);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is an array of unknown bounds.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>shared_ptr</code> to a sequence of <code><em>n</em></code> default-initialized objects
- of type <code>remove_extent_t<T></code>.</p>
- </dd>
- <dt class="hdlist1">Example</dt>
- <dd>
- <p><code>auto p = make_shared_noinit<double[]>(1024);</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="enable_shared_from_this">enable_shared_from_this</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="enable_shared_from_this_description">Description</h3>
- <div class="paragraph">
- <p>The class template <code>enable_shared_from_this</code> is used as a base class that allows
- a <code>shared_ptr</code> or a <code>weak_ptr</code> to the current object to be obtained from within a
- member function.</p>
- </div>
- <div class="paragraph">
- <p><code>enable_shared_from_this<T></code> defines two member functions called <code>shared_from_this</code>
- that return a <code>shared_ptr<T></code> and <code>shared_ptr<T const></code>, depending on constness, to
- <code>this</code>. It also defines two member functions called <code>weak_from_this</code> that return a
- corresponding <code>weak_ptr</code>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="enable_shared_from_this_example">Example</h3>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>#include <boost/enable_shared_from_this.hpp>
- #include <boost/shared_ptr.hpp>
- #include <cassert>
- class Y: public boost::enable_shared_from_this<Y>
- {
- public:
- boost::shared_ptr<Y> f()
- {
- return shared_from_this();
- }
- };
- int main()
- {
- boost::shared_ptr<Y> p(new Y);
- boost::shared_ptr<Y> q = p->f();
- assert(p == q);
- assert(!(p < q || q < p)); // p and q must share ownership
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="enable_shared_from_this_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p><code>enable_shared_from_this</code> is defined in <code><boost/smart_ptr/enable_shared_from_this.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- template<class T> class enable_shared_from_this {
- private:
- // exposition only
- weak_ptr<T> weak_this_;
- protected:
- enable_shared_from_this() = default;
- ~enable_shared_from_this() = default;
- enable_shared_from_this(const enable_shared_from_this&) noexcept;
- enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept;
- public:
- shared_ptr<T> shared_from_this();
- shared_ptr<T const> shared_from_this() const;
- weak_ptr<T> weak_from_this() noexcept;
- weak_ptr<T const> weak_from_this() const noexcept;
- }
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="enable_shared_from_this_members">Members</h3>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>enable_shared_from_this(enable_shared_from_this const &) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Default-constructs <code>weak_this_</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- <code>weak_this_</code> is <em>not</em> copied from the argument.
- </td>
- </tr>
- </table>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>enable_shared_from_this& operator=(enable_shared_from_this const &) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>*this</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- <code>weak_this_</code> is unchanged.
- </td>
- </tr>
- </table>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> shared_ptr<T> shared_from_this();</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> shared_ptr<T const> shared_from_this() const;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>shared_ptr<T>(weak_this_)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- These members throw <code>bad_weak_ptr</code> when <code>*this</code> is not owned by a <code>shared_ptr</code>.
- </td>
- </tr>
- </table>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- <div class="paragraph">
- <p><code>weak_this_</code> is initialized by <code>shared_ptr</code> to a copy of itself when it’s constructed by a pointer to <code>*this</code>.
- For example, in the following code:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>class Y: public boost::enable_shared_from_this<Y> {};
- int main()
- {
- boost::shared_ptr<Y> p(new Y);
- }</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>the construction of <code>p</code> will automatically initialize <code>p->weak_this_</code> to <code>p</code>.</p>
- </div>
- </td>
- </tr>
- </table>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> weak_ptr<T> weak_from_this() noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> weak_ptr<T const> weak_from_this() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>weak_this_</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- Unlike <code>shared_from_this()</code>, <code>weak_from_this()</code> is valid in a destructor
- and returns a <code>weak_ptr</code> that is <code>expired()</code> but still shares ownership
- with other <code>weak_ptr</code> instances (if any) that refer to the object.
- </td>
- </tr>
- </table>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="enable_shared_from">enable_shared_from</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="enable_shared_from_description">Description</h3>
- <div class="paragraph">
- <p><code>enable_shared_from</code> is used as a base class that allows a <code>shared_ptr</code> or a
- <code>weak_ptr</code> to be obtained given a raw pointer to the object, by using the
- functions <code>shared_from</code> and <code>weak_from</code>.</p>
- </div>
- <div class="paragraph">
- <p><code>enable_shared_from</code> differs from <code>enable_shared_from_this<T></code> by the fact
- that it’s not a template, and is its recommended replacement for new code.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="enable_shared_from_example">Example</h3>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>#include <boost/smart_ptr/enable_shared_from.hpp>
- #include <boost/shared_ptr.hpp>
- #include <cassert>
- class Y: public boost::enable_shared_from
- {
- public:
- boost::shared_ptr<Y> f()
- {
- return boost::shared_from( this );
- }
- };
- int main()
- {
- boost::shared_ptr<Y> p(new Y);
- boost::shared_ptr<Y> q = p->f();
- assert(p == q);
- assert(!(p < q || q < p)); // p and q must share ownership
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="enable_shared_from_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p><code>enable_shared_from</code> is defined in <code><boost/smart_ptr/enable_shared_from.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- class enable_shared_from: public enable_shared_from_this<enable_shared_from>
- {
- };
- template<class T> shared_ptr<T> shared_from( T * p );
- template<class T> weak_ptr<T> weak_from( T * p ) noexcept;
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="enable_shared_from_functions">Functions</h3>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> shared_ptr<T> shared_from( T * p );</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>shared_ptr<T>( p->enable_shared_from::shared_from_this(), p )</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- Throws <code>bad_weak_ptr</code> when <code>p</code> is not owned by a <code>shared_ptr</code>.
- </td>
- </tr>
- </table>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> weak_ptr<T> weak_from( T * p ) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>weak_ptr<T>( p->enable_shared_from::weak_from_this(), p )</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- Unlike <code>shared_from(this)</code>, <code>weak_from(this)</code> is valid in a destructor
- and returns a <code>weak_ptr</code> that is <code>expired()</code> but still shares ownership
- with other <code>weak_ptr</code> instances (if any) that refer to the object.
- </td>
- </tr>
- </table>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="make_unique">make_unique: Creating unique_ptr</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="make_unique_description">Description</h3>
- <div class="paragraph">
- <p>The <code>make_unique</code> function templates provide convenient and safe ways to
- create <code>std::unique_ptr</code> objects.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="make_unique_rationale">Rationale</h3>
- <div class="paragraph">
- <p>The C++11 standard introduced <code>std::unique_ptr</code> but did not provide any
- <code>make_unique</code> utility like <code>std::make_shared</code> that provided the same
- exception safety and facility to avoid writing <code>new</code> expressions. Before it
- was implemented by some standard library vendors (and prior to the C++14
- standard introducing <code>std::make_unique</code>), this library provided it due to
- requests from users.</p>
- </div>
- <div class="paragraph">
- <p>This library also provides additional overloads of <code>make_unique</code> for
- default-initialization, when users do not need or want to incur the expense
- of value-initialization. The C++ standard does not yet provide this
- feature with <code>std::make_unique</code>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="make_unique_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p><code>make_unique</code> is defined in <code><boost/smart_ptr/make_unique.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- <code>// T is not an array</code>
- template<class T, class... Args>
- std::unique_ptr<T> make_unique(Args&&... args);
- <code>// T is not an array</code>
- template<class T>
- std::unique_ptr<T> make_unique(type_identity_t<T>&& v);
- <code>// T is an array of unknown bounds</code>
- template<class T>
- std::unique_ptr<T> make_unique(std::size_t n);
- <code>// T is not an array</code>
- template<class T>
- std::unique_ptr<T> make_unique_noinit();
- <code>// T is an array of unknown bounds</code>
- template<class T>
- std::unique_ptr<T> make_unique_noinit(std::size_t n);
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="make_unique_free_functions">Free Functions</h3>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class... Args>
- std::unique_ptr<T> make_unique(Args&&... args);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is not an array.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>std::unique_ptr<T>(new T(std::forward<Args>(args)...)</code>.</p>
- </dd>
- <dt class="hdlist1">Example</dt>
- <dd>
- <p><code>auto p = make_unique<int>();</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- std::unique_ptr<T> make_unique(type_identity_t<T>&& v);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is not an array.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>std::unique_ptr<T>(new T(std::move(v))</code>.</p>
- </dd>
- <dt class="hdlist1">Example</dt>
- <dd>
- <p><code>auto p = make_unique<std::vector<int> >({1, 2});</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- std::unique_ptr<T> make_unique(std::size_t n);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is an array of unknown bounds.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>std::unique_ptr<T>(new remove_extent_t<T>[n]())</code>.</p>
- </dd>
- <dt class="hdlist1">Example</dt>
- <dd>
- <p><code>auto p = make_unique<double[]>(1024);</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- std::unique_ptr<T> make_unique_noinit();</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is not an array.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>std::unique_ptr<T>(new T)</code>.</p>
- </dd>
- <dt class="hdlist1">Example</dt>
- <dd>
- <p><code>auto p = make_unique_noinit<double[1024]>();</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- std::unique_ptr<T> make_unique_noinit(std::size_t n);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is an array of unknown bounds.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>std::unique_ptr<T>(new remove_extent_t<T>[n])</code>.</p>
- </dd>
- <dt class="hdlist1">Example</dt>
- <dd>
- <p><code>auto p = make_unique_noinit<double[]>(1024);</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="allocate_unique">allocate_unique: Creating unique_ptr</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="allocate_unique_description">Description</h3>
- <div class="paragraph">
- <p>The <code>allocate_unique</code> family of function templates provide convenient and safe
- ways to obtain a <code>std::unique_ptr</code> that manages a new object created using an
- allocator.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="allocate_unique_rationale">Rationale</h3>
- <div class="paragraph">
- <p>The C++14 standard introduced <code>std::make_unique</code> which used operator <code>new</code> to
- create new objects. However, there is no convenient facility in the standard
- library to use an allocator for the creation of the objects managed by
- <code>std::unique_ptr</code>. Users writing allocator aware code have often requested an
- <code>allocate_unique</code> factory function. This function is to <code>std::unique_ptr</code> what
- <code>std::allocate_shared</code> is to <code>std::shared_ptr</code>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="allocate_unique_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p><code>allocate_unique</code> is defined in <code><boost/smart_ptr/allocate_unique.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- template<class T, class A>
- class alloc_deleter;
- template<class T, class A>
- using alloc_noinit_deleter = alloc_deleter<T, noinit_adaptor<A>>;
- <code>// T is not an array</code>
- template<class T, class A, class... Args>
- std::unique_ptr<T, alloc_deleter<T, A>>
- allocate_unique(const A& a, Args&&... args);
- <code>// T is not an array</code>
- template<class T, class A>
- std::unique_ptr<T, alloc_deleter<T, A>>
- allocate_unique(const A& a, type_identity_t<T>&& v);
- <code>// T is an array of unknown bounds</code>
- template<class T, class A>
- std::unique_ptr<T, alloc_deleter<T, A>>
- allocate_unique(const A& a, std::size_t n);
- <code>// T is an array of known bounds</code>
- template<class T, class A>
- std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
- allocate_unique(const A& a);
- <code>// T is an array of unknown bounds</code>
- template<class T, class A>
- std::unique_ptr<T, alloc_deleter<T, A>>
- allocate_unique(const A& a, std::size_t n, const remove_extent_t<T>& v);
- <code>// T is an array of known bounds</code>
- template<class T, class A>
- std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
- allocate_unique(const A& a, const remove_extent_t<T>& v);
- <code>// T is not an array</code>
- template<class T, class A>
- std::unique_ptr<T, alloc_noinit_deleter<T, A>>
- allocate_unique_noinit(const A& a);
- <code>// T is an array of unknown bounds</code>
- template<class T, class A>
- std::unique_ptr<T, alloc_noinit_deleter<T, A>>
- allocate_unique_noinit(const A& a, std::size_t n);
- <code>// T is an array of known bounds</code>
- template<class T, class A>
- std::unique_ptr<remove_extent_t<T>[], alloc_noinit_deleter<T, A>>
- allocate_unique_noinit(const A& a);
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="allocate_unique_common_requirements">Common Requirements</h3>
- <div class="paragraph">
- <p>The common requirements that apply to all <code>allocate_unique</code> and
- <code>allocate_unique_noinit</code> overloads, unless specified otherwise, are described
- below.</p>
- </div>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>A</code> shall be an <em>allocator</em>. The copy constructor and destructor
- of <code>A</code> shall not throw exceptions.</p>
- </dd>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Allocates memory for an object of type <code>T</code> or <code>n</code> objects of <code>U</code>
- (if <code>T</code> is an array type of the form <code>U[]</code> and <code>n</code> is determined by
- arguments, as specified by the concrete overload). The object is initialized
- from arguments as specified by the concrete overload. Uses a rebound copy of
- <code>a</code> (for an unspecified <code>value_type</code>) to allocate memory. If an exception is
- thrown, the functions have no effect.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>std::unique_ptr</code> instance that stores and owns the address of the
- newly constructed object.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>r.get() != 0</code>, where <code>r</code> is the return value.</p>
- </dd>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p>An exception thrown from <code>A::allocate</code>, or from the initialization of
- the object.</p>
- </dd>
- <dt class="hdlist1">Remarks</dt>
- <dd>
- <div class="ulist">
- <ul>
- <li>
- <p>When an object of an array type is specified to be initialized to a value of
- the same type <code>v</code>, this shall be interpreted to mean that each array element
- of the object is initialized to the corresponding element from <code>v</code>.</p>
- </li>
- <li>
- <p>When an object of an array type is specified to be value-initialized, this
- shall be interpreted to mean that each array element of the object is
- value-initialized.</p>
- </li>
- <li>
- <p>When a (sub)object of non-array type <code>U</code> is specified to be initialized to a
- value <code>v</code>, or constructed from <code>args...</code>, <code>allocate_unique</code> shall perform this
- initialization via the expression
- <code>std::allocator_traits<A2>::construct(a2, p, expr)</code> (where <code><em>expr</em></code> is <code>v</code> or
- <code>std::forward<Args>(args)...)</code> respectively), <code>p</code> points to storage suitable
- to hold an object of type <code>U</code>, and <code>a2</code> of type <code>A2</code> is a potentially rebound
- copy of <code>a</code>.</p>
- </li>
- <li>
- <p>When a (sub)object of non-array type <code>U</code> is specified to be
- default-initialized, <code>allocate_unique_noinit</code> shall perform this initialization
- via the expression <code>::new(p) U</code>, where <code>p</code> has type <code>void*</code> and points to
- storage suitable to hold an object of type <code>U</code>.</p>
- </li>
- <li>
- <p>When a (sub)object of non-array type <code>U</code> is specified to be
- value-initialized, <code>allocate_unique</code> shall perform this initialization via the
- expression <code>std::allocator_traits<A2>::construct(a2, p)</code>, where <code>p</code> points to
- storage suitable to hold an object of type <code>U</code> and <code>a2</code> of type <code>A2</code> is a
- potentially rebound copy of <code>a</code>.</p>
- </li>
- <li>
- <p>Array elements are initialized in ascending order of their addresses.</p>
- </li>
- <li>
- <p>When the lifetime of the object managed by the return value ends, or when the
- initialization of an array element throws an exception, the initialized
- elements should be destroyed in the reverse order of their construction.</p>
- </li>
- </ul>
- </div>
- </dd>
- </dl>
- </div>
- </div>
- <div class="sect2">
- <h3 id="allocate_unique_free_functions">Free Functions</h3>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A, class... Args>
- std::unique_ptr<T, alloc_deleter<T, A>>
- allocate_unique(const A& a, Args&&... args);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is not an array.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>std::unique_ptr</code> to an object of type <code>T</code>, constructed from
- <code>args...</code>.</p>
- </dd>
- <dt class="hdlist1">Examples</dt>
- </dl>
- </div>
- </li>
- <li>
- <p><code>auto p = allocate_unique<int>(a);</code></p>
- </li>
- <li>
- <p><code>auto p = allocate_unique<std::vector<int>>(a, 16, 1);</code></p>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A>
- std::unique_ptr<T, alloc_deleter<T, A>>
- allocate_unique(const A& a, type_identity_t<T>&& v);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is not an array.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>std::unique_ptr</code> to an object of type <code>T</code>, constructed from <code>v</code>.</p>
- </dd>
- <dt class="hdlist1">Example</dt>
- <dd>
- <p><code>auto p = allocate_unique<std::vector<int>>(a, {1, 2});</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A>
- std::unique_ptr<T, alloc_deleter<T, A>>
- allocate_unique(const A& a, std::size_t n);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is an array of unknown bounds.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>std::unique_ptr</code> to a sequence of <code>n</code> value-initialized objects of
- type <code>remove_extent_t<T></code>.</p>
- </dd>
- <dt class="hdlist1">Examples</dt>
- </dl>
- </div>
- </li>
- <li>
- <p><code>auto p = allocate_unique<double[]>(a, 1024);</code></p>
- </li>
- <li>
- <p><code>auto p = allocate_unique<double[][2][2]>(a, 6);</code></p>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A>
- std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
- allocate_unique(const A& a);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is an array of known bounds.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>std::unique_ptr</code> to a sequence of <code>extent_v<T></code> value-initialized
- objects of type <code>remove_extent_t<T></code>.</p>
- </dd>
- <dt class="hdlist1">Examples</dt>
- </dl>
- </div>
- </li>
- <li>
- <p><code>auto p = allocate_unique<double[1024]>(a);</code></p>
- </li>
- <li>
- <p><code>auto p = allocate_unique<double[6][2][2]>(a);</code></p>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A>
- std::unique_ptr<T, alloc_deleter<T, A>>
- allocate_unique(const A& a, std::size_t n, const remove_extent_t<T>& v);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is an array of unknown bounds.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>std::unique_ptr</code> to a sequence of <code>n</code> objects of type
- <code>remove_extent_t<T></code>, each initialized to <code>v</code>.</p>
- </dd>
- <dt class="hdlist1">Examples</dt>
- </dl>
- </div>
- </li>
- <li>
- <p><code>auto p = allocate_unique<double[]>(a, 1024, 1.0);</code></p>
- </li>
- <li>
- <p><code>auto p = allocate_unique<double[][2]>(a, 6, {1.0, 0.0});</code></p>
- </li>
- <li>
- <p><code>auto p = allocate_unique<std::vector<int>[]>(a, 4, {1, 2});</code></p>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A>
- std::unique_ptr<remove_extent_t<T>[], alloc_deleter<T, A>>
- allocate_unique(const A& a, const remove_extent_t<T>& v);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is an array of known bounds.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>std::unique_ptr</code> to a sequence of <code>extent_v<T></code> objects of type
- <code>remove_extent_t<T></code>, each initialized to <code>v</code>.</p>
- </dd>
- <dt class="hdlist1">Examples</dt>
- </dl>
- </div>
- </li>
- <li>
- <p><code>auto p = allocate_unique<double[1024]>(a, 1.0);</code></p>
- </li>
- <li>
- <p><code>auto p = allocate_unique<double[6][2]>(a, {1.0, 0.0});</code></p>
- </li>
- <li>
- <p><code>auto p = allocate_unique<std::vector<int>[4]>(a, {1, 2});</code></p>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A>
- std::unique_ptr<T, alloc_noinit_deleter<T, A>>
- allocate_unique_noinit(const A& a);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is not an array.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>std::unique_ptr</code> to a default-initialized object of type <code>T</code>.</p>
- </dd>
- <dt class="hdlist1">Example</dt>
- <dd>
- <p><code>auto p = allocate_unique_noinit<double>(a);</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A>
- std::unique_ptr<T, alloc_noinit_deleter<T, A>>
- allocate_unique_noinit(const A& a, std::size_t n);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is an array of unknown bounds.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>std::unique_ptr</code> to a sequence of <code>n</code> default-initialized objects
- of type <code>remove_extent_t<T></code>.</p>
- </dd>
- <dt class="hdlist1">Example</dt>
- <dd>
- <p><code>auto p = allocate_unique_noinit<double[]>(a, 1024);</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A>
- std::unique_ptr<remove_extent_t<T>, alloc_noinit_deleter<T, A>>
- allocate_unique_noinit(const A& a);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Constraints</dt>
- <dd>
- <p><code>T</code> is an array of known bounds.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A <code>std::unique_ptr</code> to a sequence of <code>extent_v<T></code>
- default-initialized objects of type <code>remove_extent_t<T></code>.</p>
- </dd>
- <dt class="hdlist1">Example</dt>
- <dd>
- <p><code>auto p = allocate_unique_noinit<double[1024]>(a);</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect2">
- <h3 id="allocate_unique_deleter">Deleter</h3>
- <div class="paragraph">
- <p>Class template <code>alloc_deleter</code> is the deleter used by the <code>allocate_unique</code>
- functions.</p>
- </div>
- <div class="sect3">
- <h4 id="allocate_unique_synopsis_2">Synopsis</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class A>
- class alloc_deleter {
- public:
- using pointer = <code>unspecified</code>;
- explicit alloc_deleter(const A& a) noexcept;
- void operator()(pointer p);
- };</code></pre>
- </div>
- </div>
- </div>
- <div class="sect3">
- <h4 id="allocate_unique_members">Members</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>using pointer = <code>unspecified</code>;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="paragraph">
- <p>A type that satisfies <em>NullablePointer</em>.</p>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>explicit alloc_deleter(const A& a) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Initializes the stored allocator from <code>a</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>void operator()(pointer p);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Destroys the objects and deallocates the storage referenced by <code>p</code>,
- using the stored allocator.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="intrusive_ptr">intrusive_ptr: Managing Objects with Embedded Counts</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="intrusive_ptr_description">Description</h3>
- <div class="paragraph">
- <p>The <code>intrusive_ptr</code> class template stores a pointer to an object with an embedded reference count.
- Every new <code>intrusive_ptr</code> instance increments the reference count by using an unqualified call to the
- function <code>intrusive_ptr_add_ref</code>, passing it the pointer as an argument. Similarly, when an <code>intrusive_ptr</code>
- is destroyed, it calls <code>intrusive_ptr_release</code>; this function is responsible for destroying the object when
- its reference count drops to zero. The user is expected to provide suitable definitions of these two functions.
- On compilers that support argument-dependent lookup, <code>intrusive_ptr_add_ref</code> and <code>intrusive_ptr_release</code> should
- be defined in the namespace that corresponds to their parameter; otherwise, the definitions need to go in namespace
- <code>boost</code>. The library provides a helper base class template <code><a href="#intrusive_ref_counter">intrusive_ref_counter</a></code> which
- may help adding support for <code>intrusive_ptr</code> to user types.</p>
- </div>
- <div class="paragraph">
- <p>The class template is parameterized on <code>T</code>, the type of the object pointed to. <code>intrusive_ptr<T></code> can be implicitly
- converted to <code>intrusive_ptr<U></code> whenever <code>T*</code> can be implicitly converted to <code>U*</code>.</p>
- </div>
- <div class="paragraph">
- <p>The main reasons to use <code>intrusive_ptr</code> are:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p>Some existing frameworks or OSes provide objects with embedded reference counts;</p>
- </li>
- <li>
- <p>The memory footprint of <code>intrusive_ptr</code> is the same as the corresponding raw pointer;</p>
- </li>
- <li>
- <p><code>intrusive_ptr<T></code> can be constructed from an arbitrary raw pointer of type <code>T*</code>.</p>
- </li>
- </ul>
- </div>
- <div class="paragraph">
- <p>As a general rule, if it isn’t obvious whether <code>intrusive_ptr</code> better fits your needs than <code>shared_ptr</code>, try a <code>shared_ptr</code>-based design first.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="intrusive_ptr_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p><code>intrusive_ptr</code> is defined in <code><boost/smart_ptr/intrusive_ptr.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- template<class T> class intrusive_ptr {
- public:
- typedef T element_type;
- intrusive_ptr() noexcept;
- intrusive_ptr(T * p, bool add_ref = true);
- intrusive_ptr(intrusive_ptr const & r);
- template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r);
- intrusive_ptr(intrusive_ptr && r);
- template<class Y> intrusive_ptr(intrusive_ptr<Y> && r);
- ~intrusive_ptr();
- intrusive_ptr & operator=(intrusive_ptr const & r);
- template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r);
- intrusive_ptr & operator=(T * r);
- intrusive_ptr & operator=(intrusive_ptr && r);
- template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> && r);
- void reset();
- void reset(T * r);
- void reset(T * r, bool add_ref);
- T & operator*() const noexcept;
- T * operator->() const noexcept;
- T * get() const noexcept;
- T * detach() noexcept;
- explicit operator bool () const noexcept;
- void swap(intrusive_ptr & b) noexcept;
- };
- template<class T, class U>
- bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;
- template<class T, class U>
- bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;
- template<class T, class U>
- bool operator==(intrusive_ptr<T> const & a, U * b) noexcept;
- template<class T, class U>
- bool operator!=(intrusive_ptr<T> const & a, U * b) noexcept;
- template<class T, class U>
- bool operator==(T * a, intrusive_ptr<U> const & b) noexcept;
- template<class T, class U>
- bool operator!=(T * a, intrusive_ptr<U> const & b) noexcept;
- template<class T>
- bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) noexcept;
- template<class T> void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b) noexcept;
- template<class T> T * get_pointer(intrusive_ptr<T> const & p) noexcept;
- template<class T, class U>
- intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & r) noexcept;
- template<class T, class U>
- intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & r) noexcept;
- template<class T, class U>
- intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & r) noexcept;
- template<class E, class T, class Y>
- std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os,
- intrusive_ptr<Y> const & p);
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="intrusive_ptr_members">Members</h3>
- <div class="sect3">
- <h4 id="intrusive_ptr_element_type">element_type</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>typedef T element_type;</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Provides the type of the template parameter T.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ptr_constructors">constructors</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>intrusive_ptr() noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>get() == 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>intrusive_ptr(T * p, bool add_ref = true);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p><code>if(p != 0 && add_ref) intrusive_ptr_add_ref(p);</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>get() == p</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>intrusive_ptr(intrusive_ptr const & r);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> intrusive_ptr(intrusive_ptr<Y> const & r);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p><code>T * p = r.get(); if(p != 0) intrusive_ptr_add_ref(p);</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>get() == r.get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>intrusive_ptr(intrusive_ptr && r);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> intrusive_ptr(intrusive_ptr<Y> && r);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>get()</code> equals the old value of <code>r.get()</code>. <code>r.get() == 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ptr_destructor">destructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>~intrusive_ptr();</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p><code>if(get() != 0) intrusive_ptr_release(get());</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ptr_assignment">assignment</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>intrusive_ptr & operator=(intrusive_ptr const & r);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> const & r);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>intrusive_ptr & operator=(T * r);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>*this</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>intrusive_ptr & operator=(intrusive_ptr && r);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> intrusive_ptr & operator=(intrusive_ptr<Y> && r);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>intrusive_ptr(std::move(r)).swap(*this)</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>*this</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ptr_reset">reset</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>void reset();</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>intrusive_ptr().swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>void reset(T * r);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>intrusive_ptr(r).swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>void reset(T * r, bool add_ref);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>intrusive_ptr(r, add_ref).swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ptr_indirection">indirection</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>T & operator*() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requirements</dt>
- <dd>
- <p><code>get() != 0</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>*get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>T * operator->() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requirements</dt>
- <dd>
- <p><code>get() != 0</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ptr_get">get</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>T * get() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>the stored pointer.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ptr_detach">detach</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>T * detach() noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>the stored pointer.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>get() == 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- The returned pointer has an elevated reference count. This allows conversion of an <code>intrusive_ptr</code>
- back to a raw pointer, without the performance overhead of acquiring and dropping an extra reference.
- It can be viewed as the complement of the non-reference-incrementing constructor.
- </td>
- </tr>
- </table>
- </div>
- <div class="admonitionblock caution">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Caution</div>
- </td>
- <td class="content">
- Using <code>detach</code> escapes the safety of automatic reference counting provided by <code>intrusive_ptr</code>.
- It should by used only where strictly necessary (such as when interfacing to an existing API), and when
- the implications are thoroughly understood.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ptr_conversions">conversions</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>explicit operator bool () const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>get() != 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- This conversion operator allows <code>intrusive_ptr</code> objects to be used in boolean contexts,
- like <code>if (p && p->valid()) {}</code>.
- </td>
- </tr>
- </table>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- On C++03 compilers, the return value is of an unspecified type.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ptr_swap">swap</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>void swap(intrusive_ptr & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Exchanges the contents of the two smart pointers.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="intrusive_ptr_free_functions">Free Functions</h3>
- <div class="sect3">
- <h4 id="intrusive_ptr_comparison">comparison</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>a.get() == b.get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>a.get() != b.get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator==(intrusive_ptr<T> const & a, U * b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>a.get() == b</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator!=(intrusive_ptr<T> const & a, U * b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>a.get() != b</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator==(T * a, intrusive_ptr<U> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>a == b.get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator!=(T * a, intrusive_ptr<U> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>a != b.get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>std::less<T *>()(a.get(), b.get())</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- Allows <code>intrusive_ptr</code> objects to be used as keys in associative containers.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ptr_swap_2">swap</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> void swap(intrusive_ptr<T> & a, intrusive_ptr<T> & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>a.swap(b)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ptr_get_pointer">get_pointer</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> T * get_pointer(intrusive_ptr<T> const & p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>p.get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- Provided as an aid to generic programming. Used by <code>mem_fn</code>.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ptr_static_pointer_cast">static_pointer_cast</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>intrusive_ptr<T>(static_cast<T*>(r.get()))</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ptr_const_pointer_cast">const_pointer_cast</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>intrusive_ptr<T>(const_cast<T*>(r.get()))</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ptr_dynamic_pointer_cast">dynamic_pointer_cast</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>intrusive_ptr<T>(dynamic_cast<T*>(r.get()))</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ptr_operator">operator<<</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class E, class T, class Y>
- std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os,
- intrusive_ptr<Y> const & p);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p><code>os << p.get();</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>os</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="intrusive_ref_counter">intrusive_ref_counter</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="intrusive_ref_counter_description">Description</h3>
- <div class="paragraph">
- <p>The <code>intrusive_ref_counter</code> class template implements a reference counter for
- a derived user’s class that is intended to be used with <code>intrusive_ptr</code>. The
- base class has associated <code>intrusive_ptr_add_ref</code> and <code>intrusive_ptr_release</code>
- functions which modify the reference counter as needed and destroy the user’s
- object when the counter drops to zero.</p>
- </div>
- <div class="paragraph">
- <p>The class template is parameterized on <code>Derived</code> and <code>CounterPolicy</code>
- parameters. The first parameter is the user’s class that derives from
- <code>intrusive_ref_counter</code>. This type is needed in order to destroy the object
- correctly when there are no references to it left.</p>
- </div>
- <div class="paragraph">
- <p>The second parameter is a policy that defines the nature of the reference
- counter. The library provides two such policies: <code>thread_unsafe_counter</code> and
- <code>thread_safe_counter</code>. The former instructs the <code>intrusive_ref_counter</code> base
- class to use a counter only suitable for a single-threaded use. Pointers to a
- single object that uses this kind of reference counter must not be used in
- different threads. The latter policy makes the reference counter thread-safe,
- unless the target platform doesn’t support threading. Since in modern systems
- support for threading is common, the default counter policy is
- <code>thread_safe_counter</code>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="intrusive_ref_counter_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p><code>intrusive_ref_counter</code> is defined in
- <code><boost/smart_ptr/intrusive_ref_counter.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- struct thread_unsafe_counter;
- struct thread_safe_counter;
- template<class Derived, class CounterPolicy = thread_safe_counter>
- class intrusive_ref_counter {
- public:
- intrusive_ref_counter() noexcept;
- intrusive_ref_counter(const intrusive_ref_counter& v) noexcept;
- intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept;
- unsigned int use_count() const noexcept;
- protected:
- ~intrusive_ref_counter() = default;
- };
- template<class Derived, class CounterPolicy>
- void intrusive_ptr_add_ref(
- const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;
- template<class Derived, class CounterPolicy>
- void intrusive_ptr_release(
- const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="intrusive_ref_counter_members">Members</h3>
- <div class="sect3">
- <h4 id="intrusive_ref_counter_constructors">Constructors</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>intrusive_ref_counter() noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>intrusive_ref_counter(const intrusive_ref_counter&) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>use_count() == 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- The pointer to the constructed object is expected to be passed to
- <code>intrusive_ptr</code> constructor, assignment operator or <code>reset</code> method, which
- would increment the reference counter.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ref_counter_destructor">Destructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>~intrusive_ref_counter();</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Destroys the counter object.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- The destructor is protected so that the object can only be destroyed
- through the <code>Derived</code> class.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ref_counter_assignment">Assignment</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>intrusive_ref_counter& operator=(const intrusive_ref_counter& v) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Does nothing, reference counter is not modified.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ref_counter_use_count">use_count</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>unsigned int use_count() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>The current value of the reference counter.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- The returned value may not be actual in multi-threaded applications.
- </td>
- </tr>
- </table>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="intrusive_ref_counter_free_functions">Free Functions</h3>
- <div class="sect3">
- <h4 id="intrusive_ref_counter_intrusive_ptr_add_ref">intrusive_ptr_add_ref</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Derived, class CounterPolicy>
- void intrusive_ptr_add_ref(
- const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Increments the reference counter.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="intrusive_ref_counter_intrusive_ptr_release">intrusive_ptr_release</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Derived, class CounterPolicy>
- void intrusive_ptr_release(
- const intrusive_ref_counter<Derived, CounterPolicy>* p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Decrements the reference counter. If the reference counter reaches
- 0, calls <code>delete static_cast<const Derived*>(p)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="local_shared_ptr">local_shared_ptr: Shared Ownership within a Single Thread</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="local_shared_ptr_description">Description</h3>
- <div class="paragraph">
- <p><code>local_shared_ptr</code> is nearly identical to <code>shared_ptr</code>, with the only difference of note being that its reference count is
- updated with non-atomic operations. As such, a <code>local_shared_ptr</code> and all its copies must reside in (be local to) a single
- thread (hence the name.)</p>
- </div>
- <div class="paragraph">
- <p><code>local_shared_ptr</code> can be converted to <code>shared_ptr</code> and vice versa. Creating a <code>local_shared_ptr</code> from a <code>shared_ptr</code> creates
- a new local reference count; this means that two <code>local_shared_ptr</code> instances, both created from the same <code>shared_ptr</code>, refer
- to the same object but don’t share the same count, and as such, can safely be used by two different threads.</p>
- </div>
- <div class="listingblock">
- <div class="title">Code Example 9. Two local_shared_ptr instances created from a shared_ptr</div>
- <div class="content">
- <pre class="highlight"><code>shared_ptr<X> p1( new X );
- local_shared_ptr<X> p2( p1 ); // p2.local_use_count() == 1
- local_shared_ptr<X> p3( p1 ); // p3.local_use_count() also 1</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Creating the second <code>local_shared_ptr</code> from the first one, however, does lead to the two sharing the same count:</p>
- </div>
- <div class="listingblock">
- <div class="title">Code Example 10. A local_shared_ptr created from another local_shared_ptr</div>
- <div class="content">
- <pre class="highlight"><code>shared_ptr<X> p1( new X );
- local_shared_ptr<X> p2( p1 ); // p2.local_use_count() == 1
- local_shared_ptr<X> p3( p2 ); // p3.local_use_count() == 2</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Two <code>shared_ptr</code> instances created from the same <code>local_shared_ptr</code> do share ownership:</p>
- </div>
- <div class="listingblock">
- <div class="title">Code Example 11. Two shared_ptr instances created from a local_shared_ptr</div>
- <div class="content">
- <pre class="highlight"><code>local_shared_ptr<X> p1( new X );
- shared_ptr<X> p2( p1 ); // p2.use_count() == 2
- shared_ptr<X> p3( p1 ); // p3.use_count() == 3</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Here <code>p2.use_count()</code> is 2, because <code>p1</code> holds a reference, too.</p>
- </div>
- <div class="paragraph">
- <p>One can think of <code>local_shared_ptr<T></code> as <code>shared_ptr<shared_ptr<T>></code>, with the outer <code>shared_ptr</code> using non-atomic operations for
- its count. Converting from <code>local_shared_ptr</code> to <code>shared_ptr</code> gives you a copy of the inner <code>shared_ptr</code>; converting from <code>shared_ptr</code>
- wraps it into an outer <code>shared_ptr</code> with a non-atomic use count (conceptually speaking) and returns the result.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="local_shared_ptr_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p><code>local_shared_ptr</code> is defined in <code><boost/smart_ptr/local_shared_ptr.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- template<class T> class local_shared_ptr {
- public:
- typedef /*see below*/ element_type;
- // constructors
- constexpr local_shared_ptr() noexcept;
- constexpr local_shared_ptr(std::nullptr_t) noexcept;
- template<class Y> explicit local_shared_ptr(Y * p);
- template<class Y, class D> local_shared_ptr(Y * p, D d);
- template<class D> local_shared_ptr(std::nullptr_t p, D d);
- template<class Y, class D, class A> local_shared_ptr(Y * p, D d, A a);
- template<class D, class A> local_shared_ptr(std::nullptr_t p, D d, A a);
- local_shared_ptr(local_shared_ptr const & r) noexcept;
- template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r) noexcept;
- local_shared_ptr(local_shared_ptr && r) noexcept;
- template<class Y> local_shared_ptr(local_shared_ptr<Y> && r) noexcept;
- template<class Y> local_shared_ptr( shared_ptr<Y> const & r );
- template<class Y> local_shared_ptr( shared_ptr<Y> && r );
- template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r, element_type * p) noexcept;
- template<class Y> local_shared_ptr(local_shared_ptr<Y> && r, element_type * p) noexcept;
- template<class Y, class D> local_shared_ptr(std::unique_ptr<Y, D> && r);
- // destructor
- ~local_shared_ptr() noexcept;
- // assignment
- local_shared_ptr & operator=(local_shared_ptr const & r) noexcept;
- template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> const & r) noexcept;
- local_shared_ptr & operator=(local_shared_ptr const && r) noexcept;
- template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> const && r) noexcept;
- template<class Y, class D> local_shared_ptr & operator=(std::unique_ptr<Y, D> && r);
- local_shared_ptr & operator=(std::nullptr_t) noexcept;
- // reset
- void reset() noexcept;
- template<class Y> void reset(Y * p);
- template<class Y, class D> void reset(Y * p, D d);
- template<class Y, class D, class A> void reset(Y * p, D d, A a);
- template<class Y> void reset(local_shared_ptr<Y> const & r, element_type * p) noexcept;
- template<class Y> void reset(local_shared_ptr<Y> && r, element_type * p) noexcept;
- // accessors
- T & operator*() const noexcept; // only valid when T is not an array type
- T * operator->() const noexcept; // only valid when T is not an array type
- // only valid when T is an array type
- element_type & operator[](std::ptrdiff_t i) const noexcept;
- element_type * get() const noexcept;
- long local_use_count() const noexcept;
- // conversions
- explicit operator bool() const noexcept;
- template<class Y> operator shared_ptr<Y>() const noexcept;
- template<class Y> operator weak_ptr<Y>() const noexcept;
- // swap
- void swap(local_shared_ptr & b) noexcept;
- // owner_before
- template<class Y> bool owner_before(local_shared_ptr<Y> const & rhs) const noexcept;
- };
- // comparisons
- template<class T, class U>
- bool operator==(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
- template<class T, class U>
- bool operator==(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;
- template<class T, class U>
- bool operator==(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
- template<class T, class U>
- bool operator!=(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
- template<class T, class U>
- bool operator!=(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;
- template<class T, class U>
- bool operator!=(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
- template<class T> bool operator==(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;
- template<class T> bool operator==(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;
- template<class T> bool operator!=(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;
- template<class T> bool operator!=(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;
- template<class T, class U>
- bool operator<(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;
- // swap
- template<class T> void swap(local_shared_ptr<T> & a, local_shared_ptr<T> & b) noexcept;
- // get_pointer
- template<class T>
- typename local_shared_ptr<T>::element_type *
- get_pointer(local_shared_ptr<T> const & p) noexcept;
- // casts
- template<class T, class U>
- local_shared_ptr<T> static_pointer_cast(local_shared_ptr<U> const & r) noexcept;
- template<class T, class U>
- local_shared_ptr<T> const_pointer_cast(local_shared_ptr<U> const & r) noexcept;
- template<class T, class U>
- local_shared_ptr<T> dynamic_pointer_cast(local_shared_ptr<U> const & r) noexcept;
- template<class T, class U>
- local_shared_ptr<T> reinterpret_pointer_cast(local_shared_ptr<U> const & r) noexcept;
- // stream I/O
- template<class E, class T, class Y>
- std::basic_ostream<E, T> &
- operator<< (std::basic_ostream<E, T> & os, local_shared_ptr<Y> const & p);
- // get_deleter
- template<class D, class T> D * get_deleter(local_shared_ptr<T> const & p) noexcept;
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="local_shared_ptr_members">Members</h3>
- <div class="sect3">
- <h4 id="local_shared_ptr_element_type">element_type</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>typedef ... element_type;</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p><code>element_type</code> is <code>T</code> when <code>T</code> is not an array type, and <code>U</code> when <code>T</code> is <code>U[]</code> or <code>U[N]</code>.</p>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_default_constructor">default constructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>constexpr local_shared_ptr() noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>constexpr local_shared_ptr(std::nullptr_t) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs an empty <code>local_shared_ptr</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>local_use_count() == 0 && get() == 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_pointer_constructor">pointer constructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> explicit local_shared_ptr(Y * p);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs a <code>local_shared_ptr</code> that owns <code>shared_ptr<T>( p )</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>local_use_count() == 1 && get() == p</code>.</p>
- </dd>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p><code>std::bad_alloc</code>, or an implementation-defined exception when a resource other than memory could not be obtained.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_constructors_taking_a_deleter">constructors taking a deleter</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y, class D> local_shared_ptr(Y * p, D d);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class D> local_shared_ptr(std::nullptr_t p, D d);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs a <code>local_shared_ptr</code> that owns <code>shared_ptr<T>( p, d )</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>local_use_count() == 1 && get() == p</code>.</p>
- </dd>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p><code>std::bad_alloc</code>, or an implementation-defined exception when a resource other than memory could not be obtained.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y, class D, class A> local_shared_ptr(Y * p, D d, A a);</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class D, class A> local_shared_ptr(std::nullptr_t p, D d, A a);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs a <code>local_shared_ptr</code> that owns <code>shared_ptr<T>( p, d, a )</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>local_use_count() == 1 && get() == p</code>.</p>
- </dd>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p><code>std::bad_alloc</code>, or an implementation-defined exception when a resource other than memory could not be obtained.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_copy_and_converting_constructors">copy and converting constructors</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>local_shared_ptr(local_shared_ptr const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>Y*</code> should be convertible to <code>T*</code>.</p>
- </dd>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>If <code>r</code> is empty, constructs an empty <code>local_shared_ptr</code>; otherwise, constructs a <code>local_shared_ptr</code> that shares ownership with <code>r</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>get() == r.get() && local_use_count() == r.local_use_count()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_move_constructors">move constructors</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>local_shared_ptr(local_shared_ptr && r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> local_shared_ptr(local_shared_ptr<Y> && r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>Y*</code> should be convertible to <code>T*</code>.</p>
- </dd>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Move-constructs a <code>local_shared_ptr</code> from <code>r</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>*this</code> contains the old value of <code>r</code>. <code>r</code> is empty and <code>r.get() == 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_shared_ptr_constructor">shared_ptr constructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> local_shared_ptr( shared_ptr<Y> const & r );</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> local_shared_ptr( shared_ptr<Y> && r );</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs a <code>local_shared_ptr</code> that owns <code>r</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>local_use_count() == 1</code>. <code>get()</code> returns the old value of <code>r.get()</code>.</p>
- </dd>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p><code>std::bad_alloc</code>, or an implementation-defined exception when a resource other than memory could not be obtained.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_aliasing_constructor">aliasing constructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> local_shared_ptr(local_shared_ptr<Y> const & r, element_type * p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>constructs a <code>local_shared_ptr</code> that shares ownership with <code>r</code> and stores <code>p</code>.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>get() == p && local_use_count() == r.local_use_count()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_aliasing_move_constructor">aliasing move constructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> local_shared_ptr(local_shared_ptr<Y> && r, element_type * p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Move-constructs a <code>local_shared_ptr</code> from <code>r</code>, while storing <code>p</code> instead.</p>
- </dd>
- <dt class="hdlist1">Postconditions</dt>
- <dd>
- <p><code>get() == p</code> and <code>local_use_count()</code> equals the old count of <code>r</code>. <code>r</code> is empty and <code>r.get() == 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_unique_ptr_constructor">unique_ptr constructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y, class D> local_shared_ptr(std::unique_ptr<Y, D> && r);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>Y*</code> should be convertible to <code>T*</code>.</p>
- </dd>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <div class="ulist">
- <ul>
- <li>
- <p>When <code>r.get() == 0</code>, equivalent to <code>local_shared_ptr()</code>;</p>
- </li>
- <li>
- <p>Otherwise, constructs a <code>local_shared_ptr</code> that owns <code>shared_ptr<T>( std::move(r) )</code>.</p>
- </li>
- </ul>
- </div>
- </dd>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p><code>std::bad_alloc</code>, or an implementation-defined exception when a resource other than memory could not be obtained.</p>
- </dd>
- <dt class="hdlist1">Exception safety</dt>
- <dd>
- <p>If an exception is thrown, the constructor has no effect.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_destructor">destructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>~local_shared_ptr() noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <div class="ulist">
- <ul>
- <li>
- <p>If <code>*this</code> is empty, or shares ownership with another <code>local_shared_ptr</code> instance (<code>local_use_count() > 1</code>), there are no side effects.</p>
- </li>
- <li>
- <p>Otherwise, destroys the owned <code>shared_ptr</code>.</p>
- </li>
- </ul>
- </div>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_assignment">assignment</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>local_shared_ptr & operator=(local_shared_ptr const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>local_shared_ptr(r).swap(*this)</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>*this</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>local_shared_ptr & operator=(local_shared_ptr && r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> local_shared_ptr & operator=(local_shared_ptr<Y> && r) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y, class D> local_shared_ptr & operator=(std::unique_ptr<Y, D> && r);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>local_shared_ptr(std::move(r)).swap(*this)</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>*this</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>local_shared_ptr & operator=(std::nullptr_t) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>local_shared_ptr().swap(*this)</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>*this</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_reset">reset</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>void reset() noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>local_shared_ptr().swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> void reset(Y * p);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>local_shared_ptr(p).swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y, class D> void reset(Y * p, D d);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>local_shared_ptr(p, d).swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y, class D, class A> void reset(Y * p, D d, A a);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>local_shared_ptr(p, d, a).swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> void reset(local_shared_ptr<Y> const & r, element_type * p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>local_shared_ptr(r, p).swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> void reset(local_shared_ptr<Y> && r, element_type * p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>local_shared_ptr(std::move(r), p).swap(*this)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_indirection">indirection</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>T & operator*() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>T</code> should not be an array type.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>*get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>T * operator->() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>T</code> should not be an array type.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>element_type & operator[](std::ptrdiff_t i) const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>T</code> should be an array type. The stored pointer must not be 0. <code>i >= 0</code>. If <code>T</code> is <code>U[N]</code>, <code>i < N</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>get()[i]</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_get">get</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>element_type * get() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>The stored pointer.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_local_use_count">local_use_count</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>long local_use_count() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>The number of <code>local_shared_ptr</code> objects, <code>*this</code> included, that share ownership with <code>*this</code>, or 0 when <code>*this</code> is empty.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_conversions">conversions</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>explicit operator bool() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>get() != 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- On C++03 compilers, the return value is of an unspecified type.
- </td>
- </tr>
- </table>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> operator shared_ptr<Y>() const noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> operator weak_ptr<Y>() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>T*</code> should be convertible to <code>Y*</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>a copy of the owned <code>shared_ptr</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_swap">swap</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>void swap(local_shared_ptr & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Exchanges the contents of the two smart pointers.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_owner_before">owner_before</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class Y> bool owner_before(local_shared_ptr<Y> const & rhs) const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>See the description of <code>operator<</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="local_shared_ptr_free_functions">Free Functions</h3>
- <div class="sect3">
- <h4 id="local_shared_ptr_comparison">comparison</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator==(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator==(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator==(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>a.get() == b.get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator!=(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator!=(local_shared_ptr<T> const & a, shared_ptr<U> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator!=(shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>a.get() != b.get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> bool operator==(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> bool operator==(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>p.get() == 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> bool operator!=(local_shared_ptr<T> const & p, std::nullptr_t) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> bool operator!=(std::nullptr_t, local_shared_ptr<T> const & p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>p.get() != 0</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- bool operator<(local_shared_ptr<T> const & a, local_shared_ptr<U> const & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>An unspecified value such that</p>
- <div class="ulist">
- <ul>
- <li>
- <p><code>operator<</code> is a strict weak ordering as described in section [lib.alg.sorting] of the C++ standard;</p>
- </li>
- <li>
- <p>under the equivalence relation defined by <code>operator<</code>, <code>!(a < b) && !(b < a)</code>, two <code>local_shared_ptr</code> instances
- are equivalent if and only if they share ownership or are both empty.</p>
- </li>
- </ul>
- </div>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- Allows <code>local_shared_ptr</code> objects to be used as keys in associative containers.
- </td>
- </tr>
- </table>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- The rest of the comparison operators are omitted by design.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_swap_2">swap</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> void swap(local_shared_ptr<T> & a, local_shared_ptr<T> & b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Equivalent to <code>a.swap(b)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_get_pointer">get_pointer</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- typename local_shared_ptr<T>::element_type *
- get_pointer(local_shared_ptr<T> const & p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>p.get()</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- Provided as an aid to generic programming. Used by <code>mem_fn</code>.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_static_pointer_cast">static_pointer_cast</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- local_shared_ptr<T> static_pointer_cast(local_shared_ptr<U> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p>The expression <code>static_cast<T*>( (U*)0 )</code> must be well-formed.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>local_shared_ptr<T>( r, static_cast<typename local_shared_ptr<T>::element_type*>(r.get()) )</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock caution">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Caution</div>
- </td>
- <td class="content">
- The seemingly equivalent expression <code>local_shared_ptr<T>(static_cast<T*>(r.get()))</code> will eventually
- result in undefined behavior, attempting to delete the same object twice.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_const_pointer_cast">const_pointer_cast</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- local_shared_ptr<T> const_pointer_cast(local_shared_ptr<U> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p>The expression <code>const_cast<T*>( (U*)0 )</code> must be well-formed.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>local_shared_ptr<T>( r, const_cast<typename local_shared_ptr<T>::element_type*>(r.get()) )</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_dynamic_pointer_cast">dynamic_pointer_cast</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- local_shared_ptr<T> dynamic_pointer_cast(local_shared_ptr<U> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p>The expression <code>dynamic_cast<T*>( (U*)0 )</code> must be well-formed.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <div class="ulist">
- <ul>
- <li>
- <p>When <code>dynamic_cast<typename local_shared_ptr<T>::element_type*>(r.get())</code> returns a nonzero value <code>p</code>, <code>local_shared_ptr<T>(r, p)</code>;</p>
- </li>
- <li>
- <p>Otherwise, <code>local_shared_ptr<T>()</code>.</p>
- </li>
- </ul>
- </div>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_reinterpret_pointer_cast">reinterpret_pointer_cast</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- local_shared_ptr<T> reinterpret_pointer_cast(local_shared_ptr<U> const & r) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p>The expression <code>reinterpret_cast<T*>( (U*)0 )</code> must be well-formed.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>local_shared_ptr<T>( r, reinterpret_cast<typename local_shared_ptr<T>::element_type*>(r.get()) )</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_operator">operator<<</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class E, class T, class Y>
- std::basic_ostream<E, T> &
- operator<< (std::basic_ostream<E, T> & os, local_shared_ptr<Y> const & p);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p><code>os << p.get();</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>os</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="local_shared_ptr_get_deleter">get_deleter</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class D, class T>
- D * get_deleter(local_shared_ptr<T> const & p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>If <code>*this</code> owns a <code>shared_ptr</code> instance <code>p</code>, <code>get_deleter<D>( p )</code>, otherwise 0.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="make_local_shared">make_local_shared: Creating local_shared_ptr</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="make_local_shared_description">Description</h3>
- <div class="paragraph">
- <p>The function templates <code>make_local_shared</code> and <code>allocate_local_shared</code> provide
- convenient, safe and efficient ways to create <code>local_shared_ptr</code> objects. They
- are analogous to <code>make_shared</code> and <code>allocate_shared</code> for <code>shared_ptr</code>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="make_local_shared_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p><code>make_local_shared</code> and <code>allocate_local_shared</code> are defined in
- <code><boost/smart_ptr/make_local_shared.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- <code>// T is not an array</code>
- template<class T, class... Args>
- local_shared_ptr<T> make_local_shared(Args&&... args);
- template<class T, class A, class... Args>
- local_shared_ptr<T> allocate_local_shared(const A& a, Args&&... args);
- <code>// T is an array of unknown bounds</code>
- template<class T>
- local_shared_ptr<T> make_local_shared(std::size_t n);
- template<class T, class A>
- local_shared_ptr<T> allocate_local_shared(const A& a, std::size_t n);
- <code>// T is an array of known bounds</code>
- template<class T>
- local_shared_ptr<T> make_local_shared();
- template<class T, class A>
- local_shared_ptr<T> allocate_local_shared(const A& a);
- <code>// T is an array of unknown bounds</code>
- template<class T>
- local_shared_ptr<T> make_local_shared(std::size_t n,
- const remove_extent_t<T>& v);
- template<class T, class A>
- local_shared_ptr<T> allocate_local_shared(const A& a, std::size_t n,
- const remove_extent_t<T>& v);
- <code>// T is an array of known bounds</code>
- template<class T>
- local_shared_ptr<T> make_local_shared(const remove_extent_t<T>& v);
- template<class T, class A>
- local_shared_ptr<T> allocate_local_shared(const A& a,
- const remove_extent_t<T>& v);
- <code>// T is not an array of known bounds</code>
- template<class T>
- local_shared_ptr<T> make_local_shared_noinit();
- template<class T, class A>
- local_shared_ptr<T> allocate_local_shared_noinit(const A& a);
- <code>// T is an array of unknown bounds</code>
- template<class T>
- local_shared_ptr<T> make_local_shared_noinit(std::size_t n);
- template<class T, class A>
- local_shared_ptr<T> allocate_local_shared_noinit(const A& a,
- std::size_t n);
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="make_local_shared_description_2">Description</h3>
- <div class="paragraph">
- <p>The requirements and effects of these functions are the same as <code>make_shared</code>
- and <code>allocate_shared</code>, except that a <code>local_shared_ptr</code> is returned.</p>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="pointer_cast">Generic Pointer Casts</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="pointer_cast_description">Description</h3>
- <div class="paragraph">
- <p>The pointer cast function templates (<code>static_pointer_cast</code>,
- <code>dynamic_pointer_cast</code>, <code>const_pointer_cast</code>, and <code>reinterpret_pointer_cast</code>)
- provide a way to write generic pointer castings for raw pointers,
- <code>std::shared_ptr</code> and <code>std::unique_ptr</code>.</p>
- </div>
- <div class="paragraph">
- <p>There is test and example code in
- <a href="../../test/pointer_cast_test.cpp">pointer_cast_test.cpp</a></p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="pointer_cast_rationale">Rationale</h3>
- <div class="paragraph">
- <p>Boost smart pointers usually overload those functions to provide a mechanism
- to emulate pointers casts. For example, <code>shared_ptr<T></code> implements a static
- pointer cast this way:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U>
- shared_ptr<T> static_pointer_cast(const shared_ptr<U>& p);</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Pointer cast functions templates are overloads of <code>static_pointer_cast</code>,
- <code>dynamic_pointer_cast</code>, <code>const_pointer_cast</code>, and <code>reinterpret_pointer_cast</code>
- for raw pointers, <code>std::shared_ptr</code> and <code>std::unique_ptr</code>. This way when
- developing pointer type independent classes, for example, memory managers or
- shared memory compatible classes, the same code can be used for raw and smart
- pointers.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="pointer_cast_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p>The generic pointer casts are defined in <code><boost/pointer_cast.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- template<class T, class U> T* static_pointer_cast(U* p) noexcept;
- template<class T, class U> T* dynamic_pointer_cast(U* p) noexcept;
- template<class T, class U> T* const_pointer_cast(U* p) noexcept;
- template<class T, class U> T* reinterpret_pointer_cast(U* p) noexcept;
- template<class T, class U> std::shared_ptr<T>
- static_pointer_cast(const std::shared_ptr<U>& p) noexcept;
- template<class T, class U> std::shared_ptr<T>
- dynamic_pointer_cast(const std::shared_ptr<U>& p) noexcept;
- template<class T, class U> std::shared_ptr<T>
- const_pointer_cast(const std::shared_ptr<U>& p) noexcept;
- template<class T, class U> std::shared_ptr<T>
- reinterpret_pointer_cast(const std::shared_ptr<U>& p) noexcept;
- template<class T, class U> std::unique_ptr<T>
- static_pointer_cast(std::unique_ptr<U>&& p) noexcept;
- template<class T, class U> std::unique_ptr<T>
- dynamic_pointer_cast(std::unique_ptr<U>&& p) noexcept;
- template<class T, class U> std::unique_ptr<T>
- const_pointer_cast(std::unique_ptr<U>&& p) noexcept;
- template<class T, class U> std::unique_ptr<T>
- reinterpret_pointer_cast(std::unique_ptr<U>&& p) noexcept;
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="pointer_cast_free_functions">Free Functions</h3>
- <div class="sect3">
- <h4 id="pointer_cast_static_pointer_cast">static_pointer_cast</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U> T* static_pointer_cast(U* p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>static_cast<T*>(p)</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U> std::shared_ptr<T>
- static_pointer_cast(const std::shared_ptr<U>& p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>std::static_pointer_cast<T>(p)</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U> std::unique_ptr<T>
- static_pointer_cast(std::unique_ptr<U>&& p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p>The expression <code>static_cast<T*>((U*)0)</code> must be well-formed.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>std::unique_ptr<T>(static_cast<typename
- std::unique_ptr<T>::element_type*>(p.release()))</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock caution">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Caution</div>
- </td>
- <td class="content">
- The seemingly equivalent expression
- <code>std::unique_ptr<T>(static_cast<T*>(p.get()))</code> will eventually result in
- undefined behavior, attempting to delete the same object twice.
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="pointer_cast_dynamic_pointer_cast">dynamic_pointer_cast</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U> T* dynamic_pointer_cast(U* p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>dynamic_cast<T*>(p)</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U> std::shared_ptr<T>
- dynamic_pointer_cast(const std::shared_ptr<U>& p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>std::dynamic_pointer_cast<T>(p)</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U> std::unique_ptr<T>
- dynamic_pointer_cast(std::unique_ptr<U>&& p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- </dl>
- </div>
- </li>
- <li>
- <p>The expression <code>static_cast<T*>((U*)0)</code> must be well-formed.</p>
- </li>
- <li>
- <p><code>T</code> must have a virtual destructor.</p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- </dl>
- </div>
- </li>
- <li>
- <p>When <code>dynamic_cast<typename std::unique_ptr<T>::element_type*>(p.get())</code>
- returns a non-zero value, <code>std::unique_ptr<T>(dynamic_cast<typename
- std::unique_ptr<T>::element_type*>(p.release()));</code>.</p>
- </li>
- <li>
- <p>Otherwise, <code>std::unique_ptr<T>()</code>.</p>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="pointer_cast_const_pointer_cast">const_pointer_cast</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U> T* const_pointer_cast(U* p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>const_cast<T*>(p)</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U> std::shared_ptr<T>
- const_pointer_cast(const std::shared_ptr<U>& p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>std::const_pointer_cast<T>(p)</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U> std::unique_ptr<T>
- const_pointer_cast(std::unique_ptr<U>&& p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p>The expression <code>const_cast<T*>((U*)0)</code> must be well-formed.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>std::unique_ptr<T>(const_cast<typename
- std::unique_ptr<T>::element_type*>(p.release()))</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="pointer_cast_reinterpret_pointer_cast">reinterpret_pointer_cast</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U> T* reinterpret_pointer_cast(U* p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>reinterpret_cast<T*>(p)</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U> std::shared_ptr<T>
- reinterpret_pointer_cast(const std::shared_ptr<U>& p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>std::reinterpret_pointer_cast<T>(p)</code></p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T, class U> std::unique_ptr<T>
- reinterpret_pointer_cast(std::unique_ptr<U>&& p) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p>The expression <code>reinterpret_cast<T*>((U*)0)</code> must be well-formed.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>std::unique_ptr<T>(reinterpret_cast<typename
- std::unique_ptr<T>::element_type*>(p.release()))</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="pointer_cast_example">Example</h3>
- <div class="paragraph">
- <p>The following example demonstrates how the generic pointer casts help us
- create pointer independent code.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>#include <boost/pointer_cast.hpp>
- #include <boost/shared_ptr.hpp>
- class base {
- public:
- virtual ~base() { }
- };
- class derived : public base { };
- template<class Ptr>
- void check_if_it_is_derived(const Ptr& ptr)
- {
- assert(boost::dynamic_pointer_cast<derived>(ptr) != 0);
- }
- int main()
- {
- base* ptr = new derived;
- boost::shared_ptr<base> sptr(new derived);
- check_if_it_is_derived(ptr);
- check_if_it_is_derived(sptr);
- delete ptr;
- }</code></pre>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="pointer_to_other">pointer_to_other</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="pointer_to_other_description">Description</h3>
- <div class="paragraph">
- <p>The <code>pointer_to_other</code> utility provides a way, given a source pointer type, to obtain a pointer of the same type
- to another pointee type.</p>
- </div>
- <div class="paragraph">
- <p>There is test/example code in <a href="../../test/pointer_to_other_test.cpp">pointer_to_other_test.cpp</a>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="pointer_to_other_rationale">Rationale</h3>
- <div class="paragraph">
- <p>When building pointer independent classes, like memory managers, allocators, or containers, there is often a need to
- define pointers generically, so that if a template parameter represents a pointer (for example, a raw or smart pointer
- to an <code>int</code>), we can define another pointer of the same type to another pointee (a raw or smart pointer to a <code>float</code>.)</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template <class IntPtr> class FloatPointerHolder
- {
- // Let's define a pointer to a float
- typedef typename boost::pointer_to_other
- <IntPtr, float>::type float_ptr_t;
- float_ptr_t float_ptr;
- };</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="pointer_to_other_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p><code>pointer_to_other</code> is defined in <code><boost/smart_ptr/pointer_to_other.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- template<class T, class U> struct pointer_to_other;
- template<class T, class U,
- template <class> class Sp>
- struct pointer_to_other< Sp<T>, U >
- {
- typedef Sp<U> type;
- };
- template<class T, class T2, class U,
- template <class, class> class Sp>
- struct pointer_to_other< Sp<T, T2>, U >
- {
- typedef Sp<U, T2> type;
- };
- template<class T, class T2, class T3, class U,
- template <class, class, class> class Sp>
- struct pointer_to_other< Sp<T, T2, T3>, U >
- {
- typedef Sp<U, T2, T3> type;
- };
- template<class T, class U>
- struct pointer_to_other< T*, U >
- {
- typedef U* type;
- };
- }</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>If these definitions are not correct for a specific smart pointer, we can define a specialization of <code>pointer_to_other</code>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="pointer_to_other_example">Example</h3>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>// Let's define a memory allocator that can
- // work with raw and smart pointers
- #include <boost/pointer_to_other.hpp>
- template <class VoidPtr>
- class memory_allocator
- {
- // Predefine a memory_block
- struct block;
- // Define a pointer to a memory_block from a void pointer
- // If VoidPtr is void *, block_ptr_t is block*
- // If VoidPtr is smart_ptr<void>, block_ptr_t is smart_ptr<block>
- typedef typename boost::pointer_to_other
- <VoidPtr, block>::type block_ptr_t;
- struct block
- {
- std::size_t size;
- block_ptr_t next_block;
- };
- block_ptr_t free_blocks;
- };</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>As we can see, using <code>pointer_to_other</code> we can create pointer independent code.</p>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="atomic_shared_ptr">atomic_shared_ptr</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="atomic_shared_ptr_description">Description</h3>
- <div class="paragraph">
- <p>The class template <code>atomic_shared_ptr<T></code> implements the interface of <code>std::atomic</code>
- for a contained value of type <code>shared_ptr<T></code>. Concurrent access to <code>atomic_shared_ptr</code>
- is not a data race.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="atomic_shared_ptr_synopsis">Synopsis</h3>
- <div class="paragraph">
- <p><code>atomic_shared_ptr</code> is defined in <code><boost/smart_ptr/atomic_shared_ptr.hpp></code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- template<class T> class atomic_shared_ptr {
- private:
- shared_ptr<T> p_; // exposition only
- atomic_shared_ptr(const atomic_shared_ptr&) = delete;
- atomic_shared_ptr& operator=(const atomic_shared_ptr&) = delete;
- public:
- constexpr atomic_shared_ptr() noexcept;
- atomic_shared_ptr( shared_ptr<T> p ) noexcept;
- atomic_shared_ptr& operator=( shared_ptr<T> r ) noexcept;
- bool is_lock_free() const noexcept;
- shared_ptr<T> load( int = 0 ) const noexcept;
- operator shared_ptr<T>() const noexcept;
- void store( shared_ptr<T> r, int = 0 ) noexcept;
- shared_ptr<T> exchange( shared_ptr<T> r, int = 0 ) noexcept;
- bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept;
- bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept;
- bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept;
- bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept;
- bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept;
- bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept;
- bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept;
- bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept;
- };
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="atomic_shared_ptr_members">Members</h3>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>constexpr atomic_shared_ptr() noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Default-initializes <code>p_</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>atomic_shared_ptr( shared_ptr<T> p ) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Initializes <code>p_</code> to <code>p</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>atomic_shared_ptr& operator=( shared_ptr<T> r ) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p><code>p_.swap(r)</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>*this</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>bool is_lock_free() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>false</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- This implementation is not lock-free.
- </td>
- </tr>
- </table>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_ptr<T> load( int = 0 ) const noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>operator shared_ptr<T>() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>p_</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- The <code>int</code> argument is intended to be of type <code>memory_order</code>, but is ignored.
- This implementation is lock-based and therefore always sequentially consistent.
- </td>
- </tr>
- </table>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>void store( shared_ptr<T> r, int = 0 ) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p><code>p_.swap(r)</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_ptr<T> exchange( shared_ptr<T> r, int = 0 ) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p><code>p_.swap(r)</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>The old value of <code>p_</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>If <code>p_</code> is equivalent to <code>v</code>, assigns <code>w</code> to <code>p_</code>, otherwise assigns <code>p_</code> to <code>v</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>true</code> if <code>p_</code> was equivalent to <code>v</code>, <code>false</code> otherwise.</p>
- </dd>
- <dt class="hdlist1">Remarks</dt>
- <dd>
- <p>Two <code>shared_ptr</code> instances are equivalent if they store the same pointer value and <em>share ownership</em>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>If <code>p_</code> is equivalent to <code>v</code>, assigns <code>std::move(w)</code> to <code>p_</code>, otherwise assigns <code>p_</code> to <code>v</code>.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>true</code> if <code>p_</code> was equivalent to <code>v</code>, <code>false</code> otherwise.</p>
- </dd>
- <dt class="hdlist1">Remarks</dt>
- <dd>
- <p>The old value of <code>w</code> is not preserved in either case.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="techniques">Appendix A: Smart Pointer Programming Techniques</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="techniques_incomplete">Using incomplete classes for implementation hiding</h3>
- <div class="paragraph">
- <p>A proven technique (that works in C, too) for separating interface from implementation is to use a pointer to an incomplete class as an opaque handle:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>class FILE;
- FILE * fopen(char const * name, char const * mode);
- void fread(FILE * f, void * data, size_t size);
- void fclose(FILE * f);</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>It is possible to express the above interface using <code>shared_ptr</code>, eliminating the need to manually call <code>fclose</code>:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>class FILE;
- shared_ptr<FILE> fopen(char const * name, char const * mode);
- void fread(shared_ptr<FILE> f, void * data, size_t size);</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>This technique relies on <code>shared_ptr</code>’s ability to execute a custom deleter, eliminating the explicit call to <code>fclose</code>, and on the fact that <code>shared_ptr<X></code> can be copied and destroyed when <code>X</code> is incomplete.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_the_pimpl_idiom">The "Pimpl" idiom</h3>
- <div class="paragraph">
- <p>A C++ specific variation of the incomplete class pattern is the "Pimpl" idiom. The incomplete class is not exposed to the user; it is hidden behind a forwarding facade. <code>shared_ptr</code> can be used to implement a "Pimpl":</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>// file.hpp:
- class file
- {
- private:
- class impl;
- shared_ptr<impl> pimpl_;
- public:
- file(char const * name, char const * mode);
- // compiler generated members are fine and useful
- void read(void * data, size_t size);
- };
- // file.cpp:
- #include "file.hpp"
- class file::impl
- {
- private:
- impl(impl const &);
- impl & operator=(impl const &);
- // private data
- public:
- impl(char const * name, char const * mode) { ... }
- ~impl() { ... }
- void read(void * data, size_t size) { ... }
- };
- file::file(char const * name, char const * mode): pimpl_(new impl(name, mode))
- {
- }
- void file::read(void * data, size_t size)
- {
- pimpl_->read(data, size);
- }</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>The key thing to note here is that the compiler-generated copy constructor, assignment operator, and destructor all have a sensible meaning. As a result, <code>file</code> is <code>CopyConstructible</code> and <code>Assignable</code>, allowing its use in standard containers.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_using_abstract_classes_for_implementation_hiding">Using abstract classes for implementation hiding</h3>
- <div class="paragraph">
- <p>Another widely used C++ idiom for separating inteface and implementation is to use abstract base classes and factory functions.
- The abstract classes are sometimes called "interfaces" and the pattern is known as "interface-based programming". Again,
- <code>shared_ptr</code> can be used as the return type of the factory functions:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>// X.hpp:
- class X
- {
- public:
- virtual void f() = 0;
- virtual void g() = 0;
- protected:
- ~X() {}
- };
- shared_ptr<X> createX();
- // X.cpp:
- class X_impl: public X
- {
- private:
- X_impl(X_impl const &);
- X_impl & operator=(X_impl const &);
- public:
- virtual void f()
- {
- // ...
- }
- virtual void g()
- {
- // ...
- }
- };
- shared_ptr<X> createX()
- {
- shared_ptr<X> px(new X_impl);
- return px;
- }</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>A key property of <code>shared_ptr</code> is that the allocation, construction, deallocation, and destruction details are captured at the point of construction, inside the factory function.</p>
- </div>
- <div class="paragraph">
- <p>Note the protected and nonvirtual destructor in the example above. The client code cannot, and does not need to, delete a pointer to <code>X</code>; the <code>shared_ptr<X></code> instance returned from <code>createX</code> will correctly call <code>~X_impl</code>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_preventing_delete_px_get">Preventing <code>delete px.get()</code></h3>
- <div class="paragraph">
- <p>It is often desirable to prevent client code from deleting a pointer that is being managed by <code>shared_ptr</code>. The previous technique showed one possible approach, using a protected destructor. Another alternative is to use a private deleter:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>class X
- {
- private:
- ~X();
- class deleter;
- friend class deleter;
- class deleter
- {
- public:
- void operator()(X * p) { delete p; }
- };
- public:
- static shared_ptr<X> create()
- {
- shared_ptr<X> px(new X, X::deleter());
- return px;
- }
- };</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_encapsulating_allocation_details_wrapping_factory_functions">Encapsulating allocation details, wrapping factory functions</h3>
- <div class="paragraph">
- <p><code>shared_ptr</code> can be used in creating C++ wrappers over existing C style library interfaces that return raw pointers from their factory functions
- to encapsulate allocation details. As an example, consider this interface, where <code>CreateX</code> might allocate <code>X</code> from its own private heap, <code>~X</code> may
- be inaccessible, or <code>X</code> may be incomplete:</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>X * CreateX();
- void DestroyX(X *);</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>The only way to reliably destroy a pointer returned by <code>CreateX</code> is to call <code>DestroyX</code>.</p>
- </div>
- <div class="paragraph">
- <p>Here is how a <code>shared_ptr</code>-based wrapper may look like:</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>shared_ptr<X> createX()
- {
- shared_ptr<X> px(CreateX(), DestroyX);
- return px;
- }</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Client code that calls <code>createX</code> still does not need to know how the object has been allocated, but now the destruction is automatic.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_static">Using a shared_ptr to hold a pointer to a statically allocated object</h3>
- <div class="paragraph">
- <p>Sometimes it is desirable to create a <code>shared_ptr</code> to an already existing object, so that the <code>shared_ptr</code> does not attempt to destroy the
- object when there are no more references left. As an example, the factory function:</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>shared_ptr<X> createX();</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>in certain situations may need to return a pointer to a statically allocated <code>X</code> instance.</p>
- </div>
- <div class="paragraph">
- <p>The solution is to use a custom deleter that does nothing:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>struct null_deleter
- {
- void operator()(void const *) const
- {
- }
- };
- static X x;
- shared_ptr<X> createX()
- {
- shared_ptr<X> px(&x, null_deleter());
- return px;
- }</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>The same technique works for any object known to outlive the pointer.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_using_a_shared_ptr_to_hold_a_pointer_to_a_com_object">Using a shared_ptr to hold a pointer to a COM Object</h3>
- <div class="paragraph">
- <p>Background: COM objects have an embedded reference count and two member functions that manipulate it. <code>AddRef()</code> increments the count.
- <code>Release()</code> decrements the count and destroys itself when the count drops to zero.</p>
- </div>
- <div class="paragraph">
- <p>It is possible to hold a pointer to a COM object in a <code>shared_ptr</code>:</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>shared_ptr<IWhatever> make_shared_from_COM(IWhatever * p)
- {
- p->AddRef();
- shared_ptr<IWhatever> pw(p, mem_fn(&IWhatever::Release));
- return pw;
- }</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Note, however, that <code>shared_ptr</code> copies created from <code>pw</code> will not "register" in the embedded count of the COM object;
- they will share the single reference created in <code>make_shared_from_COM</code>. Weak pointers created from <code>pw</code> will be invalidated when the last
- <code>shared_ptr</code> is destroyed, regardless of whether the COM object itself is still alive.</p>
- </div>
- <div class="paragraph">
- <p>As <a href="../../../../libs/bind/mem_fn.html#Q3">explained</a> in the <code>mem_fn</code> documentation, you need to <code>#define BOOST_MEM_FN_ENABLE_STDCALL</code> first.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_intrusive">Using a shared_ptr to hold a pointer to an object with an embedded reference count</h3>
- <div class="paragraph">
- <p>This is a generalization of the above technique. The example assumes that the object implements the two functions required by <code><a href="#intrusive_ptr">intrusive_ptr</a></code>,
- <code>intrusive_ptr_add_ref</code> and <code>intrusive_ptr_release</code>:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> struct intrusive_deleter
- {
- void operator()(T * p)
- {
- if(p) intrusive_ptr_release(p);
- }
- };
- shared_ptr<X> make_shared_from_intrusive(X * p)
- {
- if(p) intrusive_ptr_add_ref(p);
- shared_ptr<X> px(p, intrusive_deleter<X>());
- return px;
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_using_a_shared_ptr_to_hold_another_shared_ownership_smart_pointer">Using a shared_ptr to hold another shared ownership smart pointer</h3>
- <div class="paragraph">
- <p>One of the design goals of <code>shared_ptr</code> is to be used in library interfaces. It is possible to encounter a situation where a library takes a
- <code>shared_ptr</code> argument, but the object at hand is being managed by a different reference counted or linked smart pointer.</p>
- </div>
- <div class="paragraph">
- <p>It is possible to exploit <code>shared_ptr</code>’s custom deleter feature to wrap this existing smart pointer behind a <code>shared_ptr</code> facade:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class P> struct smart_pointer_deleter
- {
- private:
- P p_;
- public:
- smart_pointer_deleter(P const & p): p_(p)
- {
- }
- void operator()(void const *)
- {
- p_.reset();
- }
- P const & get() const
- {
- return p_;
- }
- };
- shared_ptr<X> make_shared_from_another(another_ptr<X> qx)
- {
- shared_ptr<X> px(qx.get(), smart_pointer_deleter< another_ptr<X> >(qx));
- return px;
- }</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>One subtle point is that deleters are not allowed to throw exceptions, and the above example as written assumes that <code>p_.reset()</code> doesn’t throw.
- If this is not the case, <code>p_.reset();</code> should be wrapped in a <code>try {} catch(…​) {}</code> block that ignores exceptions. In the (usually unlikely) event
- when an exception is thrown and ignored, <code>p_</code> will be released when the lifetime of the deleter ends. This happens when all references, including
- weak pointers, are destroyed or reset.</p>
- </div>
- <div class="paragraph">
- <p>Another twist is that it is possible, given the above <code>shared_ptr</code> instance, to recover the original smart pointer, using <code><a href="#shared_ptr_get_deleter">get_deleter</a></code>:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>void extract_another_from_shared(shared_ptr<X> px)
- {
- typedef smart_pointer_deleter< another_ptr<X> > deleter;
- if(deleter const * pd = get_deleter<deleter>(px))
- {
- another_ptr<X> qx = pd->get();
- }
- else
- {
- // not one of ours
- }
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_from_raw">Obtaining a shared_ptr from a raw pointer</h3>
- <div class="paragraph">
- <p>Sometimes it is necessary to obtain a <code>shared_ptr</code> given a raw pointer to an object that is already managed by another <code>shared_ptr</code> instance. Example:</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>void f(X * p)
- {
- shared_ptr<X> px(???);
- }</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Inside <code>f</code>, we’d like to create a <code>shared_ptr</code> to <code>*p</code>.</p>
- </div>
- <div class="paragraph">
- <p>In the general case, this problem has no solution. One approach is to modify <code>f</code> to take a <code>shared_ptr</code>, if possible:</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>void f(shared_ptr<X> px);</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>The same transformation can be used for nonvirtual member functions, to convert the implicit <code>this</code>:</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>void X::f(int m);</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>would become a free function with a <code>shared_ptr</code> first argument:</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>void f(shared_ptr<X> this_, int m);</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>If <code>f</code> cannot be changed, but <code>X</code> uses intrusive counting, use <code><a href="#techniques_intrusive">make_shared_from_intrusive</a></code> described above. Or, if it’s known that the <code>shared_ptr</code> created in <code>f</code> will never outlive the object, use <a href="#techniques_static">a null deleter</a>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_obtaining_a_shared_ptr_weak_ptr_to_this_in_a_constructor">Obtaining a shared_ptr (weak_ptr) to this in a constructor</h3>
- <div class="paragraph">
- <p>Some designs require objects to register themselves on construction with a central authority. When the registration routines take a <code>shared_ptr</code>, this leads to the question how could a constructor obtain a <code>shared_ptr</code> to <code>this</code>:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>class X
- {
- public:
- X()
- {
- shared_ptr<X> this_(???);
- }
- };</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>In the general case, the problem cannot be solved. The <code>X</code> instance being constructed can be an automatic variable or a static variable; it can be created on the heap:</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>shared_ptr<X> px(new X);</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>but at construction time, <code>px</code> does not exist yet, and it is impossible to create another <code>shared_ptr</code> instance that shares ownership with it.</p>
- </div>
- <div class="paragraph">
- <p>Depending on context, if the inner <code>shared_ptr this_</code> doesn’t need to keep the object alive, use a <code>null_deleter</code> as explained <a href="#techniques_static">here</a> and <a href="#techniques_weak_without_shared">here</a>.
- If <code>X</code> is supposed to always live on the heap, and be managed by a <code>shared_ptr</code>, use a static factory function:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>class X
- {
- private:
- X() { ... }
- public:
- static shared_ptr<X> create()
- {
- shared_ptr<X> px(new X);
- // use px as 'this_'
- return px;
- }
- };</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_obtaining_a_shared_ptr_to_this">Obtaining a shared_ptr to this</h3>
- <div class="paragraph">
- <p>Sometimes it is needed to obtain a <code>shared_ptr</code> from <code>this</code> in a virtual member function under the assumption that <code>this</code> is already managed by a <code>shared_ptr</code>.
- The transformations <a href="#techniques_from_raw">described in the previous technique</a> cannot be applied.</p>
- </div>
- <div class="paragraph">
- <p>A typical example:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>class X
- {
- public:
- virtual void f() = 0;
- protected:
- ~X() {}
- };
- class Y
- {
- public:
- virtual shared_ptr<X> getX() = 0;
- protected:
- ~Y() {}
- };
- // --
- class impl: public X, public Y
- {
- public:
- impl() { ... }
- virtual void f() { ... }
- virtual shared_ptr<X> getX()
- {
- shared_ptr<X> px(???);
- return px;
- }
- };</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>The solution is to keep a weak pointer to <code>this</code> as a member in <code>impl</code>:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>class impl: public X, public Y
- {
- private:
- weak_ptr<impl> weak_this;
- impl(impl const &);
- impl & operator=(impl const &);
- impl() { ... }
- public:
- static shared_ptr<impl> create()
- {
- shared_ptr<impl> pi(new impl);
- pi->weak_this = pi;
- return pi;
- }
- virtual void f() { ... }
- virtual shared_ptr<X> getX()
- {
- shared_ptr<X> px(weak_this);
- return px;
- }
- };</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>The library now includes a helper class template <code><a href="#enable_shared_from_this">enable_shared_from_this</a></code> that can be used to encapsulate the solution:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>class impl: public X, public Y, public enable_shared_from_this<impl>
- {
- public:
- impl(impl const &);
- impl & operator=(impl const &);
- public:
- virtual void f() { ... }
- virtual shared_ptr<X> getX()
- {
- return shared_from_this();
- }
- }</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Note that you no longer need to manually initialize the <code>weak_ptr</code> member in <code>enable_shared_from_this</code>. Constructing a <code>shared_ptr</code> to <code>impl</code> takes care of that.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_using_shared_ptr_as_a_smart_counted_handle">Using shared_ptr as a smart counted handle</h3>
- <div class="paragraph">
- <p>Some library interfaces use opaque handles, a variation of the <a href="#techniques_incomplete">incomplete class technique</a> described above. An example:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>typedef void * HANDLE;
- HANDLE CreateProcess();
- void CloseHandle(HANDLE);</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Instead of a raw pointer, it is possible to use <code>shared_ptr</code> as the handle and get reference counting and automatic resource management for free:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>typedef shared_ptr<void> handle;
- handle createProcess()
- {
- shared_ptr<void> pv(CreateProcess(), CloseHandle);
- return pv;
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_using_shared_ptr_to_execute_code_on_block_exit">Using shared_ptr to execute code on block exit</h3>
- <div class="paragraph">
- <p><code>shared_ptr<void></code> can automatically execute cleanup code when control leaves a scope.</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p>Executing <code>f(p)</code>, where <code>p</code> is a pointer:</p>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_ptr<void> guard(p, f);</code></pre>
- </div>
- </div>
- </li>
- <li>
- <p>Executing arbitrary code: <code>f(x, y)</code>:</p>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_ptr<void> guard(static_cast<void*>(0), bind(f, x, y));</code></pre>
- </div>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_using_shared_ptrvoid_to_hold_an_arbitrary_object">Using shared_ptr<void> to hold an arbitrary object</h3>
- <div class="paragraph">
- <p><code>shared_ptr<void></code> can act as a generic object pointer similar to <code>void*</code>. When a <code>shared_ptr<void></code> instance constructed as:</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>shared_ptr<void> pv(new X);</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>is destroyed, it will correctly dispose of the <code>X</code> object by executing <code>~X</code>.</p>
- </div>
- <div class="paragraph">
- <p>This propery can be used in much the same manner as a raw <code>void*</code> is used to temporarily strip type information from an object pointer.
- A <code>shared_ptr<void></code> can later be cast back to the correct type by using <code><a href="#shared_ptr_static_pointer_cast">static_pointer_cast</a></code>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_associating_arbitrary_data_with_heterogeneous_shared_ptr_instances">Associating arbitrary data with heterogeneous <code>shared_ptr</code> instances</h3>
- <div class="paragraph">
- <p><code>shared_ptr</code> and <code>weak_ptr</code> support <code>operator<</code> comparisons required by standard associative containers such as <code>std::map</code>. This can be
- used to non-intrusively associate arbitrary data with objects managed by <code>shared_ptr</code>:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>typedef int Data;
- std::map<shared_ptr<void>, Data> userData;
- // or std::map<weak_ptr<void>, Data> userData; to not affect the lifetime
- shared_ptr<X> px(new X);
- shared_ptr<int> pi(new int(3));
- userData[px] = 42;
- userData[pi] = 91;</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_using_shared_ptr_as_a_copyconstructible_mutex_lock">Using <code>shared_ptr</code> as a <code>CopyConstructible</code> mutex lock</h3>
- <div class="paragraph">
- <p>Sometimes it’s necessary to return a mutex lock from a function, and a noncopyable lock cannot be returned by value. It is possible to use <code>shared_ptr</code> as a mutex lock:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>class mutex
- {
- public:
- void lock();
- void unlock();
- };
- shared_ptr<mutex> lock(mutex & m)
- {
- m.lock();
- return shared_ptr<mutex>(&m, mem_fn(&mutex::unlock));
- }</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Better yet, the <code>shared_ptr</code> instance acting as a lock can be encapsulated in a dedicated <code>shared_lock</code> class:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>class shared_lock
- {
- private:
- shared_ptr<void> pv;
- public:
- template<class Mutex> explicit shared_lock(Mutex & m): pv((m.lock(), &m), mem_fn(&Mutex::unlock)) {}
- };</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p><code>shared_lock</code> can now be used as:</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>shared_lock lock(m);</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Note that <code>shared_lock</code> is not templated on the mutex type, thanks to <code>shared_ptr<void></code>’s ability to hide type information.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_using_shared_ptr_to_wrap_member_function_calls">Using shared_ptr to wrap member function calls</h3>
- <div class="paragraph">
- <p><code>shared_ptr</code> implements the ownership semantics required from the <code>Wrap/CallProxy</code> scheme described in Bjarne Stroustrup’s article
- "Wrapping C++ Member Function Calls" (available online at <a href="http://www.stroustrup.com/wrapper.pdf" class="bare">http://www.stroustrup.com/wrapper.pdf</a>). An implementation is given below:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> class pointer
- {
- private:
- T * p_;
- public:
- explicit pointer(T * p): p_(p)
- {
- }
- shared_ptr<T> operator->() const
- {
- p_->prefix();
- return shared_ptr<T>(p_, mem_fn(&T::suffix));
- }
- };
- class X
- {
- private:
- void prefix();
- void suffix();
- friend class pointer<X>;
- public:
- void f();
- void g();
- };
- int main()
- {
- X x;
- pointer<X> px(&x);
- px->f();
- px->g();
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_delayed_deallocation">Delayed deallocation</h3>
- <div class="paragraph">
- <p>In some situations, a single <code>px.reset()</code> can trigger an expensive deallocation in a performance-critical region:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>class X; // ~X is expensive
- class Y
- {
- shared_ptr<X> px;
- public:
- void f()
- {
- px.reset();
- }
- };</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>The solution is to postpone the potential deallocation by moving <code>px</code> to a dedicated free list that can be periodically emptied when performance and response times are not an issue:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>vector< shared_ptr<void> > free_list;
- class Y
- {
- shared_ptr<X> px;
- public:
- void f()
- {
- free_list.push_back(px);
- px.reset();
- }
- };
- // periodically invoke free_list.clear() when convenient</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Another variation is to move the free list logic to the construction point by using a delayed deleter:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>struct delayed_deleter
- {
- template<class T> void operator()(T * p)
- {
- try
- {
- shared_ptr<void> pv(p);
- free_list.push_back(pv);
- }
- catch(...)
- {
- }
- }
- };</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="techniques_weak_without_shared">Weak pointers to objects not managed by a shared_ptr</h3>
- <div class="paragraph">
- <p>Make the object hold a <code>shared_ptr</code> to itself, using a <code>null_deleter</code>:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>class X
- {
- private:
- shared_ptr<X> this_;
- int i_;
- public:
- explicit X(int i): this_(this, null_deleter()), i_(i)
- {
- }
- // repeat in all constructors (including the copy constructor!)
- X(X const & rhs): this_(this, null_deleter()), i_(rhs.i_)
- {
- }
- // do not forget to not assign this_ in the copy assignment
- X & operator=(X const & rhs)
- {
- i_ = rhs.i_;
- }
- weak_ptr<X> get_weak_ptr() const { return this_; }
- };</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>When the object’s lifetime ends, <code>X::this_</code> will be destroyed, and all weak pointers will automatically expire.</p>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="history">Appendix B: History and Acknowledgments</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="history_summer_1994">Summer 1994</h3>
- <div class="paragraph">
- <p>Greg Colvin <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1994/N0555.pdf">proposed</a>
- to the C++ Standards Committee classes named <code>auto_ptr</code> and <code>counted_ptr</code> which were very
- similar to what we now call <code>scoped_ptr</code> and <code>shared_ptr</code>. In one of the very few cases
- where the Library Working Group’s recommendations were not followed by the full committee,
- <code>counted_ptr</code> was rejected and surprising transfer-of-ownership semantics were added to <code>auto_ptr</code>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="history_october_1998">October 1998</h3>
- <div class="paragraph">
- <p>Beman Dawes proposed reviving the original semantics under the names <code>safe_ptr</code> and <code>counted_ptr</code>,
- meeting of Per Andersson, Matt Austern, Greg Colvin, Sean Corfield, Pete Becker, Nico Josuttis,
- Dietmar Kühl, Nathan Myers, Chichiang Wan and Judy Ward. During the discussion, the four new class
- names were finalized, it was decided that there was no need to exactly follow the <code>std::auto_ptr</code>
- interface, and various function signatures and semantics were finalized.</p>
- </div>
- <div class="paragraph">
- <p>Over the next three months, several implementations were considered for <code>shared_ptr</code>, and discussed
- on the <a href="http://www.boost.org/">boost.org</a> mailing list. The implementation questions revolved around
- the reference count which must be kept, either attached to the pointed to object, or detached elsewhere.
- Each of those variants have themselves two major variants:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p>Direct detached: the <code>shared_ptr</code> contains a pointer to the object, and a pointer to the count.</p>
- </li>
- <li>
- <p>Indirect detached: the <code>shared_ptr</code> contains a pointer to a helper object, which in turn contains a pointer to the object and the count.</p>
- </li>
- <li>
- <p>Embedded attached: the count is a member of the object pointed to.</p>
- </li>
- <li>
- <p>Placement attached: the count is attached via operator new manipulations.</p>
- </li>
- </ul>
- </div>
- <div class="paragraph">
- <p>Each implementation technique has advantages and disadvantages. We went so far as to run various timings
- of the direct and indirect approaches, and found that at least on Intel Pentium chips there was very little
- measurable difference. Kevlin Henney provided a paper he wrote on "Counted Body Techniques." Dietmar Kühl
- suggested an elegant partial template specialization technique to allow users to choose which implementation
- they preferred, and that was also experimented with.</p>
- </div>
- <div class="paragraph">
- <p>But Greg Colvin and Jerry Schwarz argued that "parameterization will discourage users", and in the end we choose
- to supply only the direct implementation.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="history_may_1999">May 1999</h3>
- <div class="paragraph">
- <p>In April and May, 1999, Valentin Bonnard and David Abrahams made a number of suggestions resulting in numerous improvements.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="history_september_1999">September 1999</h3>
- <div class="paragraph">
- <p>Luis Coelho provided <code>shared_ptr::swap</code> and <code>shared_array::swap</code>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="history_november_1999">November 1999</h3>
- <div class="paragraph">
- <p>Darin Adler provided <code>operator ==</code>, <code>operator !=</code>, and <code>std::swap</code> and <code>std::less</code> specializations for shared types.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="history_may_2001">May 2001</h3>
- <div class="paragraph">
- <p>Vladimir Prus suggested requiring a complete type on destruction. Refinement evolved in discussions including Dave Abrahams,
- Greg Colvin, Beman Dawes, Rainer Deyke, Peter Dimov, John Maddock, Vladimir Prus, Shankar Sai, and others.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="history_january_2002">January 2002</h3>
- <div class="paragraph">
- <p>Peter Dimov reworked all four classes, adding features, fixing bugs, splitting them into four separate headers, and adding
- <code>weak_ptr</code>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="history_march_2003">March 2003</h3>
- <div class="paragraph">
- <p>Peter Dimov, Beman Dawes and Greg Colvin <a href="http://open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1450.html">proposed</a> <code>shared_ptr</code>
- and <code>weak_ptr</code> for inclusion in the Standard Library via the first Library Technical Report (known as TR1). The proposal was
- accepted and eventually went on to become a part of the C++ standard in its 2011 iteration.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="history_july_2007">July 2007</h3>
- <div class="paragraph">
- <p>Peter Dimov and Beman Dawes <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2351.htm">proposed</a> a number of enhancements
- to <code>shared_ptr</code> as it was entering the working paper that eventually became the C++11 standard.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="history_november_2012">November 2012</h3>
- <div class="paragraph">
- <p>Glen Fernandes provided implementations of <code>make_shared</code> and <code>allocate_shared</code> for arrays. They achieve a single allocation
- for an array that can be initialized with constructor arguments or initializer lists as well as overloads for default initialization
- and no value initialization.</p>
- </div>
- <div class="paragraph">
- <p>Peter Dimov aided this development by extending <code>shared_ptr</code> to support arrays via the syntax <code>shared_ptr<T[]></code> and <code>shared_ptr<T[N]></code>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="history_april_2013">April 2013</h3>
- <div class="paragraph">
- <p>Peter Dimov <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3640.html">proposed</a> the extension of <code>shared_ptr</code> to support
- arrays for inclusion into the standard, and it was accepted.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="history_february_2014">February 2014</h3>
- <div class="paragraph">
- <p>Glen Fernandes updated <code>make_shared</code> and <code>allocate_shared</code> to conform to the specification in C++ standard paper
- <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3870.html">N3870</a>, and implemented <code>make_unique</code> for arrays and objects.</p>
- </div>
- <div class="paragraph">
- <p>Peter Dimov and Glen Fernandes updated the scalar and array implementations, respectively, to resolve C++ standard library defect 2070.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="history_february_2017">February 2017</h3>
- <div class="paragraph">
- <p>Glen Fernandes rewrote <code>allocate_shared</code> and <code>make_shared</code> for arrays for a more optimal and more maintainable implementation.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="history_june_2017">June 2017</h3>
- <div class="paragraph">
- <p>Peter Dimov and Glen Fernandes rewrote the documentation in Asciidoc format.</p>
- </div>
- <div class="paragraph">
- <p>Peter Dimov added <code>atomic_shared_ptr</code> and <code>local_shared_ptr</code>.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="history_august_2019">August 2019</h3>
- <div class="paragraph">
- <p>Glen Fernandes implemented <code>allocate_unique</code> for scalars and arrays.</p>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="shared_array">Appendix C: shared_array (deprecated)</h2>
- <div class="sectionbody">
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- This facility is deprecated because a <code>shared_ptr</code> to <code>T[]</code> or <code>T[N]</code>
- is now available, and is superior in every regard.
- </td>
- </tr>
- </table>
- </div>
- <div class="sect2">
- <h3 id="shared_array_description">Description</h3>
- <div class="paragraph">
- <p>The <code>shared_array</code> class template stores a pointer to a dynamically allocated
- array. (Dynamically allocated array are allocated with the C++ <code>new[]</code>
- expression.) The object pointed to is guaranteed to be deleted when the last
- <code>shared_array</code> pointing to it is destroyed or reset.</p>
- </div>
- <div class="paragraph">
- <p>Every <code>shared_array</code> meets the <em>CopyConstructible</em> and <em>Assignable</em>
- requirements of the C++ Standard Library, and so can be used in standard
- library containers. Comparison operators are supplied so that shared_array
- works with the standard library’s associative containers.</p>
- </div>
- <div class="paragraph">
- <p>Normally, a <code>shared_array</code> cannot correctly hold a pointer to an object that
- has been allocated with the non-array form of <code>new</code>. See <code>shared_ptr</code> for that
- usage.</p>
- </div>
- <div class="paragraph">
- <p>Because the implementation uses reference counting, cycles of <code>shared_array</code>
- instances will not be reclaimed. For example, if <code>main</code> holds a shared_array
- to <code>A</code>, which directly or indirectly holds a shared_array back to <code>A</code>, the use
- count of <code>A</code> will be 2. Destruction of the original <code>shared_array</code> will leave
- <code>A</code> dangling with a use count of 1.</p>
- </div>
- <div class="paragraph">
- <p>A <code>shared_ptr</code> to a <code>std::vector</code> is an alternative to a <code>shared_array</code> that
- is a bit heavier duty but far more flexible.</p>
- </div>
- <div class="paragraph">
- <p>The class template is parameterized on <code>T</code>, the type of the object pointed to.
- <code>shared_array</code> and most of its member functions place no requirements on <code>T</code>;
- it is allowed to be an incomplete type, or <code>void</code>. Member functions that do
- place additional requirements (constructors, reset) are explicitly documented
- below.</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="shared_array_synopsis">Synopsis</h3>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>namespace boost {
- template<class T> class shared_array {
- public:
- typedef T element_type;
- explicit shared_array(T* p = 0);
- template<class D> shared_array(T* p, D d);
- shared_array(const shared_array& v) noexcept;
- ~shared_array() noexcept;
- shared_array& operator=(const shared_array& v) noexcept;
- void reset(T* p = 0);
- template<class D> void reset(T* p, D d);
- T& operator[](std::ptrdiff_t n) const noexcept;
- T* get() const noexcept;
- bool unique() const noexcept;
- long use_count() const noexcept;
- explicit operator bool() const noexcept;
- void swap(shared_array<T>& v) noexcept;
- };
- template<class T> bool
- operator==(const shared_array<T>& a, const shared_array<T>& b) noexcept;
- template<class T> bool
- operator!=(const shared_array<T>& a, const shared_array<T>& b) noexcept;
- template<class T> bool
- operator<(const shared_array<T>& a, const shared_array<T>& b) noexcept;
- template<class T>
- void swap(shared_array<T>& a, shared_array<T>& b) noexcept;
- }</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="shared_array_members">Members</h3>
- <div class="sect3">
- <h4 id="shared_array_element_type">element_type</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>typedef T element_type;</code></pre>
- </div>
- </div>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Type</dt>
- <dd>
- <p>Provides the type of the stored pointer.</p>
- </dd>
- </dl>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_array_constructors">Constructors</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>explicit shared_array(T* p = 0);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs a <code>shared_array</code>, storing a copy of <code>p</code>, which must be a
- pointer to an array that was allocated via a C++ <code>new[]</code> expression or be 0.
- Afterwards, the use count is 1 (even if <code>p == 0</code>; see <code>~shared_array</code>).</p>
- </dd>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>T</code> is a complete type.</p>
- </dd>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p><code>std::bad_alloc</code>. If an exception is thrown, <code>delete[] p</code> is called.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class D> shared_array(T* p, D d);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs a <code>shared_array</code>, storing a copy of <code>p</code> and of <code>d</code>.
- Afterwards, the use count is 1. When the the time comes to delete the array
- pointed to by <code>p</code>, the object <code>d</code> is used in the statement <code>d(p)</code>.</p>
- </dd>
- <dt class="hdlist1">Requires</dt>
- </dl>
- </div>
- </li>
- <li>
- <p><code>T</code> is a complete type.</p>
- </li>
- <li>
- <p>The copy constructor and destructor of <code>D</code> must not throw.</p>
- </li>
- <li>
- <p>Invoking the object <code>d</code> with parameter <code>p</code> must not throw.</p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p><code>std::bad_alloc</code>. If an exception is thrown, <code>d(p)</code> is called.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_array(const shared_array& v) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs a <code>shared_array</code>, as if by storing a copy of the pointer
- stored in <code>v</code>. Afterwards, the use count for all copies is 1 more than the
- initial use count.</p>
- </dd>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>T</code> is a complete type.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_array_destructor">Destructor</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>~shared_array() noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Decrements the use count. Then, if the use count is 0, deletes the
- array pointed to by the stored pointer. Note that <code>delete[]</code> on a pointer with
- a value of 0 is harmless.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_array_assignment">Assignment</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>shared_array& operator=(const shared_array& v) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs a new <code>shared_array</code> as described above, then replaces
- this <code>shared_array</code> with the new one, destroying the replaced object.</p>
- </dd>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>T</code> is a complete type.</p>
- </dd>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>*this</code>.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_array_reset">reset</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>void reset(T* p = 0);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs a new <code>shared_array</code> as described above, then replaces
- this <code>shared_array</code> with the new one, destroying the replaced object.</p>
- </dd>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>T</code> is a complete type.</p>
- </dd>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p><code>std::bad_alloc</code>. If an exception is thrown, <code>delete[] p</code> is called.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class D> void reset(T* p, D d);</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Constructs a new <code>shared_array</code> as described above, then replaces
- this <code>shared_array</code> with the new one, destroying the replaced object.</p>
- </dd>
- <dt class="hdlist1">Requires</dt>
- </dl>
- </div>
- </li>
- <li>
- <p><code>T</code> is a complete type.</p>
- </li>
- <li>
- <p>The copy constructor of <code>D</code> must not throw.</p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Throws</dt>
- <dd>
- <p><code>std::bad_alloc</code>. If an exception is thrown, <code>d(p)</code> is called.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_array_indexing">Indexing</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>T& operator[](std::ptrdiff_t n) const noexcept;</code></pre>
- </div>
- </div>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>A reference to element <code>n</code> of the array pointed to by the stored
- pointer. Behavior is undefined and almost certainly undesirable if the stored
- pointer is 0, or if <code>n</code> is less than 0 or is greater than or equal to the
- number of elements in the array.</p>
- </dd>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>T</code> is a complete type.</p>
- </dd>
- </dl>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_array_get">get</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>T* get() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>The stored pointer.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_array_unique">unique</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>bool unique() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>true</code> if no other <code>shared_array</code> is sharing ownership of the
- stored pointer, <code>false</code> otherwise.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_array_use_count">use_count</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>long use_count() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>The number of <code>shared_array</code> objects sharing ownership of the
- stored pointer.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_array_conversions">Conversions</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>explicit operator bool() const noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>get() != 0</code>.</p>
- </dd>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>T</code> is a complete type.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_array_swap">swap</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>void swap(shared_array<T>& b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Effects</dt>
- <dd>
- <p>Exchanges the contents of the two smart pointers.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="shared_array_free_functions">Free Functions</h3>
- <div class="sect3">
- <h4 id="shared_array_comparison">Comparison</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> bool
- operator==(const shared_array<T>& a, const shared_array<T>& b) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> bool
- operator!=(const shared_array<T>& a, const shared_array<T>& b) noexcept;</code></pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T> bool
- operator<(const shared_array<T>& a, const shared_array<T>& b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p>The result of comparing the stored pointers of the two smart
- pointers.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <div class="title">Note</div>
- </td>
- <td class="content">
- The <code>operator<</code> overload is provided to define an ordering so that
- <code>shared_array</code> objects can be used in associative containers such as
- <code>std::map</code>. The implementation uses <code>std::less<T*></code> to perform the comparison.
- This ensures that the comparison is handled correctly, since the standard
- mandates that relational operations on pointers are unspecified (5.9
- [expr.rel] paragraph 2) but <code>std::less</code> on pointers is well-defined (20.3.3
- [lib.comparisons] paragraph 8).
- </td>
- </tr>
- </table>
- </div>
- </div>
- <div class="sect3">
- <h4 id="shared_array_swap_2">swap</h4>
- <div class="listingblock">
- <div class="content">
- <pre class="highlight"><code>template<class T>
- void swap(shared_array<T>& a, shared_array<T>& b) noexcept;</code></pre>
- </div>
- </div>
- <div class="ulist none">
- <ul class="none">
- <li>
- <p></p>
- <div class="dlist">
- <dl>
- <dt class="hdlist1">Returns</dt>
- <dd>
- <p><code>a.swap(b)</code>.</p>
- </dd>
- <dt class="hdlist1">Requires</dt>
- <dd>
- <p><code>T</code> is a complete type.</p>
- </dd>
- </dl>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="copyright">Appendix D: Copyright and License</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>This documentation is</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p>Copyright 1999 Greg Colvin</p>
- </li>
- <li>
- <p>Copyright 1999 Beman Dawes</p>
- </li>
- <li>
- <p>Copyright 2002 Darin Adler</p>
- </li>
- <li>
- <p>Copyright 2003-2017 Peter Dimov</p>
- </li>
- <li>
- <p>Copyright 2005, 2006 Ion Gaztañaga</p>
- </li>
- <li>
- <p>Copyright 2008 Frank Mori Hess</p>
- </li>
- <li>
- <p>Copyright 2012-2017 Glen Fernandes</p>
- </li>
- <li>
- <p>Copyright 2013 Andrey Semashev</p>
- </li>
- </ul>
- </div>
- <div class="paragraph">
- <p>and is distributed under the <a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License, Version 1.0</a>.</p>
- </div>
- </div>
- </div>
- </div>
- <div id="footer">
- <div id="footer-text">
- Last updated 2019-12-10 00:19:52 UTC
- </div>
- </div>
- <style>
- *:not(pre)>code { background: none; color: #600000; }
- table tr.even, table tr.alt, table tr:nth-of-type(even) { background: none; }
- </style>
- </body>
- </html>
|