TITLE("pick_")
TOPIC_TEXT(
"[ $$0,0#00000000000000000000000000000000:Default][l288;i704;a17;O9;~~~.992; $$1,"
"0#10431211400427159095818037425705:param][a83;*R6 $$2,5#3131016247420302412518841"
"7583966:caption][b83;* $$3,5#07864147445237544204411237157677:title][b167;a42;C $"
"$4,6#40027414424643823182269349404212:item][b42;a42; $$5,5#4541300047534217475409"
"1244180557:text][l288;a17; $$6,6#27521748481378242620020725143825:desc][l321;t246"
";C@5;1 $$7,7#20902679421464641399138805415013:code][b2503; $$8,0#6514237545610002"
"3862071332075487:separator][*@(0.0.255) $$9,0#83433469410354161042741608181528:ba"
"se][t4167;C+117 $$10,0#37138531426314131251341829483380:class][l288;a17;*1 $$11,1"
"1#70004532496200323422659154056402:requirement][i416;b42;a42;O9;~~~.416; $$12,12#"
"10566046415157235020018451313112:tparam][b167;C $$13,13#9243045944346046191110808"
"0531343:item1][a42;C $$14,14#77422149456609303542238260500223:item2][*@2$(0.128.1"
"28) $$15,15#34511555403152284025741354420178:NewsDate][l321;*C$7 $$16,16#03451589"
"433145915344929335295360:result][l321;b83;a83;*C$7 $$17,17#0753155046352950537122"
"8428965313:result`-line][l160;t4167;*C+117 $$18,5#8860394944220582595880005322242"
"5:package`-title][{_}%EN-US [s2; Transfer semantics&][s3; Deep copy semantics&][s"
"5; Talking about transfer semantics, we are interested in passing values from one"
" place to another, e.g&][s7;l320; int a, b;&][s7;l320; a = b;&][s5; Here we trans"
"fer value contained in variable [* b] to variable [* a]. We are doing so using im"
"plicit assignment operator of type [* int.] This assignment operator passes value"
" of source to target while preserving value of source. This kind of transfer sema"
"ntics we call [*/ deep copy]. For large number of types, deep copy is good choice"
" as default transfer semantics. However there are types where preserving source i"
"s not that important and dropping this feature has advantages. Consider this simp"
"le 'container'&][s7;%00-00 [%00-00 class IntArray {]&][s7;%00-00 [%00-00 -|int co"
"unt;]&][s7;%00-00 [%00-00 -|int *array;]&][s7;%00-00 [%00")
TOPIC_TEXT(
"-00 -|void Copy(const IntArray`& src) {]&][s7;%00-00 [%00-00 -|-|array = new int"
"`[count = src.count`];]&][s7;%00-00 [%00-00 -|-|memcpy(array, src.array, count * "
"sizeof(int));]&][s7;%00-00 [%00-00 -|}]&][s7;%00-00 [%00-00 public:]&][s7;%00-00 "
"[%00-00 -|int`& operator`[`](int i)        { return array`[i`]; }]&][s7;%00-00 [%"
"00-00 -|int  GetCount() const         { return count; }]&][s7;%00-00 [%00-00 -|In"
"tArray(int n)               { count = n; array = new int`[n`]; }]&][s7;%00-00 [%0"
"0-00 -|IntArray(const IntArray`& src) { Copy(src); }]&][s7;%00-00 [%00-00 -|IntAr"
"ray`& operator=(const IntArray`& src)]&][s7;%00-00 [%00-00 -|                    "
"          { delete`[`] array; Copy(src) }]&][s7;%00-00 [%00-00 -|~IntArray()     "
"              { delete`[`] array; }]&][s7;%00-00 [%00-00 };]&][s5; This shows typ"
"ical implementation of container class with deep copy transfer semantics. Now con"
"sider we want to have function that has the [%00-00* IntArray] as return type&][s"
"7;%00-00 [%00-00 IntArray MakeArray(int n) {]&][s7;%00-00 [%00-00 -|IntArray a(n)"
";]&][s7;%00-00 [%00-00 -|for(int i = 0; i < n; i`++)]&][s7;%00-00 [%00-00 -|-|a`["
"i`] = i;]&][s7;%00-00 [%00-00 -|return a;]&][s7;%00-00 [%00-00 }]&][s5;%00-00 [%0"
"0-00 and see what happens if we use this function]&][s7;%00-00 [%00-00 IntArray y"
" = MakeArray(1000);]&][s5; Problem here is that [%00-00* IntArray] copy construct"
"or will be invoked to copy created [%00-00* IntArray] to temporary object and to "
"copy this temporary object to target [* y]. (Some really good C`++ compilers migh"
"t elide these copy constructors in this simple case, but there are other cases wh"
"ere this is not possible). And all these deep copies are made to preserve value o"
"f source that is destroyed just one step later anyway. &][s3; Pick semantics&][s5"
"; Without this preserving we could simply copy [* array] member of source to targ"
"et and somewhat disallow delete in [* ~][%00-00* IntArray]. And in fact, we do no"
"t need deep copies of containers too much often. That is ")
TOPIC_TEXT(
"why we have introduced [*/ pick][/  ]transfer semantics. Let us recreate [%00-00"
"* IntArray] with it&][s7;%00-00 [%00-00 class IntArray {]&][s7;%00-00 [%00-00 -|i"
"nt count;]&][s7;%00-00 [%00-00 -|][%00-00* mutable][%00-00  int *array;]&][s7;%00"
"-00* [%00-00 -|void Pick(pick`_ IntArray`& src) {]&][s7;%00-00* [%00-00 -|-|count"
" = src.count;]&][s7;%00-00* [%00-00 -|-|array = src.array;]&][s7;%00-00* [%00-00 "
"-|-|src.array = NULL;]&][s7;%00-00* [%00-00 -|}]&][s7;%00-00 [%00-00 public:]&][s"
"7;%00-00 [%00-00 -|int`& operator`[`](int i)        { return array`[i`]; }]&][s7;"
"%00-00 [%00-00 -|int  GetCount() const         { return count; }]&][s7;%00-00 [%0"
"0-00 -|IntArray(int n)               { count = n; array = new int`[n`]; }]&][s7;%"
"00-00 [%00-00 -|IntArray(][%00-00* pick`_][%00-00  IntArray`& src) { ][%00-00* Pi"
"ck][%00-00 (src); }]&][s7;%00-00 [%00-00 -|IntArray`& operator=(][%00-00* pick`_]"
"[%00-00  IntArray`& src)]&][s7;%00-00 [%00-00 -|                              { ]"
"[%00-00* if(array) ][%00-00 delete`[`] array;]&][s7;%00-00 [%00-00 -|            "
"                    Pick(src) }]&][s7;%00-00 [%00-00 -|~IntArray()               "
"    { ][%00-00* if(array)][%00-00  delete`[`] array; }]&][s7;%00-00 [%00-00 };]&]"
"[s5;%00-00 [%00-00 Now with pick semantics,  no unnecessary copying is made and w"
"e are free to use such container as return value. What has to be explained here i"
"s '][%00-00* pick`_][%00-00 '. Problem is that C`++ disallows binding temporaries"
" to non-const references - and that is unfortunately just the thing we need to do"
" here, as we need to change source temporary returned from function. C`++ allows "
"only one possibility for temporary to be passed - via const reference. But using "
"const reference in interface would be pretty misguiding here, as what we do is qu"
"ite opposite - we change parameter. That is why we decided to]&][s7;%00-00 [%00-0"
"0 #define pick`_ const]&][s5; Yes, this [* is] [* very] ugly, but unfortunately t"
"his best option that current C`++ gives to us. There is e")
TOPIC_TEXT(
"ffort to introduce changes in future C`++, but for now we have to live with this"
".&][s3; Pick caveats&][s5; Now let us look in pick semantics little bit deeper. O"
"ne thing is apparent - if type has default pick transfer semantics, one has to be"
" cautious when using copy constructor or operator=&][s7;%00-00 [%00-00 IntArray a"
" = MakeArray(100);]&][s7;%00-00 [%00-00 IntArray b = a; // ATTENTION: a is now pi"
"cked !]&][s7;%00-00 [%00-00 a`[3`] = 10; //illegal !]&][s5; This example shows on"
"e important aspect of pick semantics that we use throughout our code: after being"
" picked, number of operations that can be performed on source is limited. In most"
" cases, only allowed operations here are operator= and destructor. Real container"
"s add some more (we will provide common list of allowed operations later), but op"
"erations accessing or changing data of picked object are always disallowed.&][s5;"
" In fact, we had choice here - alternative approach could simply reset source to "
"some default state - this is as std`::auto`_ptr. However several years of practic"
"e in using pick semantics taught us that accessing or changing data in picked obj"
"ect is almost always error and usually hard to spot one. So we made them illegal "
"and we are also checking for such logic errors in debug mode.&][s3; Optional deep"
" copy&][s5; Now we have effective way how to transfer values without copying inte"
"rnal data at price of loosing source. But what if we would like to preserve sourc"
"e in some cases? No problem, we can simply add alternative methods for the [*/ op"
"tional deep copy]. Unlike normal deep copy and pick semantics, where signatures o"
"f methods are dictated by C`++ (that is, operator= and copy constructor), here we"
" can choose names of methods ourselves. Anyway, it is a good idea to standardize "
"them. We selected (for type T)&][s7; T(const T`&, int)&][s5; to be the signature "
"of the [*/ optional deep copy constructor]. We have to distinguish it from pick c"
"onstructor [*@5 T(pick`_ T`&)] and we can do it only by a")
TOPIC_TEXT(
"dding a parameter. It could be anything, but int somewhat resembles solution for"
" postfix operator`++. We also need optional deep copy assignment, so we overload&"
"][s7; T`& operator<<=(const T`&)&][s5; as the [*/ optional deep copy operator]. N"
"ow we can improve our simple container class to include optional deep copy semant"
"ics&][s7;%00-00 [%00-00 class IntArray {]&][s7;%00-00 [%00-00 -|int count;]&][s7;"
"%00-00 [%00-00 -|mutable int *array;]&][s7;%00-00 [%00-00 -|void Pick(pick`_ IntA"
"rray`& src) {]&][s7;%00-00 [%00-00 -|-|count = src.count;]&][s7;%00-00 [%00-00 -|"
"-|array = src.array;]&][s7;%00-00 [%00-00 -|-|src.array = NULL;]&][s7;%00-00 [%00"
"-00 -|}]&][s7;%00-00* [%00-00* -|][%00-00 void Copy(const IntArray`& src) {]&][s7"
";%00-00* [%00-00 -|-|array = new int`[count = src.count`];]&][s7;%00-00* [%00-00 "
"-|-|memcpy(array, src.array, count * sizeof(int));]&][s7;%00-00* [%00-00 -|}]&][s"
"7;%00-00 [%00-00 public:]&][s7;%00-00 [%00-00 -|int`& operator`[`](int i)        "
"{ return array`[i`]; }]&][s7;%00-00 [%00-00 -|int  GetCount() const         { ret"
"urn count; }]&][s7;%00-00 [%00-00 -|IntArray(int n)               { count = n; ar"
"ray = new int`[n`]; }]&][s7;%00-00 [%00-00 -|IntArray(pick`_ IntArray`& src) { Pi"
"ck(src); }]&][s7;%00-00 [%00-00 -|IntArray`& operator=(pick`_ IntArray`& src)]&]["
"s7;%00-00 [%00-00 -|                              { if(array) delete`[`] array;]&"
"][s7;%00-00 [%00-00 -|                                Pick(src) }]&][s7;%00-00* ["
"%00-00 -|IntArray(const IntArray`& src, int) { Copy(src); }]&][s7;%00-00* [%00-00"
" -|IntArray`& operator<<=(const IntArray`& src)]&][s7;%00-00* [%00-00 -|         "
"                     { if(array) delete`[`] array;]&][s7;%00-00* [%00-00 -|      "
"                          Copy(src) }-|]&][s7;%00-00 [%00-00 -|~IntArray()       "
"            { if(array) delete`[`] array; }]&][s7;%00-00 [%00-00 };]&][s5;%00-00 "
"[%00-00 With optional deep copy we have full control of transfer]&][s7;%00-00 [%0"
"0-00 IntArray a = MakeArray(100);]&][s7;%00-00 [%00-00 In")
TOPIC_TEXT(
"tArray b(a, 1); // deep copy]&][s7;%00-00 [%00-00 a`[3`] = 10; //legal]&][s7;%00"
"-00 [%00-00 b <<= a; // deep copy]&][s7;%00-00 [%00-00 IntArray c(a); // pick]&]["
"s7;%00-00 [%00-00 a = b; // pick - now b is picked, a and c contain MakeArray(100"
")]&][s3; Uniform access to deep copy&][s5;%00-00 [%00-00 But we need even more. C"
"onsider this example with real NTL container :]&][s7;%00-00 [%00-00 Vector< IntAr"
"ray > x, y;]&][s7;%00-00 [%00-00 ....]&][s7;%00-00 [%00-00 // put something to y]"
"&][s7;%00-00 [%00-00 ....]&][s7;%00-00 [%00-00 x <<= y;]&][s5;%00-00 [%00-00 Here"
" we are deep copy assigning container of pick with optional deep copy types to an"
"other container. During this operation we need deep copies of each indivudual ele"
"ment of ][%00-00* y][%00-00 . Problem is that we need ][%00-00* Vector][%00-00  c"
"ontainer to work both with normal deep copy types and with optional deep copy typ"
"es. We need an uniform way how to invoke deep copy constructor regardless of fact"
" it has ][%00-00* T(const T`&)][%00-00  or ][%00-00* T(const T`&, int)][%00-00  s"
"ignature. Solution is to provide two addtional functions]&][s7;%00-00 [%00-00 voi"
"d DeepCopyConstruct(void *p, const T`& x);]&][s7;%00-00 [%00-00 T   *DeepCopyNew("
"const T`& x);]&][s5;%00-00 [%00-00* DeepCopyConstruct][%00-00  constructs new dee"
"p copy of ][%00-00* x][%00-00  at given memory adress (much like placement operat"
"or new does), ][%00-00* DeepCopyNew][%00-00  constructs new deep copy of ][%00-00"
"* x][%00-00  at heap (like normal new). Now we can provide default version of the"
"se functions that will be used for types with default deep copy ]&][s7;%00-00 [%0"
"0-00 template <class T>]&][s7;%00-00 [%00-00 inline void DeepCopyConstruct(void *"
"p, const T`& x) {]&][s7;%00-00 [%00-00 -|`::new(p) T(x);]&][s7;%00-00 [%00-00 }]&"
"][s7;%00-00 &][s7;%00-00 [%00-00 template <class T>]&][s7;%00-00 [%00-00 inline T"
" *DeepCopyNew(const T`& x) {]&][s7;%00-00 [%00-00 -|return new T(x);]&][s7;%00-00"
" [%00-00 }]&][s5;%00-00 [%00-00 For types with optional d")
TOPIC_TEXT(
"eep copy we simply provide specialized version]&][s7;%00-00 [%00-00 void DeepCop"
"yConstruct(void *p, const IntArray`& x) {]&][s7;%00-00 [%00-00 -|`::new(p) IntArr"
"ay(x, 1);]&][s7;%00-00 [%00-00 }]&][s7;%00-00 &][s7;%00-00 [%00-00 IntArray *Deep"
"CopyNew(const IntArray`& x) {]&][s7;%00-00 [%00-00 -|return new IntArray(x, 1);]&"
"][s7;%00-00 [%00-00 }]&][s3; Making things easy&][s5; Now there exists way how to"
" deep copy objects of both default and optional deep copy. Anyway, this might see"
"m pretty annoying - you have to implement two methods and two global functions to"
" get optional deep copy semantics working. Fortunately, it is possible to automat"
"ize this work by using [%00-00* DeepCopyOption ]base&][s7;%00-00 [%00-00 class In"
"tArray : DeepCopyOption<IntArray> {]&][s7;%00-00 [%00-00 -|int count;]&][s7;%00-0"
"0 [%00-00 -|mutable int *array;]&][s7;%00-00 [%00-00 -|void Pick(pick`_ IntArray`"
"& src) {]&][s7;%00-00 [%00-00 -|-|count = src.count;]&][s7;%00-00 [%00-00 -|-|arr"
"ay = src.array;]&][s7;%00-00 [%00-00 -|-|src.array = NULL;]&][s7;%00-00 [%00-00 -"
"|}]&][s7;%00-00 [%00-00 -|void Copy(const IntArray`& src) {]&][s7;%00-00 [%00-00 "
"-|-|array = new int`[count = src.count`];]&][s7;%00-00 [%00-00 -|-|memcpy(array, "
"src.array, count * sizeof(int));]&][s7;%00-00 [%00-00 -|}]&][s7;%00-00 [%00-00 pu"
"blic:]&][s7;%00-00 [%00-00 -|int`& operator`[`](int i)        { return array`[i`]"
"; }]&][s7;%00-00 [%00-00 -|int  GetCount() const         { return const; }]&][s7;"
"%00-00 [%00-00 -|IntArray(int n)               { count = n; array = new int`[n`];"
" }]&][s7;%00-00 [%00-00 -|IntArray(pick`_ IntArray`& src) { Pick(src); }]&][s7;%0"
"0-00 [%00-00 -|IntArray`& operator=(pick`_ IntArray`& src)]&][s7;%00-00 [%00-00 -"
"|                              { if(array) delete`[`] array;]&][s7;%00-00 [%00-00"
" -|                                Pick(src) }]&][s7;%00-00 [%00-00 -|IntArray(co"
"nst IntArray`& src, int) { Copy(src); }]&][s7;%00-00 [%00-00 -|~IntArray()       "
"            { if(array) delete`[`] array; }]&][s7;%00-00 ")
TOPIC_TEXT(
"[%00-00 };]&][s7;%00-00 &][s5; Using [%00-00* DeepCopyOption] template all you m"
"ust provide is optional deep copy constructor - and template generates rest of me"
"thods and functions automatically.&][s3; Changing default semantics&][s5; If for "
"some reason we need version of [/ optional] deep copy type with [/ default] deep "
"copy, we can easily create it with [%00-00* WithDeepCopy ]template&][s7;%00-00 [%"
"00-00 IntArray a = MakeArray(100);]&][s7;%00-00 [%00-00 WithDeepCopy<IntArray> b("
"a); // b now has deep copy semantics]&][s7;%00-00 [%00-00 a`[3`] = 10; //legal]&]"
"[s7;%00-00 [%00-00 b = a; // deep copy]&][s7;%00-00 [%00-00 a = b; // pick]&][s7;"
"%00-00 [%00-00 b`[4`] = 1; // illegal]&][s3;%00-00 [%00-00 Polymorphic deep copy]"
"&][s5;%00-00* [%00-00* Now there is one last type of transfer semantics. Some of "
"containers allow storing polymorphic elements. E.g. Array allows storing object o"
"f type derived from basic element type. This causes new problems in situation whe"
"n we want to create deep copy of such container - what we need is polymorphic dee"
"p copy of elements. Problem is solved by already introduced ][%00-00 DeepCopyNew]"
"&][s7;%00-00 [%00-00 class Base : PolyDeepCopyNew<Base> {]&][s7;%00-00 [%00-00 -|"
"....]&][s7;%00-00 [%00-00 public:]&][s7;%00-00 [%00-00 -|....]&][s7;%00-00 [%00-0"
"0 -|virtual Base  *Copy() const    { return new Base(*this); }]&][s7;%00-00 [%00-"
"00 };]&][s7;%00-00 &][s7;%00-00 [%00-00 class Derived : Base {]&][s7;%00-00 [%00-"
"00 -|....]&][s7;%00-00 [%00-00 public:]&][s7;%00-00 [%00-00 -|....]&][s7;%00-00 ["
"%00-00 -|virtual Base    *Copy() const  { return new Derived(*this); }]&][s7;%00-"
"00 [%00-00 };]&][s7;%00-00 &][s7;%00-00 &][s7;%00-00 [%00-00 ....]&][s7;%00-00 [%"
"00-00 Array<Base> a;]&][s7;%00-00 [%00-00 a.Add(new Base);]&][s7;%00-00 [%00-00 a"
".Add(new Derived);]&][s7;%00-00 [%00-00 Array<Base> b(a, 1); // deep copy using C"
"opy members]&][s5;%00-00 [%00-00* PolyDeepCopyNew][%EN-GB*  ][%EN-GB base class c"
"reates appropriate ][%00-00* DeepCopyNew ][%00-00 special")
TOPIC_TEXT(
"ization based on ][%00-00* Copy][%00-00  virtual method. We call this transfer m"
"ethod ][%00-00*/ polymorphic deep copy][%00-00 .]&][s0;2 ")
