lhash.3 (206048) | lhash.3 (215698) |
---|---|
1.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.37 | 1.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.07) |
2.\" 3.\" Standard preamble: 4.\" ======================================================================== | 2.\" 3.\" Standard preamble: 4.\" ======================================================================== |
5.de Sh \" Subsection heading 6.br 7.if t .Sp 8.ne 5 9.PP 10\fB\\$1\fR 11.PP 12.. | |
13.de Sp \" Vertical space (when we can't use .PP) 14.if t .sp .5v 15.if n .sp 16.. 17.de Vb \" Begin verbatim text 18.ft CW 19.nf 20.ne \\$1 21.. 22.de Ve \" End verbatim text 23.ft R 24.fi 25.. 26.\" Set up some character translations and predefined strings. \*(-- will 27.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left | 5.de Sp \" Vertical space (when we can't use .PP) 6.if t .sp .5v 7.if n .sp 8.. 9.de Vb \" Begin verbatim text 10.ft CW 11.nf 12.ne \\$1 13.. 14.de Ve \" End verbatim text 15.ft R 16.fi 17.. 18.\" Set up some character translations and predefined strings. \*(-- will 19.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left |
28.\" double quote, and \*(R" will give a right double quote. | will give a 29.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to 30.\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' 31.\" expand to `' in nroff, nothing in troff, for use with C<>. 32.tr \(*W-|\(bv\*(Tr | 20.\" double quote, and \*(R" will give a right double quote. \*(C+ will 21.\" give a nicer C++. Capital omega is used to do unbreakable dashes and 22.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, 23.\" nothing in troff, for use with C<>. 24.tr \(*W- |
33.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' 34.ie n \{\ 35. ds -- \(*W- 36. ds PI pi 37. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch 38. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch 39. ds L" "" 40. ds R" "" 41. ds C` "" 42. ds C' "" 43'br\} 44.el\{\ 45. ds -- \|\(em\| 46. ds PI \(*p 47. ds L" `` 48. ds R" '' 49'br\} 50.\" | 25.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' 26.ie n \{\ 27. ds -- \(*W- 28. ds PI pi 29. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch 30. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch 31. ds L" "" 32. ds R" "" 33. ds C` "" 34. ds C' "" 35'br\} 36.el\{\ 37. ds -- \|\(em\| 38. ds PI \(*p 39. ds L" `` 40. ds R" '' 41'br\} 42.\" |
43.\" Escape single quotes in literal strings from groff's Unicode transform. 44.ie \n(.g .ds Aq \(aq 45.el .ds Aq ' 46.\" |
|
51.\" If the F register is turned on, we'll generate index entries on stderr for | 47.\" If the F register is turned on, we'll generate index entries on stderr for |
52.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index | 48.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index |
53.\" entries marked with X<> in POD. Of course, you'll have to process the 54.\" output yourself in some meaningful fashion. | 49.\" entries marked with X<> in POD. Of course, you'll have to process the 50.\" output yourself in some meaningful fashion. |
55.if \nF \{\ | 51.ie \nF \{\ |
56. de IX 57. tm Index:\\$1\t\\n%\t"\\$2" 58.. 59. nr % 0 60. rr F 61.\} | 52. de IX 53. tm Index:\\$1\t\\n%\t"\\$2" 54.. 55. nr % 0 56. rr F 57.\} |
58.el \{\ 59. de IX 60.. 61.\} |
|
62.\" | 62.\" |
63.\" For nroff, turn off justification. Always turn off hyphenation; it makes 64.\" way too many mistakes in technical documents. 65.hy 0 66.if n .na 67.\" | |
68.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). 69.\" Fear. Run. Save yourself. No user-serviceable parts. 70. \" fudge factors for nroff and troff 71.if n \{\ 72. ds #H 0 73. ds #V .8m 74. ds #F .3m 75. ds #[ \f1 --- 48 unchanged lines hidden (view full) --- 124. ds Th \o'LP' 125. ds ae ae 126. ds Ae AE 127.\} 128.rm #[ #] #H #V #F C 129.\" ======================================================================== 130.\" 131.IX Title "lhash 3" | 63.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). 64.\" Fear. Run. Save yourself. No user-serviceable parts. 65. \" fudge factors for nroff and troff 66.if n \{\ 67. ds #H 0 68. ds #V .8m 69. ds #F .3m 70. ds #[ \f1 --- 48 unchanged lines hidden (view full) --- 119. ds Th \o'LP' 120. ds ae ae 121. ds Ae AE 122.\} 123.rm #[ #] #H #V #F C 124.\" ======================================================================== 125.\" 126.IX Title "lhash 3" |
132.TH lhash 3 "2010-03-24" "0.9.8n" "OpenSSL" | 127.TH lhash 3 "2010-11-16" "0.9.8p" "OpenSSL" 128.\" For nroff, turn off justification. Always turn off hyphenation; it makes 129.\" way too many mistakes in technical documents. 130.if n .ad l 131.nh |
133.SH "NAME" 134lh_new, lh_free, lh_insert, lh_delete, lh_retrieve, lh_doall, lh_doall_arg, lh_error \- dynamic hash table 135.SH "SYNOPSIS" 136.IX Header "SYNOPSIS" 137.Vb 1 138\& #include <openssl/lhash.h> | 132.SH "NAME" 133lh_new, lh_free, lh_insert, lh_delete, lh_retrieve, lh_doall, lh_doall_arg, lh_error \- dynamic hash table 134.SH "SYNOPSIS" 135.IX Header "SYNOPSIS" 136.Vb 1 137\& #include <openssl/lhash.h> |
139.Ve 140.PP 141.Vb 2 | 138\& |
142\& LHASH *lh_new(LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE compare); 143\& void lh_free(LHASH *table); | 139\& LHASH *lh_new(LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE compare); 140\& void lh_free(LHASH *table); |
144.Ve 145.PP 146.Vb 3 | 141\& |
147\& void *lh_insert(LHASH *table, void *data); 148\& void *lh_delete(LHASH *table, void *data); 149\& void *lh_retrieve(LHASH *table, void *data); | 142\& void *lh_insert(LHASH *table, void *data); 143\& void *lh_delete(LHASH *table, void *data); 144\& void *lh_retrieve(LHASH *table, void *data); |
150.Ve 151.PP 152.Vb 3 | 145\& |
153\& void lh_doall(LHASH *table, LHASH_DOALL_FN_TYPE func); 154\& void lh_doall_arg(LHASH *table, LHASH_DOALL_ARG_FN_TYPE func, 155\& void *arg); | 146\& void lh_doall(LHASH *table, LHASH_DOALL_FN_TYPE func); 147\& void lh_doall_arg(LHASH *table, LHASH_DOALL_ARG_FN_TYPE func, 148\& void *arg); |
156.Ve 157.PP 158.Vb 1 | 149\& |
159\& int lh_error(LHASH *table); | 150\& int lh_error(LHASH *table); |
160.Ve 161.PP 162.Vb 4 | 151\& |
163\& typedef int (*LHASH_COMP_FN_TYPE)(const void *, const void *); 164\& typedef unsigned long (*LHASH_HASH_FN_TYPE)(const void *); 165\& typedef void (*LHASH_DOALL_FN_TYPE)(const void *); 166\& typedef void (*LHASH_DOALL_ARG_FN_TYPE)(const void *, const void *); 167.Ve 168.SH "DESCRIPTION" 169.IX Header "DESCRIPTION" 170This library implements dynamic hash tables. The hash table entries --- 20 unchanged lines hidden (view full) --- 191.Vb 7 192\& #define DECLARE_LHASH_HASH_FN(f_name,o_type) \e 193\& unsigned long f_name##_LHASH_HASH(const void *); 194\& #define IMPLEMENT_LHASH_HASH_FN(f_name,o_type) \e 195\& unsigned long f_name##_LHASH_HASH(const void *arg) { \e 196\& o_type a = (o_type)arg; \e 197\& return f_name(a); } 198\& #define LHASH_HASH_FN(f_name) f_name##_LHASH_HASH | 152\& typedef int (*LHASH_COMP_FN_TYPE)(const void *, const void *); 153\& typedef unsigned long (*LHASH_HASH_FN_TYPE)(const void *); 154\& typedef void (*LHASH_DOALL_FN_TYPE)(const void *); 155\& typedef void (*LHASH_DOALL_ARG_FN_TYPE)(const void *, const void *); 156.Ve 157.SH "DESCRIPTION" 158.IX Header "DESCRIPTION" 159This library implements dynamic hash tables. The hash table entries --- 20 unchanged lines hidden (view full) --- 180.Vb 7 181\& #define DECLARE_LHASH_HASH_FN(f_name,o_type) \e 182\& unsigned long f_name##_LHASH_HASH(const void *); 183\& #define IMPLEMENT_LHASH_HASH_FN(f_name,o_type) \e 184\& unsigned long f_name##_LHASH_HASH(const void *arg) { \e 185\& o_type a = (o_type)arg; \e 186\& return f_name(a); } 187\& #define LHASH_HASH_FN(f_name) f_name##_LHASH_HASH |
199.Ve 200.PP 201.Vb 8 | 188\& |
202\& #define DECLARE_LHASH_COMP_FN(f_name,o_type) \e 203\& int f_name##_LHASH_COMP(const void *, const void *); 204\& #define IMPLEMENT_LHASH_COMP_FN(f_name,o_type) \e 205\& int f_name##_LHASH_COMP(const void *arg1, const void *arg2) { \e 206\& o_type a = (o_type)arg1; \e 207\& o_type b = (o_type)arg2; \e 208\& return f_name(a,b); } 209\& #define LHASH_COMP_FN(f_name) f_name##_LHASH_COMP | 189\& #define DECLARE_LHASH_COMP_FN(f_name,o_type) \e 190\& int f_name##_LHASH_COMP(const void *, const void *); 191\& #define IMPLEMENT_LHASH_COMP_FN(f_name,o_type) \e 192\& int f_name##_LHASH_COMP(const void *arg1, const void *arg2) { \e 193\& o_type a = (o_type)arg1; \e 194\& o_type b = (o_type)arg2; \e 195\& return f_name(a,b); } 196\& #define LHASH_COMP_FN(f_name) f_name##_LHASH_COMP |
210.Ve 211.PP 212.Vb 7 | 197\& |
213\& #define DECLARE_LHASH_DOALL_FN(f_name,o_type) \e 214\& void f_name##_LHASH_DOALL(const void *); 215\& #define IMPLEMENT_LHASH_DOALL_FN(f_name,o_type) \e 216\& void f_name##_LHASH_DOALL(const void *arg) { \e 217\& o_type a = (o_type)arg; \e 218\& f_name(a); } 219\& #define LHASH_DOALL_FN(f_name) f_name##_LHASH_DOALL | 198\& #define DECLARE_LHASH_DOALL_FN(f_name,o_type) \e 199\& void f_name##_LHASH_DOALL(const void *); 200\& #define IMPLEMENT_LHASH_DOALL_FN(f_name,o_type) \e 201\& void f_name##_LHASH_DOALL(const void *arg) { \e 202\& o_type a = (o_type)arg; \e 203\& f_name(a); } 204\& #define LHASH_DOALL_FN(f_name) f_name##_LHASH_DOALL |
220.Ve 221.PP 222.Vb 8 | 205\& |
223\& #define DECLARE_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \e 224\& void f_name##_LHASH_DOALL_ARG(const void *, const void *); 225\& #define IMPLEMENT_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \e 226\& void f_name##_LHASH_DOALL_ARG(const void *arg1, const void *arg2) { \e 227\& o_type a = (o_type)arg1; \e 228\& a_type b = (a_type)arg2; \e 229\& f_name(a,b); } 230\& #define LHASH_DOALL_ARG_FN(f_name) f_name##_LHASH_DOALL_ARG 231.Ve 232.PP 233An example of a hash table storing (pointers to) structures of type '\s-1STUFF\s0' 234could be defined as follows; 235.PP | 206\& #define DECLARE_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \e 207\& void f_name##_LHASH_DOALL_ARG(const void *, const void *); 208\& #define IMPLEMENT_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \e 209\& void f_name##_LHASH_DOALL_ARG(const void *arg1, const void *arg2) { \e 210\& o_type a = (o_type)arg1; \e 211\& a_type b = (a_type)arg2; \e 212\& f_name(a,b); } 213\& #define LHASH_DOALL_ARG_FN(f_name) f_name##_LHASH_DOALL_ARG 214.Ve 215.PP 216An example of a hash table storing (pointers to) structures of type '\s-1STUFF\s0' 217could be defined as follows; 218.PP |
236.Vb 14 237\& /* Calculates the hash value of 'tohash' (implemented elsewhere) */ | 219.Vb 10 220\& /* Calculates the hash value of \*(Aqtohash\*(Aq (implemented elsewhere) */ |
238\& unsigned long STUFF_hash(const STUFF *tohash); | 221\& unsigned long STUFF_hash(const STUFF *tohash); |
239\& /* Orders 'arg1' and 'arg2' (implemented elsewhere) */ | 222\& /* Orders \*(Aqarg1\*(Aq and \*(Aqarg2\*(Aq (implemented elsewhere) */ |
240\& int STUFF_cmp(const STUFF *arg1, const STUFF *arg2); | 223\& int STUFF_cmp(const STUFF *arg1, const STUFF *arg2); |
241\& /* Create the type-safe wrapper functions for use in the LHASH internals */ | 224\& /* Create the type\-safe wrapper functions for use in the LHASH internals */ |
242\& static IMPLEMENT_LHASH_HASH_FN(STUFF_hash, const STUFF *) 243\& static IMPLEMENT_LHASH_COMP_FN(STUFF_cmp, const STUFF *); 244\& /* ... */ 245\& int main(int argc, char *argv[]) { 246\& /* Create the new hash table using the hash/compare wrappers */ 247\& LHASH *hashtable = lh_new(LHASH_HASH_FN(STUFF_hash), 248\& LHASH_COMP_FN(STUFF_cmp)); 249\& /* ... */ --- 21 unchanged lines hidden (view full) --- 271\&\fB\s-1NOTE\s0\fR) \- instead, either declare the callbacks to match the 272prototype required in \fIlh_new()\fR or use the declare/implement macros to 273create type-safe wrappers that cast variables prior to calling your 274type-specific callbacks. An example of this is illustrated here where 275the callback is used to cleanup resources for items in the hash table 276prior to the hashtable itself being deallocated: 277.PP 278.Vb 9 | 225\& static IMPLEMENT_LHASH_HASH_FN(STUFF_hash, const STUFF *) 226\& static IMPLEMENT_LHASH_COMP_FN(STUFF_cmp, const STUFF *); 227\& /* ... */ 228\& int main(int argc, char *argv[]) { 229\& /* Create the new hash table using the hash/compare wrappers */ 230\& LHASH *hashtable = lh_new(LHASH_HASH_FN(STUFF_hash), 231\& LHASH_COMP_FN(STUFF_cmp)); 232\& /* ... */ --- 21 unchanged lines hidden (view full) --- 254\&\fB\s-1NOTE\s0\fR) \- instead, either declare the callbacks to match the 255prototype required in \fIlh_new()\fR or use the declare/implement macros to 256create type-safe wrappers that cast variables prior to calling your 257type-specific callbacks. An example of this is illustrated here where 258the callback is used to cleanup resources for items in the hash table 259prior to the hashtable itself being deallocated: 260.PP 261.Vb 9 |
279\& /* Cleans up resources belonging to 'a' (this is implemented elsewhere) */ | 262\& /* Cleans up resources belonging to \*(Aqa\*(Aq (this is implemented elsewhere) */ |
280\& void STUFF_cleanup(STUFF *a); | 263\& void STUFF_cleanup(STUFF *a); |
281\& /* Implement a prototype-compatible wrapper for "STUFF_cleanup" */ | 264\& /* Implement a prototype\-compatible wrapper for "STUFF_cleanup" */ |
282\& IMPLEMENT_LHASH_DOALL_FN(STUFF_cleanup, STUFF *) 283\& /* ... then later in the code ... */ 284\& /* So to run "STUFF_cleanup" against all items in a hash table ... */ 285\& lh_doall(hashtable, LHASH_DOALL_FN(STUFF_cleanup)); 286\& /* Then the hash table itself can be deallocated */ 287\& lh_free(hashtable); 288.Ve 289.PP --- 13 unchanged lines hidden (view full) --- 303can instead choose to declare your callback with a prototype matching 304the types you are dealing with and use the declare/implement macros to 305create compatible wrappers that cast variables before calling your 306type-specific callbacks. An example of this is demonstrated here 307(printing all hash table entries to a \s-1BIO\s0 that is provided by the 308caller): 309.PP 310.Vb 7 | 265\& IMPLEMENT_LHASH_DOALL_FN(STUFF_cleanup, STUFF *) 266\& /* ... then later in the code ... */ 267\& /* So to run "STUFF_cleanup" against all items in a hash table ... */ 268\& lh_doall(hashtable, LHASH_DOALL_FN(STUFF_cleanup)); 269\& /* Then the hash table itself can be deallocated */ 270\& lh_free(hashtable); 271.Ve 272.PP --- 13 unchanged lines hidden (view full) --- 286can instead choose to declare your callback with a prototype matching 287the types you are dealing with and use the declare/implement macros to 288create compatible wrappers that cast variables before calling your 289type-specific callbacks. An example of this is demonstrated here 290(printing all hash table entries to a \s-1BIO\s0 that is provided by the 291caller): 292.PP 293.Vb 7 |
311\& /* Prints item 'a' to 'output_bio' (this is implemented elsewhere) */ | 294\& /* Prints item \*(Aqa\*(Aq to \*(Aqoutput_bio\*(Aq (this is implemented elsewhere) */ |
312\& void STUFF_print(const STUFF *a, BIO *output_bio); | 295\& void STUFF_print(const STUFF *a, BIO *output_bio); |
313\& /* Implement a prototype-compatible wrapper for "STUFF_print" */ | 296\& /* Implement a prototype\-compatible wrapper for "STUFF_print" */ |
314\& static IMPLEMENT_LHASH_DOALL_ARG_FN(STUFF_print, const STUFF *, BIO *) 315\& /* ... then later in the code ... */ 316\& /* Print out the entire hashtable to a particular BIO */ 317\& lh_doall_arg(hashtable, LHASH_DOALL_ARG_FN(STUFF_print), logging_bio); 318.Ve 319.PP 320\&\fIlh_error()\fR can be used to determine if an error occurred in the last 321operation. \fIlh_error()\fR is a macro. --- 17 unchanged lines hidden (view full) --- 339\&\fIlh_free()\fR, \fIlh_doall()\fR and \fIlh_doall_arg()\fR return no values. 340.SH "NOTE" 341.IX Header "NOTE" 342The various \s-1LHASH\s0 macros and callback types exist to make it possible 343to write type-safe code without resorting to function-prototype 344casting \- an evil that makes application code much harder to 345audit/verify and also opens the window of opportunity for stack 346corruption and other hard-to-find bugs. It also, apparently, violates | 297\& static IMPLEMENT_LHASH_DOALL_ARG_FN(STUFF_print, const STUFF *, BIO *) 298\& /* ... then later in the code ... */ 299\& /* Print out the entire hashtable to a particular BIO */ 300\& lh_doall_arg(hashtable, LHASH_DOALL_ARG_FN(STUFF_print), logging_bio); 301.Ve 302.PP 303\&\fIlh_error()\fR can be used to determine if an error occurred in the last 304operation. \fIlh_error()\fR is a macro. --- 17 unchanged lines hidden (view full) --- 322\&\fIlh_free()\fR, \fIlh_doall()\fR and \fIlh_doall_arg()\fR return no values. 323.SH "NOTE" 324.IX Header "NOTE" 325The various \s-1LHASH\s0 macros and callback types exist to make it possible 326to write type-safe code without resorting to function-prototype 327casting \- an evil that makes application code much harder to 328audit/verify and also opens the window of opportunity for stack 329corruption and other hard-to-find bugs. It also, apparently, violates |
347\&\s-1ANSI\-C\s0. | 330ANSI-C. |
348.PP 349The \s-1LHASH\s0 code regards table entries as constant data. As such, it 350internally represents \fIlh_insert()\fR'd items with a \*(L"const void *\*(R" 351pointer type. This is why callbacks such as those used by \fIlh_doall()\fR 352and \fIlh_doall_arg()\fR declare their prototypes with \*(L"const\*(R", even for the 353parameters that pass back the table items' data pointers \- for 354consistency, user-provided data is \*(L"const\*(R" at all times as far as the 355\&\s-1LHASH\s0 code is concerned. However, as callers are themselves providing 356these pointers, they can choose whether they too should be treating 357all such parameters as constant. 358.PP 359As an example, a hash table may be maintained by code that, for 360reasons of encapsulation, has only \*(L"const\*(R" access to the data being 361indexed in the hash table (ie. it is returned as \*(L"const\*(R" from 362elsewhere in their code) \- in this case the \s-1LHASH\s0 prototypes are | 331.PP 332The \s-1LHASH\s0 code regards table entries as constant data. As such, it 333internally represents \fIlh_insert()\fR'd items with a \*(L"const void *\*(R" 334pointer type. This is why callbacks such as those used by \fIlh_doall()\fR 335and \fIlh_doall_arg()\fR declare their prototypes with \*(L"const\*(R", even for the 336parameters that pass back the table items' data pointers \- for 337consistency, user-provided data is \*(L"const\*(R" at all times as far as the 338\&\s-1LHASH\s0 code is concerned. However, as callers are themselves providing 339these pointers, they can choose whether they too should be treating 340all such parameters as constant. 341.PP 342As an example, a hash table may be maintained by code that, for 343reasons of encapsulation, has only \*(L"const\*(R" access to the data being 344indexed in the hash table (ie. it is returned as \*(L"const\*(R" from 345elsewhere in their code) \- in this case the \s-1LHASH\s0 prototypes are |
363appropriate as\-is. Conversely, if the caller is responsible for the | 346appropriate as-is. Conversely, if the caller is responsible for the |
364life-time of the data in question, then they may well wish to make 365modifications to table item passed back in the \fIlh_doall()\fR or 366\&\fIlh_doall_arg()\fR callbacks (see the \*(L"STUFF_cleanup\*(R" example above). If 367so, the caller can either cast the \*(L"const\*(R" away (if they're providing 368the raw callbacks themselves) or use the macros to declare/implement 369the wrapper functions without \*(L"const\*(R" types. 370.PP 371Callers that only have \*(L"const\*(R" access to data they're indexing in a --- 70 unchanged lines hidden --- | 347life-time of the data in question, then they may well wish to make 348modifications to table item passed back in the \fIlh_doall()\fR or 349\&\fIlh_doall_arg()\fR callbacks (see the \*(L"STUFF_cleanup\*(R" example above). If 350so, the caller can either cast the \*(L"const\*(R" away (if they're providing 351the raw callbacks themselves) or use the macros to declare/implement 352the wrapper functions without \*(L"const\*(R" types. 353.PP 354Callers that only have \*(L"const\*(R" access to data they're indexing in a --- 70 unchanged lines hidden --- |