€cdocutils.nodes document q)q}q(U nametypesq}q(XtechnicalitiesqNUcontentsqNXcreating a reference proxyqNuUsubstitution_defsq }q Uparse_messagesq ]q Ucurrent_sourceq NU decorationqNUautofootnote_startqKUnameidsq}q(hUtechnicalitiesqhUcontentsqhUcreating-a-reference-proxyquUchildrenq]qcdocutils.nodes section q)q}q(U rawsourceqUUparentqhUsourceqX4/root/project/libs/gil/doc/design/technicalities.rstqUtagnameqUsectionqU attributesq }q!(Udupnamesq"]Uclassesq#]Ubackrefsq$]Uidsq%]q&haUnamesq']q(hauUlineq)KUdocumentq*hh]q+(cdocutils.nodes title q,)q-}q.(hXTechnicalitiesq/hhhhhUtitleq0h }q1(h"]h#]h$]h%]h']uh)Kh*hh]q2cdocutils.nodes Text q3XTechnicalitiesq4…q5}q6(hh/hh-ubaubcdocutils.nodes topic q7)q8}q9(hUhhhhhUtopicq:h }q;(h"]h#]q<(Ucontentsq=Ulocalq>eh$]h%]q?hah']q@hauh)Kh*hh]qAcdocutils.nodes bullet_list qB)qC}qD(hUhh8hNhU bullet_listqEh }qF(h"]h#]h$]h%]h']uh)Nh*hh]qGcdocutils.nodes list_item qH)qI}qJ(hUh }qK(h"]h#]h$]h%]h']uhhCh]qLcdocutils.nodes paragraph qM)qN}qO(hUh }qP(h"]h#]h$]h%]h']uhhIh]qQcdocutils.nodes reference qR)qS}qT(hUh }qU(h%]qVUid1qWah$]h"]h#]h']UrefidhuhhNh]qXh3XCreating a reference proxyqY…qZ}q[(hXCreating a reference proxyq\hhSubahU referenceq]ubahU paragraphq^ubahU list_itemq_ubaubaubh)q`}qa(hUhhhhhhh }qb(h"]h#]h$]h%]qchah']qdhauh)K h*hh]qe(h,)qf}qg(hh\hh`hhhh0h }qh(h%]h$]h"]h#]h']UrefidqihWuh)K h*hh]qjh3XCreating a reference proxyqk…ql}qm(hh\hhfubaubhM)qn}qo(hXSometimes it is necessary to create a proxy class that represents a reference to a given object. Examples of these are GIL's reference to a planar pixel (``planar_pixel_reference``) and GIL's sub-byte channel references. Writing a reference proxy class can be tricky. One problem is that the proxy reference is constructed as a temporary object and returned by value upon dereferencing the iterator:hh`hhhh^h }qp(h"]h#]h$]h%]h']uh)K h*hh]qq(h3XšSometimes it is necessary to create a proxy class that represents a reference to a given object. Examples of these are GIL's reference to a planar pixel (qr…qs}qt(hXšSometimes it is necessary to create a proxy class that represents a reference to a given object. Examples of these are GIL's reference to a planar pixel (hhnubcdocutils.nodes literal qu)qv}qw(hX``planar_pixel_reference``h }qx(h"]h#]h$]h%]h']uhhnh]qyh3Xplanar_pixel_referenceqz…q{}q|(hUhhvubahUliteralq}ubh3XÛ) and GIL's sub-byte channel references. Writing a reference proxy class can be tricky. One problem is that the proxy reference is constructed as a temporary object and returned by value upon dereferencing the iterator:q~…q}q€(hXÛ) and GIL's sub-byte channel references. Writing a reference proxy class can be tricky. One problem is that the proxy reference is constructed as a temporary object and returned by value upon dereferencing the iterator:hhnubeubcdocutils.nodes literal_block q)q‚}qƒ(hX’struct rgb_planar_pixel_iterator { typedef my_reference_proxy reference; reference operator*() const { return reference(red,green,blue); } };hh`hhhU literal_blockq„h }q…(Ulinenosq†‰Ulanguageq‡XcppU xml:spaceqˆUpreserveq‰h%]h$]h"]Uhighlight_argsqŠ}h#]h']uh)Kh*hh]q‹h3X’struct rgb_planar_pixel_iterator { typedef my_reference_proxy reference; reference operator*() const { return reference(red,green,blue); } };qŒ…q}qŽ(hUhh‚ubaubhM)q}q(hXhThe problem arises when an iterator is dereferenced directly into a function that takes a mutable pixel:q‘hh`hhhh^h }q’(h"]h#]h$]h%]h']uh)Kh*hh]q“h3XhThe problem arises when an iterator is dereferenced directly into a function that takes a mutable pixel:q”…q•}q–(hh‘hhubaubh)q—}q˜(hX¦template // Models MutablePixelConcept void invert_pixel(Pixel& p); rgb_planar_pixel_iterator myIt; invert_pixel(*myIt); // compile error!hh`hhhh„h }q™(h†‰h‡Xcpphˆh‰h%]h$]h"]hŠ}h#]h']uh)Kh*hh]qšh3X¦template // Models MutablePixelConcept void invert_pixel(Pixel& p); rgb_planar_pixel_iterator myIt; invert_pixel(*myIt); // compile error!q›…qœ}q(hUhh—ubaubhM)qž}qŸ(hXhC++ does not allow for matching a temporary object against a non-constant reference. The solution is to:q hh`hhhh^h }q¡(h"]h#]h$]h%]h']uh)K%h*hh]q¢h3XhC++ does not allow for matching a temporary object against a non-constant reference. The solution is to:q£…q¤}q¥(hh hhžubaubhB)q¦}q§(hUhh`hhhhEh }q¨(Ubulletq©X*h%]h$]h"]h#]h']uh)K(h*hh]qªhH)q«}q¬(hXBUse const qualifier on all members of the reference proxy object: hh¦hhhh_h }q­(h"]h#]h$]h%]h']uh)Nh*hh]q®hM)q¯}q°(hXAUse const qualifier on all members of the reference proxy object:q±hh«hhhh^h }q²(h"]h#]h$]h%]h']uh)K(h]q³h3XAUse const qualifier on all members of the reference proxy object:q´…qµ}q¶(hh±hh¯ubaubaubaubh)q·}q¸(hXÄtemplate struct my_reference_proxy { const my_reference_proxy& operator=(const my_reference_proxy& p) const; const my_reference_proxy* operator->() const { return this; } ... };hh`hhhh„h }q¹(h†‰h‡Xcpphˆh‰h%]h$]h"]hŠ}h#]h']uh)K*h*hh]qºh3XÄtemplate struct my_reference_proxy { const my_reference_proxy& operator=(const my_reference_proxy& p) const; const my_reference_proxy* operator->() const { return this; } ... };q»…q¼}q½(hUhh·ubaubhB)q¾}q¿(hUhh`hhhhEh }qÀ(h©X*h%]h$]h"]h#]h']uh)K4h*hh]qÁ(hH)qÂ}qÃ(hXxUse different classes to denote mutable and constant reference (maybe based on the constness of the template parameter) hh¾hhhh_h }qÄ(h"]h#]h$]h%]h']uh)Nh*hh]qÅhM)qÆ}qÇ(hXwUse different classes to denote mutable and constant reference (maybe based on the constness of the template parameter)qÈhhÂhhhh^h }qÉ(h"]h#]h$]h%]h']uh)K4h]qÊh3XwUse different classes to denote mutable and constant reference (maybe based on the constness of the template parameter)qË…qÌ}qÍ(hhÈhhÆubaubaubhH)qÎ}qÏ(hXADefine the reference type of your iterator with const qualifier: hh¾hhhh_h }qÐ(h"]h#]h$]h%]h']uh)Nh*hh]qÑhM)qÒ}qÓ(hX@Define the reference type of your iterator with const qualifier:qÔhhÎhhhh^h }qÕ(h"]h#]h$]h%]h']uh)K7h]qÖh3X@Define the reference type of your iterator with const qualifier:q×…qØ}qÙ(hhÔhhÒubaubaubeubh)qÚ}qÛ(hXgstruct iterator_traits { typedef const my_reference_proxy reference; };hh`hhhh„h }qÜ(h†‰h‡Xcpphˆh‰h%]h$]h"]hŠ}h#]h']uh)K9h*hh]qÝh3Xgstruct iterator_traits { typedef const my_reference_proxy reference; };qÞ…qß}qà(hUhhÚubaubhM)qá}qâ(hX°A second important issue is providing an overload for ``swap`` for your reference class. The default ``std::swap`` will not work correctly. You must use a real value type as the temporary. A further complication is that in some implementations of the STL the ``swap`` function is incorrectly called qualified, as ``std::swap``. The only way for these STL algorithms to use your overload is if you define it in the ``std`` namespace:hh`hhhh^h }qã(h"]h#]h$]h%]h']uh)K@h*hh]qä(h3X6A second important issue is providing an overload for qå…qæ}qç(hX6A second important issue is providing an overload for hháubhu)qè}qé(hX``swap``h }qê(h"]h#]h$]h%]h']uhháh]qëh3Xswapqì…qí}qî(hUhhèubahh}ubh3X' for your reference class. The default qï…qð}qñ(hX' for your reference class. The default hháubhu)qò}qó(hX ``std::swap``h }qô(h"]h#]h$]h%]h']uhháh]qõh3X std::swapqö…q÷}qø(hUhhòubahh}ubh3X‘ will not work correctly. You must use a real value type as the temporary. A further complication is that in some implementations of the STL the qù…qú}qû(hX‘ will not work correctly. You must use a real value type as the temporary. A further complication is that in some implementations of the STL the hháubhu)qü}qý(hX``swap``h }qþ(h"]h#]h$]h%]h']uhháh]qÿh3Xswapr…r}r(hUhhüubahh}ubh3X. function is incorrectly called qualified, as r…r}r(hX. function is incorrectly called qualified, as hháubhu)r}r(hX ``std::swap``h }r(h"]h#]h$]h%]h']uhháh]r h3X std::swapr …r }r (hUhjubahh}ubh3XX. The only way for these STL algorithms to use your overload is if you define it in the r …r}r(hXX. The only way for these STL algorithms to use your overload is if you define it in the hháubhu)r}r(hX``std``h }r(h"]h#]h$]h%]h']uhháh]rh3Xstdr…r}r(hUhjubahh}ubh3X namespace:r…r}r(hX namespace:hháubeubh)r}r(hX˜namespace std { template void swap(my_reference_proxy& x, my_reference_proxy& y) { my_value tmp=x; x=y; y=tmp; } }hh`hhhh„h }r(h†‰h‡Xcpphˆh‰h%]h$]h"]hŠ}h#]h']uh)KHh*hh]rh3X˜namespace std { template void swap(my_reference_proxy& x, my_reference_proxy& y) { my_value tmp=x; x=y; y=tmp; } }r…r}r (hUhjubaubhM)r!}r"(hX‚Lastly, remember that constructors and copy-constructors of proxy references are always shallow and assignment operators are deep.r#hh`hhhh^h }r$(h"]h#]h$]h%]h']uh)KUh*hh]r%h3X‚Lastly, remember that constructors and copy-constructors of proxy references are always shallow and assignment operators are deep.r&…r'}r((hj#hj!ubaubhM)r)}r*(hXbWe are grateful to Dave Abrahams, Sean Parent and Alex Stepanov for suggesting the above solution.r+hh`hhhh^h }r,(h"]h#]h$]h%]h']uh)KXh*hh]r-h3XbWe are grateful to Dave Abrahams, Sean Parent and Alex Stepanov for suggesting the above solution.r.…r/}r0(hj+hj)ubaubeubeubahUU transformerr1NU footnote_refsr2}r3Urefnamesr4}r5Usymbol_footnotesr6]r7Uautofootnote_refsr8]r9Usymbol_footnote_refsr:]r;U citationsr<]r=h*hU current_liner>NUtransform_messagesr?]r@UreporterrANUid_startrBKU autofootnotesrC]rDU citation_refsrE}rFUindirect_targetsrG]rHUsettingsrI(cdocutils.frontend Values rJorK}rL(Ufootnote_backlinksrMKUrecord_dependenciesrNNU rfc_base_urlrOUhttps://tools.ietf.org/html/rPU tracebackrQˆUpep_referencesrRNUstrip_commentsrSNU toc_backlinksrTUentryrUU language_coderVUenrWU datestamprXNU report_levelrYKU _destinationrZNU halt_levelr[KU strip_classesr\Nh0NUerror_encoding_error_handlerr]Ubackslashreplacer^Udebugr_NUembed_stylesheetr`‰Uoutput_encoding_error_handlerraUstrictrbU sectnum_xformrcKUdump_transformsrdNU docinfo_xformreKUwarning_streamrfNUpep_file_url_templatergUpep-%04drhUexit_status_levelriKUconfigrjNUstrict_visitorrkNUcloak_email_addressesrlˆUtrim_footnote_reference_spacerm‰UenvrnNUdump_pseudo_xmlroNUexpose_internalsrpNUsectsubtitle_xformrq‰U source_linkrrNUrfc_referencesrsNUoutput_encodingrtUutf-8ruU source_urlrvNUinput_encodingrwU utf-8-sigrxU_disable_configryNU id_prefixrzUU tab_widthr{KUerror_encodingr|Uasciir}U_sourcer~hUgettext_compactrˆU generatorr€NUdump_internalsrNU smart_quotesr‚‰U pep_base_urlrƒU https://www.python.org/dev/peps/r„Usyntax_highlightr…Ulongr†Uinput_encoding_error_handlerr‡jbUauto_id_prefixrˆUidr‰Udoctitle_xformrЉUstrip_elements_with_classesr‹NU _config_filesrŒ]Ufile_insertion_enabledrˆU raw_enabledrŽKU dump_settingsrNubUsymbol_footnote_startrKUidsr‘}r’(hh`hhhh8hWhSuUsubstitution_namesr“}r”hh*h }r•(h"]h%]h$]Usourcehh#]h']uU footnotesr–]r—Urefidsr˜}r™ub.